1、系统常量
- make -p可以看到所有的系统常量,这是Makefile内置的系统变量
- 这些变量在我们编写makefile是可以通过上述的系统常量进行替换,例如下面的举例
# 默认,汇编程序的名称,默认为as
AS = as
# 默认,C编译器名称
CC = cc
# 默认,C预编译器名称
CPP = $(CC) -E
# 默认,C++编译器名称
CXX = g++
# 默认,文件删除程序别名
RM = rm -f
main:main.cpp
g++ main.cpp -o main
${CXX} main.cpp -o main
clean:
${RM}
rm -f main
2、自定义变量
- 虽然makefile内置了一些系统变量,但makefile也支持自定义变量
- 例如定义一个myargs表示我们自定义的变量,改变了的值是-Wall和-g
- -Wall:表示make编译过程中输出所有的警告信息(Warning all)
- -g:表示加入gdb调试信息
- 这样写的好处是当在多出需要这个两个操作时直接引入这个变量即可
- 使用:
${变量名} / $(变量名)
# 定义一个自定义变量
myargs = -Wall -g
main:main.cpp
${CXX} main.cpp -o main ${myargs}
hello:hello.cpp
${CXX} hello.cpp -o hello ${myargs}
3、系统变量
系统变量是最灵活的一个东西,可以灵活使用它缩减makefile编写的脚本量,
首先引入两个概念:
- 什么是规则:规则就是makefile中gcc、g++、c++编译满足的条件
- 什么是命令:命令就是gcc、g++、c++编译指令
主要系统变量:
$@
:规则命令中的目标$<
:规则命令中的第一个条件$^
:规则命令中的所有依赖条件$*
:不包括扩展名的目标文件名称$+
:所有的依赖文件,以空格分隔$?
:所有时间戳比目标文件完的依赖文件,以空格分隔$%
:如果目标是归档成员,则该变量表示目标的归档成员名称
3.1、$@
的使用
hello.o:hello.c
gcc -c hello.c -o hello.o
#规则:这两行代码
#依赖:hello.o是hello.c的依赖
#命令:gcc -c hello.c -o hello.o
#目标:就是hello.o,因此可以换成$@
#但是只能换命令中的目标不能换依赖中的目标
#因此可以将上面的命令转化为如下
hello.o:hello.c
gcc -c hello.c -o $@
3.2、$^
的使用
hello:hello.o sub.o add.o mul.o
gcc hello.o sub.o add.o mul.o -o hello
# 所有条件:hello.o sub.o add.o mul.o
# 因此可以将上面的命令转化为如下
gcc $^ -o hello
gcc $^ -o $@
3.3、$<
:规则命令中的第一个条件
hello.o:hello.c
gcc -c hello.c -o hello.o
#第一个条件:hello.c
#因此可以将上面的命令转化为如下
gcc -c $< -o hello.o
gcc -c $< -o $@
4、Demo实战
准备add.h/add.cpp、sub.h/sub.cpp、mul.h/mul.cpp、main.cpp这几个文件,然后再main.cpp中引入前三个头文件不难写出如下的makefile迷你版文件
main: main.o sub.o add.o mul.o
g++ add.o sub.o mul.o main.o -o main
add.o:add.cpp
g++ -c add.cpp -o add.o
sub.o:sub.cpp
g++ -c sub.cpp -o sub.o
mul.o:mul.cpp
g++ -c mul.cpp -o mul.o
main.o:main.cpp
g++ -c main.cpp -o main.o
clean:
rm -r *.o main
4.1、优化(一)
首先引入自定义变量优化和结果替换
obj = main.o sub.o add.o mul.o
target = main
${target}: ${obj}
g++ ${obj} -o ${target}
add.o:add.cpp
g++ -c add.cpp -o add.o
sub.o:sub.cpp
g++ -c sub.cpp -o sub.o
mul.o:mul.cpp
g++ -c mul.cpp -o mul.o
main.o:main.cpp
g++ -c main.cpp -o main.o
clean:
rm -r ${obj} ${target}
4.2、优化(二)
使用系统变量进行等价替换
$^
:表示所有依赖条件,可以等价替换掉所有的${obj}$<
:表示第一个条件依赖,可以等价替换掉xxx.cpp,当所有依赖只有一个时使用$^
和$<
效果是一样的
obj = main.o sub.o add.o mul.o
target = main
${target}: ${obj}
# g++ ${obj} -o ${target}
g++ $^ -o $@
add.o:add.cpp
g++ -c $< -o $@
sub.o:sub.cpp
g++ -c $^ -o $@
mul.o:mul.cpp
g++ -c $< -o $@
main.o:main.cpp
g++ -c $^ -o $@
clean:
rm -r ${obj} ${target}
4.3、优化(三)
引入系统常量,可以达到跨平台的效果,不把g++、C++写死,根据不同的平台来自行决定
obj = main.o sub.o add.o mul.o
target = main
${target}: ${obj}
${CXX} $^ -o $@
add.o:add.cpp
${CXX} -c $< -o $@
sub.o:sub.cpp
${CXX} -c $^ -o $@
mul.o:mul.cpp
${CXX} -c $< -o $@
main.o:main.cpp
${CXX} -c $^ -o $@
clean:
${RM} -r ${obj} ${target}