gcc 编译与链接选项

 
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 或 libxxx.so gcc -lcurses hello.c  使用库 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 中用于创建静态链接库(就是把多个目标文件打包成一个)。
 

posted on 2023-06-02 16:02  NJ_Leon  阅读(181)  评论(0编辑  收藏  举报

导航