这一篇继续Makefile入门。上一篇讲了Makefile的核心描述块,以及宏的使用。Makefile为了方便构建项目提供了许多预定义的特殊宏。通过对他们的操作会让build过程更简单。
预定义的特殊宏有四类,通过这些特殊的宏,让makefile拥有了和外部交互的能力。
当在依赖中出现文件名时文件名宏将被makefile生成。
$@ | 当前的target的全名 |
$$@ | 当前target,只能放在依赖中 |
$* | 去掉后缀名 |
$** | 显示所有的依赖 |
$? | 将显示所有时间戳晚于target的依赖项 |
$< | 显示一个当前目标时间戳晚的依赖。只有在推断中有效.(推断 inference rule之后会提到) |
$@和@可以方便的根据target的名称动态选择依赖项,不同之处在于
- # makefile 内容
- file.exe: o$$@ test.obj
- echo $@
- echo $*
- echo $**
- echo $?
-
- ofile.exe:
- echo test
-
- test.obj:
- echo do nothing
-
- # 输出
- test
- do nothing
- file.exe
- file
- ofile.exe test.obj
- ofile.exe test.obj
以上所列出来的关于文件名的宏也能搭配一些后缀修饰符出现,可以组合出不同的效果
D | 驱动器加上目录 |
B | 没有后缀的文件名 |
F | 文件名加上后缀 |
R | 驱动其加上文件名,不加后缀 |
为了便于理解可以看下面的例子
- # makefile 内容
- C:\file.exe:
- echo $@
- echo $(@D)
- echo $(@B)
- echo $(@F)
- echo $(@R)
-
- # 输出
- C:\file.exe
- C:\
- file
- file.exe
- C:\file
这里的递归是指在makefile里面又去调用make命令来执行另一个makefile。和include不一样,该命令相当于重新启动了一个make。和创建子进程一样,他会继承当前的环境变量,同时也有命令行宏,也有定义在tools.ini里面定义的宏。
这里简单介绍一下tools.ini,该文件将会在make执行makefile之前先去执行tools.ini里面设置的定义的宏和配置。利用该文件就可以修改一次tools.ini文件,然后是的每次执行makefile都能拥有一样用户定义的配置了。
MAKE | 这个宏就是make命令的全路径。在命令块中使用$(make) 就等于调用了一个make |
MAKEDIR | 当前makefile所在的目录 |
MAKEFLAGS | 显示当前生效的选项。 |
编译相关命令是最重要的命令,因为makefile主要就是编译项目。而通过重定义这些宏可以增加编译选项或者是编译器。下面是nmake里面所使用的宏:
Macro Assembler | AS | ml or ml64 | AFLAGS |
C Compiler | CC | cl | CFLAGS |
C++ Compiler | CPP | cl | CPPFLAGS |
C++ Compiler | CXX | cl | CXXFLAGS |
Resource Compiler | RC | rc | RFLAGS |
被预定义的环境变量最好理解,也就是当前make程序中所有的环境变量的内容都可以作为预定义宏来使用。需要注意的是,这些宏都是可以被修改的。而且让make进程的环境变量随着改变。但是如果使用SET命令来修改进程的环境变量,则环境变量的宏不会随着改变。下面用JAVA_HOME来举例
- # makefile内容
- all:
- echo $(JAVA_HOME)
-
- # 输出
- C:\jdk-11