gcc(GNU Compiler Collection)编译过程

发布于:2023-01-05 ⋅ 阅读:(509) ⋅ 点赞:(0)

gcc编译过程

gcc命令其实依次执行了四步操作

1、预处理(Preprocessing):将所有的.c 、.cpp文件处理为.i文件,

2、编译(Compilation):将所有的.i文件编译为.S文件

3、汇编(Assemble):将所有的.S文件汇编为.o文件

4、链接(Linking):将所有的.o文件链接为一个可执行文件

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

 如果把汇编这一步隐藏掉,就有如下流程:

https://zhuanlan.zhihu.com/p/380180101

 (1)预处理

C/C++源文件中,以“#”开头的命令被称为预处理命令,如包含命令“#include”、宏定义命令“#define”、条件编译命令“#if”、“#ifdef”等。

预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到一个“.i”文件中等待进一步处理。

预处理不处理语法错误,只是会执行预处理指令(包含头文件,宏定义,预处理条件开关)。比如,源文件中少了个分号之类的,预处理不会报错,编译的时候才会报错。

(2)编译

编译就是把C/C++代码(比如上述的“.i”文件)“翻译”成汇编代码。编译的时候编译器会检查语法错误

(3)汇编

汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现为ELF目标文件(OBJ文件)。“反汇编”是指将机器代码转换为汇编代码,这在调试程序时常常用到。

(4)链接

链接就是将上步生成的OBJ文件和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。

gcc常用命令

选项 功能
--help 查看所有命令选项
-v 查看gcc编译器的版本,显示gcc执行时的详细过程
-o 指定输出文件名为file,这个名称不能跟源文件名同名
-E 只预处理,不会编译、汇编、链接t
-S 只编译,不会汇编、链接
-c 编译和汇编,不会链接

-pass-exit-codes :从一个阶段以最高错误代码退出。

--target-help :显示特定于目标的命令行选项。

--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...] :显示特定类型的命令行选项(使用 -v --help 显示子进程的命令行选项)。

-dumpspecs :显示所有内置规范字符串。

-dumpversion :显示编译器的版本。

-dumpmachine :显示编译器的目标处理器。

-print-search-dirs :显示编译器搜索路径中的目录。

-print-libgcc-file-name :显示编译器配套库的名称。

-print-file-name=<lib> :显示库 <lib> 的完整路径。

-print-prog-name=<prog> :显示编译器组件 <prog> 的完整路径。

-print-multiarch :显示目标的规范化 GNU 三元组,用作库路径中的一个组件。

-print-multi-directory :显示 libgcc 版本的根目录。

-print-multi-lib :显示命令行选项和多个库搜索目录之间的映射。

-print-multi-os-directory :显示操作系统库的相对路径。

-print-sysroot :显示目标库目录。

-print-sysroot-headers-suffix :显示用于查找标题的 sysroot 后缀。

-Wa,<options> :将逗号分隔的 <options> 传递给汇编器(assembler)。

-Wp,<options> :将逗号分隔的 <options> 传递给预处理器(preprocessor)。

-Wl,<options> :将逗号分隔的 <options> 传递给链接器(linker)。

-Xassembler <arg> :将 <arg> 传递给汇编器(assembler)。

-Xpreprocessor <arg> :将 <arg> 传递给预处理器(preprocessor)。

-Xlinker <arg> :将 <arg> 传递给链接器(linker)。

-save-temps :不用删除中间文件。

-save-temps=<arg> :不用删除指定的中间文件。

-no-canonical-prefixes :在构建其他 gcc 组件的相对前缀时,不要规范化路径。

-pipe :使用管道而不是中间文件。

-time :为每个子流程的执行计时。

-specs=<file> :使用 <file> 的内容覆盖内置规范。

-std=<standard> :假设输入源为 <standard>

--sysroot=<directory> :使用 <directory> 作为头文件和库的根目录。

-B <directory> :将 <directory> 添加到编译器的搜索路径。

-v :显示编译器调用的程序。

-### :与 -v 类似,但引用的选项和命令不执行。

-E :仅执行预处理(不要编译、汇编或链接)。

-S :只编译(不汇编或链接)。

-c :编译和汇编,但不链接。

-o <file> :指定输出文件。

-pie :创建一个动态链接、位置无关的可执行文件。

-I :指定头文件的包含路径。

-L :指定链接库的包含路径。

-shared :创建共享库/动态库。

-static :使用静态链接。

--help :显示帮助信息。

--version :显示编译器版本信息。

参考

gcc详细编译过程


网站公告

今日签到

点亮在社区的每一天
去签到