g++ 命令

g++ 命令

常见 g++ 编译选项

路径和链接库

参数 含义
-I #include 包含头文件时,头文件的查找路径,将依次查找
-isystem #include <header> 包含头文件时,文件的查找路径(优先级在 -I 之后),而且将不显示这些头文件里出现的警告
-l 需要链接的库
-L 链接库所在的路径
-Wl, rpath 需要添加到程序 RUNPATH 的路径
-pthread 多线程编译

宏和优化级别

-DMACRO 或者 -DMACRO=value 可以指定宏。其中最重要的一个是 -DNDEBUG,用于取消生产版本里的 assert 指令(注意 -g 并不会取消 assert 指令)。

-g 则用于生成 debug 信息,-O0-O1-O2-O3则是不同的优化级别。

我们在编译时经常会碰到 make release 或者 make debug,事实上它们分别是上面指令的组合:

  • make release: -DNDEBUG -O2
  • make debug: -g -O0

错误信息相关

参数 含义
-Wall 大部分常见的警告信息。
-Wextra -Wall更多的警告信息。
-Werror 将警告视作错误,会阻止编译进行,对大多数情况下过于严厉。
-pedantic ANSI/ISO C 标准所列出的所有警告。
-Wwarning-type 提示具体的警告类型。
-Wno-warning-type 不提示具体的警告类型。

常用的一个组合为:-Wall -Wextra -pedantic -Werror=return-type -Winvalid-pch -Wno-unused-parameter

其他选项

参数 含义
-std=c++11 指定 C++ 版本。可用c++1z
-MD 会生成.d依赖文件,记录头文件的依赖关系,方便编译器根据修改情况来决定是否需要重新编译,通常会加上
-pipe 中间文件直接放在内存,而不是显式的临时文件,通常会加上
-fPIC 生成动态链接库的目标文件时,必须添加该选项。生成静态库,但被其它动态库时用时,也需要添加该选项
-share 表示生成的目标文件为动态链接库
-m64 生成 64 位应用程序

普通编译

文件目录结构

1
2
3
4
5
6
.
├── include
│ └── swap.h
├── main.cpp
└── src
└── swap.cpp

使用 g++ 进行普通编译

1
2
3
4
5
6
7
8
9
$ g++ main.cpp src/swap.cpp
main.cpp:1:10: fatal error: swap.h: No such file or directory
1 | #include "swap.h"
| ^~~~~~~~
compilation terminated.
src/swap.cpp:1:10: fatal error: swap.h: No such file or directory
1 | #include "swap.h"
| ^~~~~~~~
compilation terminated.

使用 g++ 加上 -Iinclude 参数编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ g++ main.cpp src/swap.cpp -Iinclude

# 新的目录结构
.
├── a.out
├── include
│ └── swap.h
├── main.cpp
└── src
└── swap.cpp

$ ./a.out
Before Swap:
a: 0 b: 1
After Swap:
a: 1 b: 0

增加编译参数

1
2
3
4
5
6
$ g++ main.cpp src/swap.cpp -Iinclude -Wall -std=c++11 -o b.out
$ ./b.out
Before Swap:
a: 0 b: 1
After Swap:
a: 1 b: 0

静态库和动态库编译

链接静态库生成可执行文件

1
2
3
4
5
6
7
8
9
10
11
12
# 汇编,生成 swap.o 文件
$ g++ swap.cpp -c -I../include
# 生成静态库文件 libswap.a
$ ar rs libswap.a swap.o
ar: creating libswap.a
# 链接,生成可执行文件 static_main
$ g++ main.cpp -lswap -Lsrc -Iinclude -o static_main
$ ./static_main
Before Swap:
a: 0 b: 1
After Swap:
a: 1 b: 0

链接动态库生成可执行文件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 生成动态库文件 libswap.so
$ g++ swap.cpp -I../include -fPIC -shared -o libswap.so
## 上面的一条指令等价于这两条指令
$ gcc swap.cpp -I..include -c fPIC
$ gcc -shared -o libswap.so swap.o

# 链接,生成可执行文件: sharemain
$ g++ main.cpp -Iinclude -Lsrc -lswap -o sharemain
$ ./sharemain
Before Swap:
a: 0 b: 1
After Swap:
a: 1 b: 0

参考文献

张君宝的微课堂: https://zhiqiang.org/coding/gcc-compile-paras.html