实现自动化编译程序。
make——一条命令
Makefile——一个文件——在当前的源代码路径下
在当前源文件目录下touch创建一个Makefile文件,首字母可大写可小写。
vim Makefile在其中写入(myfile.c代表要编译的源文件)
myfile:myfile.c
gcc -o myfile myfile.c//tab键开头,语法规则
//这样一个简单的makefile就完成了
make
命令,可以执行在myfile中内置好的gcc命令,会生成myfile可执行文件。myfile:myfile.c
gcc -o myfile myfile.c//tab键开头,语法规则
.PHONY:clean
clean:
rm -f myfile//tab键开头,语法规则
//clean就完成了
make clean
即可删除myfile文件。//Makefile
myfile:myfile.c
gcc -o myfile myfile.c
.PHONY:clean
clean:
rm -f myfile
makefile是一个围绕依赖关系与依赖方法构建的自动化编译工具。
目标文件:依赖文件列表
,说明生成myfile文件是依赖myfile.c文件生成的——可以有多个依赖文件,用空格分隔;并且依赖文件列表也可以为空。tab键开头
+要执行的程序
,写入在依赖关系下要执行的程序。对依赖关系的拆解说明:
myfile:myfile.o //myfile 依赖于myfile.o
gcc -o myfile myfile.o
myfile.o:myfile.s//myfile.o依赖于myfile.s
gcc -c -o myfile.o myfile.s
myfile.s:myfule.i//myfile.s依赖于myfile.i
gcc -S -o myfile.s myfile.i
myfile.i:myfile.c//myfile.i依赖于myfile.c
gcc -E -o myfile.i myfile.c
make执行这个Makefile时,显示从-E开始从下往上执行,但是本身是从上往下运行的。
过程解析:
利用myfile.o生成myfile —— 没有myfile.o —— 向下走 —— 利用myfile.s生成myfile.o —— 没有myfile.s ——向下走 —— 利用myfile.i生成myfile.s —— 没有myfile.i —— 向下走 —— 利用myfile.c生成myfile.i —— 有myfile.c —— 执行-E —— 生成myfile.i —— … —— 执行-o —— 生成myfile。
所以命令行显示从下往上执行。
清理部分:
clean://依赖文件列表可以为空,依旧可以执行clean
rm -f myfile.i myfile.s myfile.o myfile
合并即可生成一个完整的Makefile:
myfile:myfile.o //myfile 依赖于myfile.o
gcc -o myfile myfile.o
myfile.o:myfile.s//myfile.o依赖于myfile.s
gcc -c -o myfile.o myfile.s
myfile.s:myfule.i//myfile.s依赖于myfile.i
gcc -S -o myfile.s myfile.i
myfile.i:myfile.c//myfile.i依赖于myfile.c
gcc -E -o myfile.i myfile.c
clean://依赖文件列表可以为空,依旧可以执行clean
rm -f myfile.i myfile.s myfile.o myfile
注:
make命令执行的时候是从上到下扫描的,如果把clean写在最前面,则make执行的就是clean清理了,相生成目标文件只能make myfile了。
一般直接写myfile:myfile.c,不用分开,这里只是为了讲解拆分开。
myfile:myfile.c
gcc -o myfile myfile.c//tab键开头,语法规则
.PHONY:clean
clean:
rm -f myfile//tab键开头,语法规则
.PHONY——总是被执行——修饰的目标称为伪目标
解析:
总是被执行的意思就是可以连续使用,没有用.PHONY修饰的目标,比如myfile,在make生成一次可执行文件后,马上再make一次的话就无法执行了,因为源文件没有修改,会生成一样的文件没有必要,如果用.PHONY修饰myfile,就可以重复连续执行了。
一般.PHONY修饰clean,不用来修饰目标文件。
make判断是否连续执行的条件是对比文件的修改时间,可以用stat [目标文件]
来查看文件的时间。
有没有一种方法可以在不修改源文件的情况下更新文件的时间从而让make可以再次执行呢?——touch [源文件]。
touch有两个作用:
如此就可以连续再次make了。
在写makefile时,可以按下图所示方式简写
其中:
- $@ —— 表示上一行 “ : ” 左侧的目标文件(图中的myproc)
- $^ —— 表示上一行 “ : ” 右侧的所有文件的依赖列表(图中的myproc.c)
如果有多个依赖文件,就可以不用全部写出,直接用$^来简写。
.PHONY:all
all:myfile mytest
myfile:myfile.cc
g++ -o $@ $^ -std=c++11
mytest:mytest.cc
g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
rm -f myfile mytest
不加前两行,使用make只会生成一个可执行文件myfile。
前两句的意思是:要生成的目标文件是all,all依赖myfile和mytest,但是没有,自动生成myfile和mytest,但是没有all的依赖方法,所以后续不会生成all可执行文件。
- stat : 显示文件的状态信息,输出的信息比ls的输出信息更详细。