文章目录
makefile基本规则
makefile 语法
target... : prerequisites ...
command
- target:目标文件,可以是object file,也可以是可执行文件,还可以是一个标签。
- prerequisites:要生成那个target所需要的文件或是目标。
- command:make需要执行的命令,在Makefile中的命令,必须要以[Tab]键开始。
make工作原理
- make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
- 如果找到,它会找文件中的第一个目标文件(target),并把这个文件作为最终的目标文件。
- 如果target不存在,或是target所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成target这个文件。
- 如果target所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
- 当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件声明make的终极任务,也就是执行文件target了。
g++常用参数
编译选项
-g
生成调试信息,该程序可以被调试器调试
-pipe
管道,它可以用来同时连接两个程序,其中一个程序的输出将直接作为另一个程序的输入,这样就可以避免使用临时文件,提高编译速度,但编译时消耗更多的内存。
-fPIC
- PIC: position independent code。
- 生成位置无关的代码(一般用于动态库.so)。
- 共享对象可能会被不同的进程加载到不同的位置上,如果共享对象中的指令使用了绝对地址,外部模块地址,那么在共享对象被加载时就必须根据相关模块的加载位置对这个地址做调整,也就是修改这些地址,让它在对应进程中能正确访问。
-w
关闭编译时的警告,也就是编译后不显示任何warning
-D 宏定义
路径相关
-I(大写的i)
- -I参数是用来指定头文件所在目录。
- /usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/include里我们就要用-I参数指定了。
-L(大写的l)
- -L参数跟着的是库文件所在的目录。
-l(小写的L)
- -l参数就是用来指定程序要链接的库,-l参数紧接着就是库名。
编译过程
g++ -E 预编译
预编译,将.c文件转化为.i文件
g++ -S 转换为汇编文件
编译,将.c/.h文件转化为.s文件(汇编语言文件)
g++ -c 转换为.o文件(只编译,不链接)
汇编,将.s 文件转化成 .o文件(二进制机器文件),-c代表只编译不链接
g++ -o 链接(将目标文件链接起来)
-o 后面接上目标文件( 可执行程序 或者库文件)
创建库文件
ar命令创建静态库.a
ar crv libapi.a api.o #生成静态库 libapi.a
g++ main.cpp -lapi -o output #生成output可执行文件,链接静态库
g++创建动态库.so
g++ -shared -fPIC -o libapi.so api.o #生成libapi.so 动态库
g++ main.cpp -lapi -o output #生成output可执行文件,链接动态库
常用语法
反斜杠(\)
反斜杠(\)是换行符的意思。这样比较便于Makefile的易读。例:
clean:
rm edit main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
$@ $< $^
$@:目标项
$<:第一个依赖项
$^:全部依赖项
匹配符*
匹配符%的流程是:
1.我要找test1.o的构造规则,看看Makefile中那个规则符合。
2.然后找到了%.o:%.c,
3.来套一下来套一下:
4.%.o 和我要找的 test1.o 匹配
5.套上了,得到%=test1。
6.所以在后面的%.c就表示test1.c了。
7.OK进行构造
变量
声明变量
VPATH = src include
访问变量
$(VPATH)
常用函数
$(wildcard 寻找的文件)
$(wildcard *.c)
- 等于找到系统中所有后缀为.c的文件,返回成以空格隔开的一整行字符
返回值如test1.c test2.c test3.c 这样
$(basename 文件名)
- 取得文件的名字(去掉后缀的意思)
- $(basename test1.c) 就会取得test1
$(addsuffix 后缀,列表)
- $(addsuffix .o, test1 test2 test3) 返回值即test1.o test2.o test3.o