makefile、cmake和shell之间的联系
- makefile:帮组我们管理编译项目
- CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。它能够输出各种各样的Makefile或者project文件, CMake并不直接建构出最终的软件,而是产生标准的建构档(如Makefile或projects )。
- shell脚本:一系列命令和语法
makefile自动编译和链接
gcc编译四步骤
-
1.预处理阶段
宏定义展开,宏定义替换,展开include的文件
gcc -E -o xx.i xx.c -
2.预编译阶段
GCC才会去检查你代码的规范性,语法是否有错误,gcc会把代码翻译成汇编 -
3.汇编阶段(比较耗时)
gcc -c -o xx.cpp xx.o
把.s文件翻译成二进制.o文件(机器的指令),文本打开的是乱码 -
4.链接阶段
计算逻辑地址,合并数据段,有些函数是在另一个so库文件中的
gcc xx.cpp yy.cpp -o xx: 这步骤帮我们省了编译四步骤。但是当我们修改了一个文件,需要重新编译,那么每次都会重新生成.o文件,因此需要对多个cpp用上面的步骤拆分
手写Makefile
一个规则
- 目标:依赖条件(一个tab缩进)命令
新建一个文件a.c文件
#include<stdio.h>
int main(){
printf("Hello world\n");
return 0;
}
新建Makefile:
#一个规则
#两个函数
#三个自动变量
a.out:a.c
gcc a.c -o a.out
执行make命令和./a.out命令
image.png
两个思想:
1、若想生成目标文件,会检查规则中依赖是否存在,若不存在,则寻找是否有完整的规则来生成该依赖条件
2、会检查规则中的目标是否需要更新,必须先检查它所有依赖项,依赖中任何一个被改,则目标必须被更新(原理就是检查更新时间)
#一个规则
#两个函数
#三个自动变量
# 默认情况下只会执行第一个
hello.out:hello.o sub.o add.o div.o
gcc hello.o sub.o add.o div.o -o hello.out
div.o:div.cpp
gcc -c div.cpp -o div.o
add.o:add.cpp
gcc -c add.cpp -o add.o
sub.o:sub.cpp
gcc -c sub.cpp -o sub.o
hello.o:hello.cpp
gcc -c hello.cpp -o hello.o
两个函数
-
src=$(wildcard* c)
找到当前目录下所有后缀名.c的文件并赋值给src -
就是把所有src变量里所有后缀为.cpp文件替换成.o文件
obj=$(patsubst %cpp,%o,$(src));
代码
#一个规则
#两个函数
#三个自动变量
src=$(wildcard *.cpp)
obj=$(patsubst %cpp,%o,$(src))
# 默认情况下只会执行第一个
hello.out:$(obj)
gcc $(obj) -o hello.out
div.o:div.cpp
gcc -c div.cpp -o div.o
add.o:add.cpp
gcc -c add.cpp -o add.o
sub.o:sub.cpp
gcc -c sub.cpp -o sub.o
hello.o:hello.cpp
gcc -c hello.cpp -o hello.o
clean:
rm -rf $(obj) hello.out
三个自动变量
$@:表示规则中的目标
$^:表示规则中所有的依赖条件,组成一个列表,以空格隔开
$<:表示规格中第一个依赖条件,如果运行在模式套用中,相当于依次取出依赖条件套用该模式规则
修改上面代码
#一个规则
#两个函数
#三个自动变量
src=$(wildcard *.cpp)
obj=$(patsubst %cpp,%o,$(src))
# 默认情况下只会执行第一个
hello.out:$(obj)
gcc $^ -o $@
div.o:div.cpp
gcc -c $< -o $@
add.o:add.cpp
gcc -c $< -o $@
sub.o:sub.cpp
gcc -c $< -o $@
hello.o:hello.cpp
gcc -c $< -o $@
clean:
rm -rf $(obj) hello.out
#生成伪目标
.PHONY: clean
我们可以发现这里都是xx.o:xx.cpp,所以我们可以用 模式匹配
#一个规则
#两个函数
#三个自动变量
src=$(wildcard *.cpp)
obj=$(patsubst %cpp,%o,$(src))
# 默认情况下只会执行第一个
# 注释
hello.out:$(obj)
gcc $^ -o $@
# 模式规则
%o:%cpp
gcc -c $< -o $@
clean:
rm -rf $(obj) hello.out
#生成伪目标
.PHONY: clean
网友评论