简介
makefile 是一种描述软件工程使得编译规则和各个文件依赖关系的文件。
make 是一个命令工具,负责解释makefile 文件指令。是编译器标配的命令。
makefile 的编写规则
all: book1 book2
book1: book1.c
gcc -o book1 book1.c
book2: book2.c _public.h _public.c
gcc -o book2 book2.c _public.c
clean:
rm -f book1 book2
注意:gcc 前的空格是一个制表符\t
。
g++ 编译命令
1. 预处理
主要动作: 宏的替换,注释的消除,找到相关的库文件
命令:g++ -E test.cpp func.cpp > test.i
生成文件: test.i
只激活预处理,不生成文件,需要重定向到一个输出文件里
2.编译
主要动作:将预处理后的文件转换为汇编文件,里面为汇编指令
命令:g++ -S test.cpp func.cpp
生成文件 test.s func.s (汇编)
3.汇编
主要动作:将汇编文件转换为目标文件(二进制)
命令:g++ -c test.cpp func.cpp
生成 test.o func.o 文件(二进制)
4.链接
主要动作:将多个目标文件、库文件整合为可执行文件
命令:g++ test.o func.o
或者命令:g++ test.s func.s
或者命令:g++ test.cpp func.cpp
生成 a.out 文件
5.链接高级指令
5.1 -o
用于指定生成二进制目标文件名称
// 生成 test 二进制文件,实质是将a.out 重命名为 test
g++ test.cpp func.cpp -o test
5.2. -I
添加搜索头文件的路径(大写i)
系统默认头文件搜索路径大致为
当前目录(如果是双引号包含的话) --> /usr/include --> /usr/local/include
// 添加/home/include 到搜索路径,实际上此语句应该不常用,因为默认搜索路径一般够用了
g++ test.cpp -I/home/include
/*** 此时,搜索路径为
当前目录(如果是双引号包含的话) --> /home/include --> /usr/include --> /usr/local/include
***/
5.3. -L
指定要链接的库所在目录,-l
指定路径寻找库文件
链接时库搜索路径 /lib --> /usr/lib -->/usr/local/lib
运行时库搜索路径 /lib --> /usr/lib
注意,这里只是在链接是说明链接库所在目录,决定了二进制文件是否可以生成,但该二进制文件能否真正运行,还未可知,如果链接的是静态库则肯定可以运行,如果链接的是动态库,在默认搜索目录没有找到需要的库文件,则不能正常运行。
// -L 将/lib 添加到库搜索目录,
// -l 将 libm.so 库文件链接到项目
g++ test.cpp -L/usr/local/lib -lfmt
5.4 -shared -fPIC
生成动态库
g++ my_lib.cpp -shared -fPIC -o libmylib.so
6. 添加运行时库搜索路径的两种方法
6.1 更改系统相关文件
以添加 usr/local/lib
为例
sudo vi /etc/ld.so.conf
//添加一行如下一行
/usr/local/lib
// 保存并退出
:x
// 更新缓存
sudo ldconfig
另外补充一下,mysql,opencv等在安装时候会在/etc/ld.so.conf.d/ 文件夹下建立相应的.conf文件来声明运行时库搜索地址,通过查看ld.so.conf.d下的各个文件就能得知整个系统在运行时库搜索的全部路径。
6.2 在链接程序时就指定运行时搜索库文件路径
使用-wl,-rpath=<link_path>
参数
g++ 123.cpp -L. -lmylib -Wl,-rpath=./
其中 -L . 指定将当前目录加入链接库搜索路径
-l 将 libmylib.so 链接如目标文件
-Wl,-rpath=./ 将当前目录加入运行时库搜索路径
7 添加系统默认的头文件搜索路径
添加默认的头文件搜索路径
sudo vi /etc/profile
// 添加如下代码,中间的即为要添加的搜索路径
export CPLUS_INCLUDE_PATH=/www/server/mysql/include:$CPLUS_INCLUDE_PATH
export C_INCLUDE_PATH=/www/server/mysql/include:$C_INCLUDE_PATH
// 重启即生效