计算机系统篇之链接(1):gcc/g++的编译流程

本文详细解析了gcc/g++的编译流程,包括预处理、编译、汇编和链接四个步骤。预处理阶段,gcc/g++将源文件扩展并生成中间文件;编译阶段将预处理后的文件转化为汇编代码;汇编阶段则将汇编代码转换为可重定位目标文件;最后,链接器将多个目标文件结合系统库生成可执行文件。文章还介绍了各阶段的相关命令及参数设置。
摘要由CSDN通过智能技术生成

计算机系统篇之链接(1):gcc/g++的编译流程

Author:stormQ

Saturday, 21. December 2019 09:48AM


gcc/g++,实质上是一个编译驱动器(Compile Driver),对它的调用意味着调用一系列的程序——预处理器、编译器、汇编器和链接器,从而将源代码转化成可执行目标文件。具体流程可以分为如下四个步骤:

1)预处理

首先调用 C 预处理器(名称为cpp的可执行目标文件,通常位于/usr/bin/目录下)将每个源文件(比如:以.c 或 .cc 或. cpp结尾的文件)扩展源代码——即插入所有用#include命令指定的文件,并扩展所有用#define声明指定的宏。对一个源文件进行预处理的输出结果是一个以.i结尾的中间文件,即编码为 ASCII 码的源代码中间文件。

由源文件生成预处理文件的命令:

# 一个源文件(以.c/.cc/.cpp结尾的文件)对应一个预处理后的源文件(以.i结尾的文件)
$ cpp -std=c++11 main.cpp -o main.i
$ cpp -std=c++11 shm_manager_sim.cpp -o shm_manager_sim.i
$ cpp -std=c++11 subscription_sim.cpp -o subscription_sim.i
$ cpp -std=c++11 topic_manager_sim.cpp -o topic_manager_sim.i

$ g++ -E main.cpp -o main.i
$ g++ -E shm_manager_sim.cpp -o shm_manager_sim.i
$ g++ -E subscription_sim.cpp -o subscription_sim.i
$ g++ -E topic_manager_sim.cpp -o topic_manager_sim.i

注意:

  • main.cpp 中包含了<thread>头文件(在 C++11 标准中涵盖)。所以,直接调用预处理器cpp时需要添加-std=c++11选项,而采用g++ -E的方式不需要添加该选项。

  • 如果源文件与其包含的用户头文件不在同一个目录中,需要添加-I选项指定搜索路径,从而成功地生成.i文件。示例:1)用户头文件都处于同一个目录时,对应的命令:g++ -E main.cpp -o main.i -I <directory>;2)用户头文件处于不同目录时,对应的命令:g++ -E main.cpp -o main.i -I <directory 1> -I <directory 2> -I <directory n>

  • 在某些 gcc/g++ 版本中,预处理器被集成到编译驱动器中,而不是作为独立的程序存在。

2)编译

其次,调用编译器(名称为cc1——用于编译C程序的可执行目标文件或cc1plus——用于编译C++程序的可执行目标文件,在本人的机器上两者位于/usr/lib/gcc/x86_64-linux-gnu/6目录下)将扩展后的源代码(以.i结尾的文件)编译成汇编代码(以.s结尾的文件,即编码为 ASCII 码的汇编语言文件)。

由预处理文件生成汇编语言文件的命令:

# 一个预处理后的源文件(以.i结尾的文件)对应一个汇编代码文件(以.s结尾的文件)
# /usr/lib/gcc/x86_64-linux-gnu/6/cc1plus -o main.s main.cpp <other arguments>
$ /usr/lib/gcc/x86_64-linux-gnu/6/cc1plus -o main.s main.cpp -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE -quiet -dumpbase -mtune=generic -march=x86-64 -auxbase-strip -version -fstack-protector-strong -Wformat -Wformat-security

$ g++ -S main.i -o main.s
$ g++ -S shm_manager_sim.i -o shm_manager_sim.s
$ g++ -S subscription_sim.i -o subscription_sim.s
$ g++ -S topic_manager_sim.i -o topic_manager_sim.s

注意:

  • cc1plus命令中<other arguments>部分如何确定?详见下文。

  • 如果需要添加调试信息,只能在执行本步骤时加-g选项。其他时期:步骤1)、步骤3)、步骤4)时加-g选项都没有任何作用。添加-g所生成的汇编代码文件中可以看到与调试相关的 sections,如:.debug_aranges.debug_info.deb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值