Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:cpp:编译选项

Gcc和G++的编译选项

可以参考一下这里:odt笔记_20221007(gnu编译套件.odt)


宏:
-D[MACRO] 定义宏
-D[MACRO=DEFN] 定义宏
-U[MACRO] 取消定义一个宏

编译:
-I[path] 添加头文件路径
-L[path] 添加链接路径
-l[lib] 添加链接库,默认是动态链接,找不到动态链接库则尝试寻找静态链接库;-lxxx对应的lib文件是libxxx.so/libxxx.a
-E 只进行预编译
-S 编译到汇编代码
-c 编译到目标代码
-g 生成调试信息
-o 指定输出文件
-fPIC 生成位置独立代码,这是动态库的必需选项
-static 指定使用静态链接(对所有链接库生效)
-shared 生成动态链接库
--std=[c++11] 指定C++语言标准

警告:
-w 关闭所有警告
-Wall 生成所有警告
-W[address] 开启某一个警告,[]里面有很多可以填的选项,address表示使用可疑的内存地址时给出警告
-Werror 把所有的警告视为错误
-Werror=[switch] 将某一个警告视为错误,[]里面有很多可以填的选项
-Wno-error=[switch] 将某一个警告不视为错误,[]里面有很多可以填的选项
-Wextra 打开额外的警告(all里面没有包括的)
-pedantic 以ANSI/ISO C标准列出的所有警告

优化:
-O0 不进行优化
-O 优化等级1
-O1 优化等级1
-O2 优化等级2
-O3 优化等级3(最大)
-fno-elide-constructors 关闭编译器的返回值优化

g++的链接细节

g++ 中的 -lxxx 默认是动态链接(shared linking),不是静态链接。

g++ main.cpp -lfoo
// 如果系统中有 libfoo.so(共享对象),g++ 会优先链接这个动态库。
// 只有当找不到 .so 时,它才可能尝试链接静态库 .a(如果没有禁用静态链接)。

// 如果你想强制使用静态库链接(比如 libfoo.a),你可以这样写:
g++ main.cpp /path/to/libfoo.a
g++ -static main.cpp -lfoo
// 不过使用 -static 会尝试对所有库都进行静态链接,这可能会引发一些链接错误
// 特别是 libc 或 libstdc++ 静态链接时。

include/link参数的顺序

# include

# 【结论】同名头文件出现多份时,排在 -I 列表最前面的目录会“遮住”后面的目录
# 【/project/include】优先
-I/project/include -I/third_party/include

# 以下两条命令几乎没有区别
# 编译器在真正调用预处理器前,会把整条命令行里出现的所有 -I 目录收集好
# 然后按它们在 -I 之间的先后顺序搜索。它不会因为源文件名写在中间就提前开始扫描
# 【结论】【-I】的相互顺序有影响(前面的优先),【-I和源文件】的顺序不重要
g++ -I/path e1.cpp
g++ e1.cpp -I/path

# link

# 先编译 e1.cpp,找出用到的 C++ 标准库符号,再用 -lc++ 去满足它
# 【先提出需求(e1.cpp用到了哪些函数)】【再满足需求(从-l的参数中去找到这些需要的函数)】
mpiCC e1.cpp -lc++

# 链接器先看到 -lc++,但这时候它还不知道 e1.cpp 里用不用 libc++ 的符号
# 所以它基本跳过(动态库按需/静态库直接无效),等它看到 e1.cpp 后,已经不会回头重新看前面的库
# 链接失败,找不到符号
# 【总结:目标文件(或源文件)前,库放后,结果更稳定】
mpiCC -lc++ e1.cpp
/var/www/DokuWikiStick/dokuwiki/data/pages/程序/cpp/编译选项.txt · Last modified: 2025/07/19 15:35 by zhonghui