gcc/g++ 常见的编译命令
大约 6 分钟
gcc/g++ 常见的编译命令
基本编译命令
- 编译C程序:
gcc filename.c -o outputname
- 编译C++程序:
g++ filename.cpp -o outputname
添加编译选项
-g
:添加调试信息,用于gdb等调试器。-O2
或-O3
:优化代码,提高运行效率。-Wall
:显示所有警告信息。-Wextra
:显示额外的警告信息。-Werror
:将所有警告当作错误处理。gcc -g -O2 -Wall filename.c -o outputname g++ main.cc -m32 -g -o main.o #-m32指定编译为32位程序

包含头文件和库
-I
:指定头文件搜索路径。-L
:指定库文件搜索路径。-l
:链接指定的库。 例如:gcc -I/path/to/headers -L/path/to/libs -lmylib filename.c -o outputname
编译多个源文件
gcc file1.c file2.c file3.c -o outputname
预处理、编译、汇编和链接
-E
:只进行预处理,输出到标准输出。-S
:编译并汇编,输出汇编代码。-c
:编译并汇编,输出目标文件(.o)。
例如,只进行预处理:gcc -E filename.c -o output.i
使用静态库和动态库
静态库:在链接时,库文件会被拷贝到可执行程序中(产品中打包了库文件)
动态库:在链接时库文件会提供自己的位置,在运行时根据位置进行加载(运行时加载的库文件)
特点 | 可执行程序的大小 | 安装难度 | 升级 |
---|---|---|---|
静态 | 大 | 低 | 难 |
动态 | 小 | 高 | 容易 |
- 创建静态库:
- 生成目标文件
gcc -c mylib.c -o amylib.o
- 打包成库文件
ar crsv libmylib.a mylib.o
- 生成目标文件
- 创建动态库:
- 编译时生成与
gcc -c mylib.c -o amylib.o -fpic
- 从目标文件生成动态文件
gcc -shared -o libmylib.so mylib.o
- 编译时生成与
- 链接静态库:
gcc filename.c -L. -lmylib -o outputname
- 链接动态库:除了上面的链接命令(
gcc filename.c -L. -lmylib -o outputname
),还需要在运行时指定动态库的位置,可以使用LD_LIBRARY_PATH
环境变量或/etc/ld.so.conf
文件来实现。
如何更新动态库🍗🍗🍗
动态库的好处:用户不需要重新链接就能更新库文件
重新编译库
gcc -shared -o libmylib.so mylib.c -fPIC
更新版本号:如果服务端;如果不更新协议,可以多个客户端版本共用一个服务端。
安装新库:需要将它安装到系统中合适的位置。这通常意味着将库文件复制到某个标准库目录,如
/usr/local/lib
或/usr/lib
mv libmylib.so libmylib.so.0.0.1 sudo cp libmylib.so.0.0.1 /usr/lib/ sudo rm libmylib.so #删除旧的软链接 sudo ln -s libmylib.so.0.0.1 libmylib.so #重新建立新链接
image-20240310173458700 - 版本号决定了新旧程序
- 保存所有版本的库文件(因为不知道新版本的库文件是否会产生bug)
- 建立库文件和libmylib.so的软链接(为了让程序链接或运行过程中能正确找到相应的库文件)
- 如果更新,重建软链接即可
更新库缓存:在某些系统上,如 Linux,当新的共享库被安装后,你可能需要更新系统的库缓存。这通常可以通过运行
ldconfig
命令完成,该命令会重新生成/etc/ld.so.cache
文件,该文件包含了系统中所有共享库的列表。sudo ldconfig
或者,如果你的库安装在一个非标准目录,你可能需要编辑
/etc/ld.so.conf
文件并添加你的库目录,然后再运行ldconfig
。
gcc -fpic 什么作用(了解)
- 主要用于生成位置无关代码(Position Independent Code,简称 PIC)。这种代码的特性在于没有绝对跳转,所有的跳转都是相对跳转,因此代码可以被加载器加载到内存的任意位置并正确执行(因为共享库在加载到内存时,其位置不是固定的,因此必须能够处理这种不确定性)。
- 使用
-fPIC
选项编译的源文件在引用函数头文件时,有更宽松的尺度。例如,只需要包含函数的声明头文件,即使没有相应的 C 文件来实现这些函数,编译成共享库(.so 文件)也可以成功
ar crsv 作用
ar
是 Unix-like 系统中的一个工具,用于创建、修改和提取静态库文件(通常具有 .a
扩展名)
c
:创建一个库。如果库已经存在,则替换它。r
:将文件插入库中。如果文件已存在于库中,则替换它。s
:创建或更新库的目标文件索引。这对于加速链接过程很有用,因为链接器可以使用索引来快速找到库中的特定符号。v
:详细模式。显示正在执行的操作的详细信息。
示例:
当你使用 ar crsv libname.a file1.o file2.o
这样的命令时,你实际上是在告诉 ar
:
- 创建一个名为
libname.a
的静态库(如果它不存在的话)。 - 将
file1.o
和file2.o
这两个目标文件添加到库中(如果它们已经存在于库中,则替换它们)。 - 更新或创建库的索引。
- 显示执行过程中的详细信息。
同时存在动态库(共享库)和静态库
- 默认行为:在许多系统中,如果没有显式指定,链接器默认会优先链接到,因为它们通常更小,多个程序可以共享同一个库文件,从而节省磁盘空间。
- 链接器选项:链接器通常接受一些选项来控制它应该优先链接到哪种类型的库。例如,GCC 链接器接受
-static
和-shared
选项来分别指示链接器优先链接到静态库或动态库。
如果你想要控制链接的优先级,你可以使用以下策略:
- 显式指定库文件:在链接时,你可以直接指定要链接的库文件的路径。例如,使用
-L
选项来添加库文件的搜索路径,并使用-l
选项来指定库名。如果你想要链接到静态库,你可以直接指定静态库文件的路径(包括.a
扩展名)。🍔
gcc your_program.o -L/path/to/libs -l:libmylib.a -o your_program
- 使用链接器选项:使用
-static
选项告诉链接器优先链接静态库。🍔
gcc your_program.o -static -lmylib -o your_program_static
- 修改环境变量:某些系统允许通过设置环境变量(如
LD_LIBRARY_PATH
对于运行时动态库搜索,或者LIBRARY_PATH
对于链接时库搜索)来影响库的搜索顺序。