Makefile 过程

内容纲要

1. gcc / g++ 编译流程

gcc -lstdc++ main.cpp 直接从源代码到目标可执行文件

把过程拆分:
预处理 gcc -E main.cpp>main.ii
编译  gcc -S main.ii 得到名为 main.s 的汇编文件
汇编  gcc -c main.s 得到名为 main.o 而二进制文件
链接  gcc -lstdc++ main.o 得到名为 a.out 的可执行文件

2. 变量

系统变量

$\* 不包括扩展名的目标文件名称
$+  所有的依赖文件,以空格分隔
$<   表示规则中的第一个条件
$?  所有时间戳比目标文件晚的依赖文件,以空格分隔
$@  目标文件的完整名称
$^  所有不重复的依赖文件,以空格分隔
$%  如果目标是归档成员,则该变量表示目标的归档成员名称

系统常量(可用 make -p 查看)

AS  汇编程序的名称 默认为 as
CC  C 编译器名称 默认为 cc
CPP C 预编译器名称    默认为 cc -E
CXX C++ 编译器名称   默认 g++
RM  文件删除程序别名    默认为 rm -f

自定义变量

定义:变量名=变量值
使用:$(变量名)/${变量名}

3. 伪目标和模式匹配

伪目标 .PHONY:clean
声明目标为伪目标后,makefile 将不会判断目标是否存在或该目标是否需要更新。

%.o:%.cpp   .o 依赖于对应的 .cpp
wildcard    $(wildcard ./*.cpp) 获取当前目录下所有的 .cpp 文件
patsubst    $(patsubst %.cpp, %.o, ./*.cpp) 将对应的 cpp 文件名替换成 .o 文件名

4. 运行流程

file

5. 编译动态链接库

动态链接库:不会把代码编译到二进制文件中,而是在运行时才去加载,所以只需要维护一个地址。

-fPIC   产生位置无关的代码
-shared 共享
-l  指定动态库
-I  指定头文件目录,默认当前目录
-L  手动指定库文件搜索目录,默认只链接共享目录

好处是程序可以和库文件分离,分别发版,库文件可被多处共享。

动态 运行时才加载 动态加载
链接 库文件和二进制程序分离,用某种特殊手段维护两者之间的关系
.dll、.so

SoTest.cpp  libSoTest.so

g++ -shared -fPIC SoTest.cpp -o libSoTest.so
g++ -lSoTest -L./ test.cpp -o test

g++ -lSoTest -L./001 main.cpp -o main

1. 动态库编译完成后要发布

Linux 默认动态库路径配置文件:
/etc/ld.so.conf /etc/ld.so.conf.d/*.conf
/usr/lib /usr/local/lib

2. 运行时手动指定动态库目录

LD_LIBRARY_PATH=./001
export LD_LIBRARY_PATH

6. 编译静态链接库

静态链接库:会把库中的代码编译到二进制文件中,当程序编译完成后,该库文件可以删除。动态库必须与程序同时部署,还要保证程序能加载得到库文件。

留下评论

您的电子邮箱地址不会被公开。