gcc编译系统 不念不忘少年蓝@ 2022-06-13 10:51 270阅读 0赞 ## 一、文件名后缀 ## 常用文件名后缀及其表示的文件类型如下表: <table> <thead> <tr> <th align="left">文件名后缀</th> <th align="left">文件类型</th> </tr> </thead> <tbody> <tr> <td align="left">.c</td> <td align="left">C 源文件</td> </tr> <tr> <td align="left">.i</td> <td align="left">预处理后的 C 源文件</td> </tr> <tr> <td align="left">.ii</td> <td align="left">预处理后的 C++ 源文件</td> </tr> <tr> <td align="left">.h</td> <td align="left">C 或 C++ 头文件</td> </tr> <tr> <td align="left">.C .cc .cp .cpp .c++ .cxx</td> <td align="left">C++ 源文件</td> </tr> <tr> <td align="left">.s</td> <td align="left">汇编程序文件</td> </tr> <tr> <td align="left">.S</td> <td align="left">必须预处理的汇编程序文件</td> </tr> <tr> <td align="left">.o</td> <td align="left">目标文件</td> </tr> <tr> <td align="left">.a</td> <td align="left">静态链接库</td> </tr> <tr> <td align="left">.so</td> <td align="left">动态链接库</td> </tr> </tbody> </table> ## 二、程序的编译过程 ## ![编译流程][20170705135553918] ### 2.1 预处理 ### 在这一阶段,源码中的所有预处理语句得到处理。**预处理之后源码中不再包含任何预处理语句。** 例如: * `#include` 语句所包含的文件内容替换掉语句本身 * 所有已定义的宏被展开 * 根据 `#ifdef`、`#if` 等语句的条件是否成立取舍相应的部分 GCC预处理阶段可以生成 `.i` 的文件,通过选项 `-E` 可以使编译器在预处理结束时就停止编译。 例如: gcc -E -o hello.i hello.c ### 2.2 编译 ### 这一阶段,编译器**对源码进行词法分析、语法分析、优化等操作,最后生成汇编代码**。这是整个过程中最重要的一步,因此也常把整个过程称为`编译`。 可以通过选项 `-S` 使 GCC 在进行完编译后停止,生成 `.s` 的汇编程序。例如: gcc -S -o hello.s hello.c ### 2.3 汇编 ### 这一阶段**使用汇编器对汇编代码进行处理,生成机器语言代码**,保存在后缀为 `.o` 的目标文件中。当程序由多个代码文件构成时,每个文件都要先完成汇编工作,生成 .o 目标文件后,才能进入下一步的链接工作。 目标文件已经是最终程序的某一部分了,只是在链接之前还不能执行。可以通过 `-c` 选项生成目标文件。例如: gcc -c -o hello.o hello.c ### 2.4 链接 ### 经过汇编以后的机器代码还不能直接运行。为了使操作系统能够正确加载可执行文件,文件中必须包含固定格式的信息头,还必须与系统提供的启动代码`链接`起来才能正常运行,这些工作都是由链接器来完成的。例如: gcc -o hello hello.c ## 三、gcc 的基本用法 ## gcc [-Wall] [-O1..3] [-g] [-o name] file... * `-Wall`: 打开所有警告项 * `-O`: 设置优化级别,O0 表示关闭优化功能 * `-g`: 将调试信息编译到目标文件中 * `-o name`: 指定输出文件的名称是 name * `file`: 被编译(链接)的文件 使用举例: ![20170705140416364][] ## 四、gcc 命令行选项 ## 按照选项作用所对应的编译阶段,可将 gcc 的选项分为四组:**预处理选项、编译选项、优化选项和连接选项**。 ### 4.1 预处理选项 ### <table> <thead> <tr> <th align="left">选项格式</th> <th align="left">功能</th> </tr> </thead> <tbody> <tr> <td align="left">-C</td> <td align="left">在预处理后的输出中保留源文件中的注释</td> </tr> <tr> <td align="left">-D name</td> <td align="left">预定义一个宏 name,而且其值为 1</td> </tr> <tr> <td align="left">-D name=definition</td> <td align="left">预定义一个宏 name,并指定其值为 definition 所指定的值。其作用等价于在源文件中使用宏定义指令:#define name definition。但 -D 选项比宏定义指令的优先级高,它可以覆盖源文件中的定义</td> </tr> <tr> <td align="left">-U name</td> <td align="left">取消先前对 name 的任何定义,不管是内置的,还是由 -D 选项提供的</td> </tr> <tr> <td align="left">-I dir</td> <td align="left">指定搜索头文件的路径 dir。先在指定的路径中搜索要包含的头文件,若找不到,则在标准路径(/usr/include, /usr/lib及当前工作目录)上搜索</td> </tr> <tr> <td align="left">-E</td> <td align="left">只对指定的源文件进行预处理,不做编译,生成的结果送到标准输出</td> </tr> </tbody> </table> ### 4.2 编译选项 ### <table> <thead> <tr> <th align="left">选项格式</th> <th align="left">功能</th> </tr> </thead> <tbody> <tr> <td align="left">-c</td> <td align="left">只生成目标文件,不进行连接。用于对源文件的分别编译</td> </tr> <tr> <td align="left">-S</td> <td align="left">只进行编译,不做汇编,生成汇编代码文件格式,其名与源文件相同,但扩展名为 .s</td> </tr> <tr> <td align="left">-o file</td> <td align="left">将输出放在文件file中。如果未使用该选项,则可执行文件放在 a.out 中</td> </tr> <tr> <td align="left">-g</td> <td align="left">指示编译程序在目标代码中加入供调试程序 gdb 使用的附加信息</td> </tr> <tr> <td align="left">-v</td> <td align="left">在标准出错输出上显示编译阶段所执行的命令,即编译驱动程序及预处理程序的版本号</td> </tr> </tbody> </table> ### 4.3 优化选项 ### 优化分为对中间代码的优化和针对目标码生成的优化。 ### 4.4 连接选项 ### <table> <thead> <tr> <th align="left">选项格式</th> <th align="left">功能</th> </tr> </thead> <tbody> <tr> <td align="left">object-file-name</td> <td align="left">不以专用后缀结尾的文件名就认为是目标文件名或库名。连接程序可以根据文件内容来区分目标文件和库</td> </tr> <tr> <td align="left">-c -S -E</td> <td align="left">如果使用其中任何一个选项,那么都不运行连接程序,而且目标文件名不应该用做参数</td> </tr> <tr> <td align="left">-llibrary</td> <td align="left">连接时搜索由 library 命名的库。连接程序按照在命令行上给定的顺序搜索和处理库及目标文件。实际的库名是 liblibrary.a</td> </tr> <tr> <td align="left">-static</td> <td align="left">在支持动态连接的系统中,它强制使用静态链接库,而阻止连接动态库;而在其他系统中不起作用.把指定的目录 dir 加到连接程序搜索库文件的路径表中,即在搜索-l后面</td> </tr> <tr> <td align="left">-L dir</td> <td align="left">列举的库文件时,首先到 dir 下搜索,找不到再到标准位置下搜索</td> </tr> <tr> <td align="left">-Bprefix</td> <td align="left">该选项规定在什么地方查找可执行文件、库文件、包含文件和编译程序本身数据文件</td> </tr> <tr> <td align="left">-o file</td> <td align="left">指定连接程序最后生成的可执行文件名称为 file,不是默认的 a.out</td> </tr> </tbody> </table> [20170705135553918]: /images/20220613/84c7ba79c76f44e7b10b06a95b28d0bb.png [20170705140416364]: /images/20220613/0ab56c877fe34439ad8c9bb8f3050e1d.png
还没有评论,来说两句吧...