什么是Makefile
向我这种Linux初学者,一开始是不知道什么是Makefile的,我们经常会遇到一种情况,就是当自己下载源码,自己编码安装程序时,总是最后执行make指令,程序都装好了,为什么我们make一下,就可以了? 其实这背后主要就是Makefile的功劳。
用Makefile来管理程序,它是描述整个工程程序编译、链接的规则的文件。尤其是对于大型的工程,如果我们用gcc自己一条条编译链接的话,会很麻烦,使用Makefile就大大提高我们的开发效率。
基本的Makefile文件的组成
Makefile的两大基本组成部分是 规则 和 变量
先看两个例子
main :main.o module1.o module2.o #这之后代表注释
gcc main.o module1.o module2.o -o main
main.o : main.c head1.h head2.h
gcc -c main.c
module1.o :module1.c head1.h
gcc -c module1.c
module2.o :module2.c head2.h
gcc -c module1.c
#This is a makefile
all:led.bin
led.bin: led.o
arm-linux-ld -Tled.lds -o led.elf led.o
arm-linux-objcopy -O binary led.elf led.bin
%.o : %.S
arm-linux-gcc -g -o $@ $< -c
.PHONY: clean
clean:
rm *.o led.elf led.bin led.dis
规则
规则 是Makefile的基本单元,一个Makefile由若干规则组成
每一个规则只有一个目标,可以有多个依赖和多条命令
最终目标:第一条规则的目标,(make时 可以make target-name )
直接make 就是要达到最终目标
伪目标:没有依赖的目标(phony targets),比如上面中的clean
变量
多次出现的东西,可以用一个变量来代替,所以变量就是为了简化规则的编写
使用变量要注意:
赋值 变量名=要替代的内容 【‘=’左右不要加空格】
使用 $(变量名)常用的系统默认变量
$@ 目标
$^ 第一个依赖
$< 代表这个规则中所有的依赖
使用技巧
通用规则
在一个工程中有多个类似的规则,可以用一条代替多条
//例如 使用通用规则之前
func1.o : func1.s
arm-linux-gcc -g -o $@ -c $^
func2.o : func2.s
arm-linux-gcc -g -o $@ -c $^
func3.o : func3.s
arm-linux-gcc -g -o $@ -c $^
//使用通用规则之后
%.o : %.s
arm-linux-gcc -g -o $@ -c $^
去回显
命令前加@
自定义Makefile文件名字
默认情况下make命令只能找 名字的Makefile 或者 makefile的文件
通过选项-f 可以自定义
make -f your-Makefile-name
分析第一个例子的Makefile执行过程
make //执行make
make 首先寻找当前目录下的Makefile文件,找到之后,
在当前目录下寻找第一个规则中的目标文件main,发现没有,去寻找main的依赖文件,发现也没有,然后就跳过第二个规则。
定位到第3行,寻找目标文件main.o,发现没有,于是寻找依赖文件main.c head1.h head2.h,都被找到,于是执行第4行的gcc 命令。 此时还没有找全第一个规则的依赖,接着下一个规则
定位到第5行,没有module1.o ,但是有module1.c head1.h,执行第6行 ,还没有找全第一个规则的依赖,接着下一个规则
定位到第7行,没有module2.o ,但是有module2.c head2.h,执行第8行 ,第一个规则的依赖已经全了,可以执行第一个规则了,回溯到第一个规则,生成目标文件main
定位到第9行,发现是注释,不予理睬,