前言
gcc是一个非常强大的编译器,它是跨平台的,早起iOS,安卓,linux,mac都支持gcc的编译(ps:现在iOS,安卓,mac都转移到功能性能更优的clang编译器了,不过clang编译器也是基于gcc编译器优化而来的,它同样也支持上述系统)
- mac系统下gcc命令被连接到了clang命令,所以mac系统下,gcc命令和clang命令最终都是clang编译器(编译参数跟gcc大同小异)。Linux系统下gcc被默认安装,clang则需要手动安装,两者是不同的命令。
- gcc编译器有默认的编译参数,一般情况下使用gcc进行编译时不需要更改相关参数
接下来就是常用的gcc编译参数
- 命令 gcc --help可以查看命令详情
gcc常用编译参数
- 1、-Dmacro
使用该参数后,相当于声明了#define macro语句,被编译的源文件都可以使用该宏,比如如下源代码test.c
#ifdef CONFIG_PI
int var = 1;
#endif
如果编译时命令为:gcc -c -DCONFIG_PI test.c -o test.o 那么将会执行int var=1;语句
- 2、-Dmacro=val
使用该参数后,相当于声明了#define macro=val,被编译的源文件都可以使用该宏,比如如下源代码test.c
#if CONFIG_PI
int var = 1;
#endif
如果编译时命令为:gcc -c -DCONFIG_PI=1 test.c -o test.o 那么将会执行int var=1;语句
-
3、-Umacro
使用该参数后,相当于声明了#undef macro,被编译的源文件该宏都将不可见了 -
4、-undef
取消对任何非标准宏的定义,切勿使用该选项,会造成意想不到效果 -
5、-Idir
-I和dir之间可加空格也可以挨着写
对于#include "file";编译器默认按照当前目录,系统目录的顺序查找,如果指定了-Idir,那么将先到dir所在目录去搜索要包含的文件未找到按默认规则查找
对于#include<file>;编译器默认只在系统目录查找。如果指定了-Idir,那么将先到dir所在目录去搜索要包含的文件未找到按默认规则查找
系统目录一般是操作系统的标准头文件搜索目录,编译器自带的搜索路目录等等(gcc和clang不太一样,不过含义是一样的)如下为clang编译器的系统目录
gcc -c main.c -o main.o -v
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
-
6、-I-
取消前一个-Idir参数的定义 -
7、-nostdinc
取消编译器的默认头文件搜索规则,一般和-Idir联合使用,明确限定头文件的搜索目录。 -
8、-E、-S、-c
-E:生成预处理后的代码 如gcc -E main.c -o main.i
-S:生成汇编代码 如gcc -S main.i -o main.s
-c:生成目标代码(二进制,用于连接) gcc -c main.s -o main.o -
9、-C
在预处理的时候, 不删除注释信息, 一般和-E使用, 分析程序用。
分别执行
gcc -E main.c -o main.i
gcc -E -C main.c -o main.i
可以看到没有-C时 main.i文件将没有注释信息
-
10、-llib
指定编译的源文件中所引用的外部库名称,-l和lib之间可加空格也可不加,该选项在编译阶段可加可不加,连接阶段才有效。 -
11、-Ldir
指定编译的源文件中所引用的外部库的搜索路径,-L和lib之间可加空格也可不加,该选项在编译阶段可加可不加,连接阶段才有效。连接器默认会在当前目录,系统目录搜索库,优先使用动态库,如果指定了此选项,那么将优先在dir目录下搜索库,未找到则按默认规则搜索
备注:如果最终可执行程序是动态链接生成的,那么程序加载时默认到系统目录(一般是/usr/local/lib下)下搜索所引用的动态库(并非会到上面的dir中搜索),如果设置了LD_LIBRAY_PATH环境变量的值,那么程序加载时动态库将优先去该路径搜索,然后按默认规则搜索
-
12、-O0 、-O1 、-O2 、-O3
编译器的优化级别,-O0 表示没有优化, -O1 为默认值,-O3 优化级别最高。 -
13、-g
编译器编译的时候产生用于调试的额外信息,程序体积会比较大 -
14、-ggdb
编译器编译的时候产生用于gdb调试的额外信息,程序体积会比较大 -
15、-static
编译器将采用静态链接 -
16、-shared
编译器默认就为此选项(动态链接) -
17、-Wall
启用所有的警告输出 -
18、-Werror
编译器会将所有的警告转换成错误信息,备注:当碰到警告信息时会当成错误退出编译 -
19、-std
指定编译器中C/C++的标准。不同版本的gcc编译器默认的c/c++标准不一样,比如7.5.0版本gcc编译器默认c++标准为c++11;
gcc -std=c++11 hello-world.cpp
可指定的值有c++11, c++14, c90, c89等等
-
20、-v
打印编译过程中的所有信息 -
21、-fPIC
编译位置无关的目标文件,编译阶段使用。当动态链接和编译动态库时要开启此选项 -
22、-Wl,option1,-Wl,option2.......
用来设置连接阶段的参数







网友评论