gcc 编译与链接选项
2023-06-02 https://www.cnblogs.com/NJ-Leon/
Makefile 中的 gcc 编译选项有很多,因此学习记录下。
程序编译的过程
gcc 与 g++ 分别是 gnu 的 c & c++ 编译器。gcc / g++ 在执行编译工作的时候,总共需要4步:
- 预处理,生成 .i 的文件 [ 预处理器 cpp ]
- 将预处理后的文件转换成汇编语言, 生成文件 .s [ 编译器 egcs ]
- 将汇编代码变为目标代码(机器代码)生成 .o 的obj文件 [ 汇编器 as ]
- 连接目标代码, 生成可执行程序 [ 链接器 ld ]
gcc 编译选项 CFLAGS 参数
选项 | 释义 |
-E
|
只激活预处理。 gcc -E hello.c -o hello.i
|
-S
|
只激活预处理和编译,就是只把文件编译成为汇编代码。生成 .s 的汇编代码。
|
-c |
只激活预处理,编译和汇编。用于把源码文件编译成 .o 对象文件,不进行链接,所以,不产生可执行文件。
|
-o |
指定输出,缺省的时候,gcc 编译出来的文件是 a.out
|
-g | 用于在生成的目标文件中,添加调试信息,可以使用 gdb 进行调试。 |
-ggdb |
此选项将尽可能的生成gdb的可以使用的调试信息。
|
-Idir |
添加 dir 目录为头文件搜索路径,如 -I./ 在当前目录查找头文件。
|
-Wall |
显示所有警告信息。
|
-Werror |
视警告为错误,出现任何警告就放弃编译。
|
-w |
不生成任何警告信息。
|
-Wextra
|
打印出更多的警告信息,比开启 -Wall 打印的还多
|
-O | 编译器的优化选项4个级别,-O0 表示没有优化,-O1 为缺省值,-O3 优化级别最高。默认是0,不优化。 |
-fPIC |
PIC 是 position-independent code的意思,此选项去除独立位置代码,适合于动态链接。
|
-v | 显示执行编译阶段的命令,同时显示编译器驱动程序,预处理器,编译器的版本号。 |
-D XXX | 添加宏定义,对程序进行条件编译。 |
-ansi
|
关闭 gnu c 中与 ansi c 不兼容的特性,激活 ansi c 的专有特性(包括禁止一些 asm inline typeof 关键字,以及 UNIX,vax 等预处理宏。
|
-include file
|
包含某个代码。简单来说,就是便于某个文件需要另一个文件的时候,就可以用它设定。功能就相当于在代码中使用 #include
|
-std=
|
编译的标准,包括 GNU99,c++11,c99 等等。
|
gcc 链接选项 LDFLAGS 参数
选项 | 释义 |
-lxxx
|
-l 后面紧接着库名,指定编译时候使用的库,库名为
libxxx.a 或 使用库 curses 进行编译。 |
-Ldir
|
用于把目录 dir 添加到库搜索路径上,可以使用相对和绝对路径,"-L."、“-L./include”、“-L/opt/include”
|
-static |
使用静态库链接生成目标文件,避免使用共享库,生成目标文件会比使用动态链接库大。
|
-share
|
此选项将尽量使用动态库,所以生成文件比较小,但是需要系统有动态库。
|
-shared
|
创建一个动态链接库(不指定的话输出的是 obj 文件) gcc -fPIC -shared func.c -o libfunc.so
|
-rdynamic
|
动态链接符号信息,用于动态链接功能。所有符号添加到动态符号表中(目的是能够通过使用 dlopen 来实现向后跟踪)。
|
-s |
从可执行文件中删除符号表和重定位信息,不能再用 gdb 调试可执行文件。
|
-pthread
|
支持多线程, 使用pthread库
|
LIBS
LDFLAGS 是选项,LIBS 是要链接的库。LDFLAGS 告诉链接器从哪里寻找库文件,LIBS 告诉链接器要链接哪些库文件。
LDFLAGS = -L/var/xxx/lib -L/opt/mysql/lib LIBS = -lmysqlclient -liconv
LDFLAGS 指定 -L ,虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库。如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给 "-Wl,R"
LDFLAGS = -L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib
如果在执行 ./configure 以前,设置环境变量 export LDFLAGS="-L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib" ,注意设置环境变量等号两边不可以有空格,而且要加上引号(shell的用法)。
那么执行 ./configure 以后,Makefile 将会设置这个选项, 链接时会有这个参数,编译出来的可执行程序的库文件搜索路径就得到扩展了。
打包
ar -r libhello.a hello.o 这里的 ar 相当于 tar 的作用,将多个目标打包。Makefile 中用于创建静态链接库(就是把多个目标文件打包成一个)。