动机
之前对g++/gcc编译过程和编译选项只有浅显了解,因为项目需要,将其学习一下。以下是学习笔记。
g++和gcc
- GNU Compiler Collection即GUN 编译器集合,它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。
gcc
是GCC中的GUN C Compiler(C 编译器);g++
是GCC中的GUN C++ Compiler(C++编译器)。 - 编译时
g++
会自动链接标准库STL,而gcc
不会自动链接STL(使用STL,需要加参数 –lstdc++)。g++编译过程
g++编译程序主要经过四个过程:
1.预处理(Pre-Processing)
2.编译 (Compiling)
3.汇编 (Assembling)
g++调用汇编器进行汇编,生成目标文件.o
。
4.链接 (Linking)
将程序所需要的目标文件进行链接生成可执行文件。
g++编译常用选项
选项名 | 作用 |
---|---|
-o | 指定目标名称 (缺省的时候,gcc 编译出来的文件是a.out) |
-c | 只激活预处理,编译,和汇编,也就是只把程序做成obj文件 |
-Idir | 将dir目录加入搜索头文件的目录路径 |
-Ldir | 将dir目录加入搜索库的目录路径 |
-llib | 链接库目录(-Ldir指定)下的lib库 |
-Wall | 启用大部分警告信息 |
举几个栗子
1
2
3
4
5
6
7
8
g++ -E hello.c -o hello.i # 对hello.c文件进行预处理,生成了hello.i 文件
g++ -S hello.i -o hello.s # 对预处理文件进行编译,生成了汇编文件
g++ -c hello.s -o hello.o # 对汇编文件进行编译,生成了【目标文件】
g++ hello.o -o hello # 对目标文件进行链接,生成【可执行文件】
g++ hello.c -o hello # 直接编译链接成【可执行目标文件】
g++ test1.c test2.c -o test # 编译test1.c test2.c并链接生成可执行文件test
头文件/库文件链接
开发软件时,完全不使用第三方函数库的情况是比较少见的,通常来讲都需要借助许多函数库的支持才能够完成相应的功能。
路径
一般头文件的位置在
/usr/include
及其子目录底下的include文件夹/usr/local/include
及其子目录底下的include文件夹
库文件的位置在
/usr/lib
/usr/local/lib
但也有的时候,我们要用的头文件和库文件不在这些目录下,这时候需要我们使用-I
和-L
编译选项来指定搜索路径,比如:
程序test.c
是在linux上使用c连接mysql,这个时候我们需要去mysql官网下载MySQL Connectors的C库,下载下来解压之后,有一个include文件夹,里面包含头文件,还有一个lib文件夹,里面包含二进制so文件。 那么头文件搜索目录为$(workPath)/include
,lib文件夹是为$(workPath)/lib
动态库/静态库
Linux下的库文件分为两大类,分别是动态链接库(通常以.so
结尾)和静态链接库(通常以.a
结尾),二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。
- 静态库(
.a
):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。 - 动态库(
.so
或.sa
):程序在运行的时候才去链接共享库的代码,多个程序共享使用库的代码,这样就减少了程序的体积。