makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要重新编译,如何进行链接等操作。
makefile就是自动化编译,告诉make命令如何编译和链接
makefile 包含以下五个:
target ... : prerequisites ...
command
或者
target ... : prerequisites ... ;command
注意 一个是冒号,一个是分号
在同一行 可以使用分号进行分割,如果不在同一行 使用tab连接 如果命令太长可以使用反斜杠换行
参数 | 含义 |
---|---|
target | 目标文件。可以使Object File 也可以是执行文件,还可以是标签(Lable) |
prerequisites | 依赖文件,即要生成那个target所需要的文件或其他target |
command | make需要执行的命令 |
当前文件存在main.c tool.c tool.c三个文件
下面吗是makefile文件内容
main :main.o tool.o
gcc main.o tool.o -o main
.PHONY:clean
clean :
-rm main *.o
执行 make 后输出如下
cc -c -o main.o main.c
cc -c -o tool.o tool.c
gcc main.o tool.o -o main
生成一个可执行文件main
-o :指定可执行文件名称
clean :标签,不会生成clean文件,这样大的target称为伪目标,伪目标的名字不能和文件名重复。clean一般放在文件最后
.PHONY : 显示地指明clean是一个伪目标
默认方式下,输入make命令后:
为了makefile容易维护,在makefile中我们可以使用变量。makefile的变两个就是一个字符串,理解为C语言中定义的宏可能会更好。
比如我们声明一个变量交objects,于是我们可以很方便地在我们的makefile中通过$(objects)
方式来使用这个变量了。
objects = main.o tool.o
main: $(objects)
gcc $(objects) -o main
.PHONY:clean
clean:
rm main $(objects)
执行make后输入如下
cc -c -o main.o main.c
cc -c -o tool.o tool.c
gcc main.o tool.o -o main
使用include关键字可以吧其他Makefile包含进来,include语法格式
include
举个例子,假设有几个Makefile
a.mk b,mk c.mk
还拥有一个文件叫做 # foo.make
,以及一个变量$(bar)
包含了e.mk
和f.mk
include foo.make *.mk $(bar)
等价于
include foo.make a.mk b.mk c.mk e.mk f.mk
如果文件找不到,而你希望make时不理会哪些无法读取的文件而继续执行
可以在include前加一个减号 - 例如
-include
如果当前环境中定义了环境变量MAKEFILES
,那么,make会把这个变量中的值做一个类似于include的动作。这个变量中的值是其他的Makefile。用空格分隔。只是他和include不同的是,从这个环境变量中引入的Makefile的目标不会起作用,如果环境变量中定义的文件发现错误,make也会不理。但是建议不要使用这个环境变量,因为只要这个变量一被定义,那么当你使用make时,所有的Makefile都会受到他的影响。也是有时候Makefile出现奇怪的事,那么可以查看当前环境中的没有定义这个变量。
变量名 | 描述 | 默认值 |
---|---|---|
CC | C语言编译器的名称 | cc |
CPP | C语言预处理器名称 | $(CC) -E |
CXX | C++语言编译器的名称 | g++ |
RM | 删除文件程序的名称 | rm -f |
GFLAGS | c语言编译器的处理选项 | 无 |
CPPFLAGS | c语言预处理器的编译选项 | 无 |
CXXFLAGS | C++语言编译器的编译选项 | 无 |
自动变量 | 描述 |
---|---|
$* | 目标文件的名称,不包含拓展名 |
$@ | 目标文件的名称,包含拓展名 |
$+ | 所有的依赖文件,以空格隔开,可能含有重复的文件 |
$^ | 所有的依赖文件,以空格隔开,不重复 |
$< | 依赖项中第一个依赖文件的名称 |
$? | 依赖项中所有比目标文件新的依赖文件 |
define FUNC
$(info echo "hello")
endef
$(call FUNC)
------------------------
输出 :hello
define FUNC1
$(info echo $(1) $(2))
endef
$(call FUNC1,hello,world)
------------------------
输出 :hello world
有三个文件
main.c tool.c tool.h
gcc -c tool.c
gcc -c main.c
gcc -o main main.o tool.o
./main
max=8
vim makefile
main:main.o tool.o
gcc main.o tool.o -o main
.PHONY: clean
clean:
-rm main *.o
输出
cc -c -o main.o main.c
cc -c -o tool.o tool.c
gcc main.o tool.o -o main
objects = main.o tool.o
main: $(objects)
gcc $(objects) -o main
.PHONY: clean
clean:
-rm main $(objects)
define func // 定义方法
$(info "hello")
endef
$(call func)
define func1
$(info $(1) $(2))
endef
$(call func1,hello,world)
objects = main.o tool.o
main: $(objects)
gcc $(objects) -o main
.PHONY: clean
clean:
-rm main $(objects)
输出
$ make
"hello"
hello world
make: “main”已是最新。
GNU的makefile工作时的执行步骤如下