GCC 编译选项及使用
gcc/g++指令选项
功 能
-E(大写)
预处理指定的源文件,不进行编译。
-S(大写)
编译指定的源文件,但是不进行汇编。
-c
编译、汇编指定的源文件,但是不进行链接。
-o
指定生成文件的文件名。
-llibrary
在编译链接文件时增加一个额外的库,库名为library.a。建议 -l 和库文件名之间不使用空格。
-ansi
对于 C 语言程序来说,其等价于 -std=c90;对于 C++ 程序来说,其等价于 -std=c++98。
-std=
手动指令编程语言所遵循的标准,例如 c89、c90、c++98、c++11 等。
-Idir
在编译源程序时增加一个搜索头文件的额外目录—dir,即include增加一个搜索的额外目录。
-Ldir
在编译源文件时增加一个搜索库文件的额外目录—dir
-w
禁止所有警告
-Wwarning
允许产生warning类型的警告,warning可以是:main、unused等很多取值,最常用是-Wall,表示产生所有警告。如果warning取值为error,其含义是将所有警告作为错误(error),即出现警告就停止编译。
-Wall
将编译过程中的所有级别的警告都打印出来
GCC -E
示例1:gcc -E demo.c -o demo.i
示例2:gcc -E -C demo.c -o demo.i。
作用:阻止 GCC 删除源文件和头文件中的注释。
GCC -S选项:编译非汇编文件
概述:gcc -S 指令操作的文件并非必须是经过预处理后得到的 .i 文件,-S 选项的功能是令 GCC 编译器将指定文件处理至编译阶段结束。这也就意味着,gcc -S 指令可以操作预处理后的 .i 文件,也可以操作源代码文件:
如果操作对象为 .i 文件,则 GCC 编译器只需编译此文件;
如果操作对象为 .c 或者 .cpp 源代码文件,则 GCC 编译器会对其进行预处理和编译这 2 步操作。
示例1:gcc -S demo.i。
作用:默认情况下,编译操作会自行新建一个文件名和指定文件相同、后缀名为 .s 的文件,并将编译的结果保存在该文件中。
示例2:gcc -S demo.i -o test.i。
作用:将编译结果保存在指定的test.i文件中。
示例3:gcc -S demo.c -fverbose-asm。
作用:提高文件内汇编代码的可读性,可以借助 -fverbose-asm 选项,GCC 编译器会自行为汇编代码添加必要的注释。
GCC -c
概述:gcc -c 选项并非只能用于加工 .s 文件。事实上,-c 选项只是令 GCC 编译器将指定文件加工至汇编阶段,但不执行链接操作。这也就意味着:
如果指定文件为源程序文件(例如 demo.c),则 gcc -c 指令会对 demo.c 文件执行预处理、编译以及汇编这 3 步操作;
如果指定文件为刚刚经过预处理后的文件(例如 demo.i),则 gcc -c 指令对 demo.i 文件执行编译和汇编这 2 步操作;
如果指定文件为刚刚经过编译后的文件(例如 demo.s),则 gcc -c 指令只对 demo.s 文件执行汇编这 1 步操作。
示例1:gcc -c demo.s。
作用:让 GCC 编译器将指定文件加工至汇编阶段,并生成相应的目标文件。
示例2:gcc -c demo.s -o test.o。
作用:将汇编操作的结果输入到指定文件中。
GCC执行链接操作
概述:得到生成目标文件之后,接下来就可以直接使用 gcc 指令继续执行链接操作,gcc 会根据所给文件的后缀名 .o,自行判断出此类文件为目标文件,仅需要进行链接操作。
示例:gcc democ.o -o democ.exe。
GCC -o选项:指定输出文件
概述:gcc -o选项用来指定输出文件,如果不使用 -o 选项,那么将采用默认的输出文件 a.out。
语法格式:gcc [-E|-S|-c] [infile] [-o outfile]。其中,用方括号 [] 括起来的部分可以忽略。
GCC -l 选项:手动添加链接库
链接器的作用:链接器把多个二进制的目标文件(object file)链接成一个单独的可执行文件。在链接过程中,它必须把符号(变量名、函数名等一些列标识符)用对应的数据的内存地址(变量地址、函数地址等)替代,以完成程序中多个模块的外部引用。链接器也必须将程序中所用到的所有C标准库函数加入其中。对于链接器而言,链接库不过是一个具有许多目标文件的集合,它们在一个文件中以方便处理。
libc.a 与 libc.so:标准库的大部分函数通常放在文件 libc.a 中(文件名后缀.a代表“achieve”,译为“获取”),或者放在用于共享的动态链接文件 libc.so 中(文件名后缀.so代表“share object”,译为“共享对象”)。这些链接库一般位于 /lib/ 或 /usr/lib/,或者位于 GCC默认搜索的其他目录。当使用 GCC 编译和链接程序时,GCC 默认会链接 libc.a 或者 libc.so,但是对于其他的库(例如非标准库、第三方库等),就需要手动添加。
gcc main.c -o main.out -lm:使用-l选项,以链接数学库。数学库的文件名是 libm.a。前缀lib和后缀.a是标准的,m是基本名称,GCC 会在-l选项后紧跟着的基本名称的基础上自动添加这些前缀、后缀,本例中,基本名称为 m。
链接其它目录中的库:
背景:通常,GCC 会自动在标准库目录中搜索文件,例如 /usr/lib,如果想链接其它目录中的库,就得特别指明。有三种方式可以链接在 GCC 搜索路径以外的链接库
解决方法:
方法1:把链接库作为一般的目标文件,为 GCC 指定该链接库的完整路径与文件名。
示例:例如,如果链接库名为 libm.a,并且位于 /usr/lib 目录,那么下面的命令会让 GCC 编译 main.c,然后将 libm.a 链接到 main.o:
gcc main.c -o main.out /usr/lib/libm.a
方法2:使用-L选项,为 GCC 增加另一个搜索链接库的目录:
gcc main.c -o main.out -L/usr/lib -lm:可以使用多个-L选项,或者在一个-L选项内使用冒号分割的路径列表。
方法3:把包括所需链接库的目录加到环境变量 LIBRARYPATH 中。