GCC 编译选项总结

-c

只激活预处理,编译,和汇编,也就是他只把程序做成obj文件

例子用法:

gcc -c hello.c 

他将生成 .o 的 obj 文件

-S

只激活预处理和编译,就是指把文件编译成为汇编代码。

例子用法:

gcc -S hello.c 

他将生成 .s 的汇编代码,你可以用文本编辑器察看。

-E

只激活预处理,这个不生成文件, 你需要把它重定向到一个输出文件里面。

例子用法:

gcc -E hello.c > pianoapan.txt 
gcc -E hello.c | more 

慢慢看吧, 一个 hello word 也要预处理成800行的代码。

-o

指定目标名称, 默认的时候, gcc 编译出来的文件是 a.out, 可以改掉它。

例子用法:

gcc -o hello.exe hello.c (,windows用习惯了) 
gcc -o hello.asm -S hello.c

-g

指示编译器,在编译的时候,产生调试信息。

-x language

指定无论源文件以什么作为后缀名,使后缀名无效,按language编译。
例子用法:

 gcc -x c hello.pig 

-x none filename

关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型 。
例子用法:

gcc -x c hello.pig -x none hello2.c 

-mcpu=name

指定目标处理器的名字

-mthumb / -marm

指定生成的代码是在ARM状态下执行还是在Thumb状态下执行。

-Dmacro

相当于 C 语言中的 #define macro

-Dmacro=defn

相当于 C 语言中的 #define macro=defn

-include file

包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以用它设定,功能就相当于在代码中使用 #include<filename>
例子用法:

gcc hello.c -include /root/pianopan.h 

-Idir

在你是用 #include “file” 的时候, gcc/g++ 会先在当前目录查找你所制定的头文件, 如果没有找到, 它会到默认的头文件目录找, 如果使用 -I 制定了目录,他会先在你所制定的目录查找, 然后再按常规的顺序去找。

-I-

就是取消前一个参数的功能, 所以一般在 -Idir 之后使用。

-idirafter dir

在 -I 的目录里面查找失败, 将到这个目录里面查找。

-Wall

生成所有警告信息。

-fdata-sections ; -ffunction-sections ; -Wl,–gc-sections

有时我们的程序会定义一些暂时使用不上的功能和函数,虽然我们不使用这些功能和函数,但它们往往会浪费我们的ROM和RAM的空间。这在使用静态库时,体现的更为严重。有时,我们只使用了静态库仅有的几个功能,但是系统默认会自动把整个静态库全部链接到可执行程序中,造成可执行程序的大小大大增加。

为了解决前面分析的问题,引入了上面几个参数。GCC链接操作是以section作为最小的处理单元,只要一个section中的某个符号被引用,该section就会被加入到可执行程序中去。因此,GCC在编译时可以使用 -ffunction-sections-fdata-sections 将每个函数或符号创建为一个sections,其中每个sections名与function或data名保持一致。而在链接阶段, -Wl,–gc-sections 指示链接器去掉不用的section(其中-wl, 表示后面的参数 -gc-sections 传递给链接器),这样就能减少最终的可执行程序的大小了。

我们常常使用下面的配置启用这个功能:

CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections

-u symbol

假装符号symbol未定义,以强制链接库模块来定义它。您可以对不同的符号多次使用-u 来强制加载其他库模块。

-l ; -L

-l 参数就是用来指定程序要链接的库,-l 参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。

好了现在我们知道怎么得到库名,当我们自已要用到一个第三方提供的库名字libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与libtest.so配套的头文件)

放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了,但如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/usr/bin/ld: cannot find-lxxx”,也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest。

-gdwarf ;-gdwarf-version

以DWARF格式产生调试信息(如果支持的话)。版本的值可以是2、3、4或5。

-Wa,option

此选项传递 option 给汇编程序; 如果 option 中间有逗号, 就将 option 分成多个选项, 然 后传递给汇编程序。

-Wl,option

此选项传递 option 给链接程序; 如果 option 中间有逗号, 就将 option 分成多个选项, 然后传递给链接程序。

-M ;-MM ;-MD; -MMD ;-MF;-MT

生成文件关联的信息。包含目标文件所依赖的所有依赖文件。-MM 和-M一样,但会忽略由#include造成的依赖关系。-MD,-MMD与-M,-MM相同,只是将依赖信息输出到了目标文件名.d文件。

-MF 指定一个文件用于存放生成文件的关联信息,如果不指定,默认是存放在目标文件名.d中。

-MT 指定目标文件名。

-MP

这个选项指示预处理器为主文件以外的每个依赖关系添加一个假目标,使每个依赖关系都不依赖任何东西。这些假规则可以解决如果你删除头文件而不更新 Makefile 的错误。

-specs = file

用于覆盖gcc默认的传递参数,这些新的参数是在一个新的文件里面里面指定,一般file是以.specs结尾。

-specs=nano.specs 的作用:
nona.specs 将 -lc 替换成 -lc_nano,使有精简版的C库替代标准C库,可以减少最终程序映像的大小。

-T script

将脚本用作链接器脚本。大多数使用GNU链接器的系统都支持此选项。在某些目标上,例如没有操作系统的裸板目标,链接时可能需要“-T”选项,以避免引用未定义的符号。

--cref

Cross Reference的简写,输出交叉引用表(cross reference table)。


版权声明:本文为weixin_51760563原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。