002-编译和链接(从源文件.cpp到可执行文件.exe可执行文件到底经历了什么?)

1 前言

一般我们在写代码的时候,写完直接点击编译运行,但是却并未思考,编译这个过程到底发生了什么;实际上,当前的很多IDE(如Visual Stidio)都将这个过程忽略了;也就是从源文件(.cpp)到可执行文件(.exe)中间的过程我们并未过多了解;

.cpp文件到可执行文件.exe中间的过程如下图所示(预编译–>编译–>汇编–>链接)4个步骤

在这里插入图片描述

2 预编译(Propressing)

预编译主要就是处理宏定义,将其展开等工作

  1. 从.cpp文件变成.i文件
  2. 主要是处理源代码文件中的预编译指令,例如#xxxx
    1) 预编译指令的展开
    2) 添加行号和文件名等调试信息
    3) 删除注释
    4) 处理编译器指令如#pragma
  3. 预编译后的文件不包含任何宏定义

3 编译(Compliation)

编译主要负责识别源代码,并将其转换成优化后的汇编代码

  1. 从.i文件变成.s文件(汇编代码文件)
  2. 主要工作是对.i文件进行一系列的词法分析等,目的是让编译器知道这写的代码是啥
    1) 词法分析: 主要是将源代码指令识别分解成一个个符号、关键字、数字等
    2) 语法分析: 主要是分析表达式是否合理,例如不允许指针和指针相乘运算等
    3) 语义分析: 在编译阶段主要是静态语义;工作是声明和类型的匹配、类型的转换,经过语义分析之后,所有的表达式都被标注了相对应的类型
    4) 中间语言生成: 将上述的源代码转换成适合用于转换为汇编代码的中间代码;我的理解是将这些代码变得更加简洁(这其中也必然存在拆分动作)
    5) 目标代码生成和优化: a) 所谓的目标代码,其实是优化后的汇编代码; b) 将中间代码转化成汇编代码; c) 再将汇编代码进行优化; d) 最后成为.s文件

4 汇编(Assembly)

汇编是一个理解起来比较简单的过程:对应不同的机器的指令集,将汇编代码一条一条翻译为机器指令

  1. 将.s文件变成.o文件(也即目标文件)
  2. 汇编器将上一步骤优化后的汇编代码一条一条的转化为机器指令
  3. 机器指令(形如:010101111000110101…)是唯一可以被计算机读懂的指令

5 链接(Linking)

链接主要负责将目标文件(.o文件)和库文件整合起来,就像拼图一样

  1. 将.o文件和运行时库(Runtime Library)中的目标文件组装成可执行的.exe文件
  2. 这个过程就像是拼图一样,将相互需要的文件进行组装(比如a.o文件中调用了b.o文件中的函数等)

备注:什么是运行时库(Runtime Library)?

  1. 库其实是支持程序运行的基本函数的集合
  2. 是一组目标文件的包,就是一些常用的代码编译成目标文件后打包存放就是所谓的库
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 使用CMake可以编译具有不同目录和多个源文件可执行文件。 首先,我们需要创建一个CMakeLists.txt文件来描述项目的结构和编译选项。以下是一个示例CMakeLists.txt文件: ```cmake cmake_minimum_required(VERSION 3.10) project(MyProject) # 设置编译选项 set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # 添加可执行文件目标 add_executable(MyExecutable src/main.cpp src/util.cpp ) # 添加头文件路径 target_include_directories(MyExecutable PUBLIC include ) # 添加可执行文件所需的其他 target_link_libraries(MyExecutable PRIVATE MyLibrary ) ``` 在这个示例中,我们将项目命名为“MyProject”并设置了CMake的最低版本要求。然后,我们将编译选项设置为C++11,并添加了两个源文件(main.cpp和util.cpp)来创建一个可执行文件“MyExecutable”。还通过“target_include_directories”指定了头文件路径,以及通过“target_link_libraries”指定了可执行文件所需的其他(例如MyLibrary)。 接下来,我们将在项目的根目录中创建一个“build”文件夹,并在该文件夹中使用CMake来生成编译结果。使用以下命令: ```shell cd build cmake .. make ``` 这将生成一个名为“MyExecutable”的可执行文件,位于“build”文件夹中。您可以通过执行以下命令来运行它: ```shell ./MyExecutable ``` 这样,您就可以通过CMakeLists.txt文件编译带有不同目录和多个源文件可执行文件。 ### 回答2: 使用C语言编写的项目通常需要一个主目录,作为整个项目的根目录。在主目录下,我们可以将源代码和其他项目文件组织在不同的子目录中。 为了编译一个包含不同目录中多个源文件的C程序,我们可以使用CMake来管理项目的构建过程。CMake是一个跨平台的构建工具,可以根据CMakeLists.txt文件配置项目的构建。 首先,我们需要在主目录下创建一个CMakeLists.txt文件。这个文件将告诉CMake如何构建我们的项目。 CMakeLists.txt文件通常包含以下内容: 1. 设置项目的名称和最低要求的CMake版本: ```cmake cmake_minimum_required(VERSION 3.10) project(my_project) ``` 2. 添加可执行文件,并指定源文件的路径: ```cmake add_executable(my_executable src/main.c src/util.c ) ``` 上面的例子中,我们在src目录下有两个源文件:main.c和util.c。通过将它们包含在add_executable命令中,CMake将会构建一个名为my_executable的可执行文件。 3. 添加其他的源文件和目录: ```cmake add_library(my_library src/other.c src/helpers/helper1.c src/helpers/helper2.c ) ``` 在这个例子中,我们添加了一个名为my_library的,并指定了多个源文件和目录。 4. 指定链接: ```cmake target_link_libraries(my_executable my_library) ``` 上面的命令将my_executable与my_library进行链接。 5. 编译项目: ```bash mkdir build cd build cmake .. make ``` 以上命令将创建一个名为build的目录,在这个目录下运行cmake和make命令来构建项目。 通过上述步骤,我们可以使用CMake和CMakeLists.txt文件编译包含不同目录中多个源文件的C程序,并生成可执行文件my_executable。 ### 回答3: 编译可以使用cmakelists.txt文件来指导。CMake是一个跨平台的编译工具,可以帮助我们简化编译过程。 在CMakeLists.txt文件中,我们需要包含一些基本内容来指示CMake如何构建我们的项目。首先,我们需要指定我们的最低CMake版本。接下来,我们可以定义项目的名称和版本号。 接下来,我们需要使用project()命令来指定项目的名称和版本号。然后,我们可以定义目标可执行文件的名称,并指定源文件。 如果我们有多个源文件,可以使用add_executable()命令来指定所有源文件的名称。如果源文件位于不同的目录中,我们可以使用相对路径或绝对路径来指定它们的位置。 一旦我们定义了所有的源文件,我们可以使用target_link_libraries()命令来指定与我们的项目相关的。 最后,我们可以使用add_custom_target()命令来定义自定义目标,以便在构建过程中执行一些自定义命令。 完成了CMakeLists.txt文件的编写后,我们可以使用cmake命令来生成一个Makefile。然后,我们可以使用make命令来编译我们的项目,生成可执行文件。 总结起来,使用CMake进行编译可以帮助我们简化编译过程,并且可以支持多个源文件和不同目录的编译。只需在CMakeLists.txt文件中配置好项目信息、源文件和目标可执行文件的相关命令,然后使用cmake和make命令来生成和编译项目,最终生成可执行文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咖啡与乌龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值