✨个人主页: 熬夜学编程的小林
💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】
目录
1、背景
总结:
2、编写makefile
第一步,先创建两个文件,一个用于编写源代码(test.c),一个用于自动编译源代码(makefile/Makefile)。
[jkl@VMCentos7 lesson4]$ touch test.c makefile # 创建两个文件
[jkl@VMCentos7 lesson4]$ ls
makefile test.c
第二步,编写makefile文件。
test.exe:test.c
gcc test.c -o test.exe
.PHONY:clean
clean:
rm -f test.exe
注意:
第三步,编写test.c文件。
#include<stdio.h>
int main()
{
printf("hello linux\n");
return 0;
}
第四步,通过命令看效果。
[jkl@VMCentos7 lesson4]$ make
gcc test.c -o test.exe
[jkl@VMCentos7 lesson4]$ ls
makefile test.c test.exe
[jkl@VMCentos7 lesson4]$ ./test.exe
hello linux
2、make原理
在Linux中,输入make命令后,make会在当前目录下找文件名为 "makefile或者Makefile"的文件,1. 如果找到,则会把文件中的第一个目标文件作为最终的目标文件。
[jkl@VMCentos7 lesson4]$ ls # 查看当前目录的文件,有一个makefile一个Makefile文件
makefile Makefile test.c
[jkl@VMCentos7 lesson4]$ make # 把第一个文件作为目标文件
gcc test.c -o test.exe # 执行makefile
[jkl@VMCentos7 lesson4]$ cat makefile
test.exe:test.c
gcc test.c -o test.exe
.PHONY:clean
clean:
rm -f test.exe
[jkl@VMCentos7 lesson4]$ cat Makefile
mytest:test.c
gcc -o mytest test.c
2. 如果没有找到,则打印提示信息。
[jkl@VMCentos7 ~]$ make
make: *** No targets specified and no makefile found. Stop. # 没有找到目标文件
3、理解makefile
首先我们需要知道makefile文件中代码所代表的意思,通过下图进行一一解释:
注意:上面我们说了输入make指令出现两种可能,此处只讲解找到最终文件的情况。
当我们在命令行中输入make命令,会默认生成第一个目标文件,即执行第一个依赖方法。
[jkl@VMCentos7 lesson4]$ make # 默认执行第一个依赖方法,并打印出来
gcc test.c -o test.exe
[jkl@VMCentos7 lesson4]$ ls # 查看当前目录文件,确实生成了可执行程序(目标文件)test.exe
makefile Makefile test.c test.exe
当我们再次输入make命令,会出现以下提示:
[jkl@VMCentos7 lesson4]$ make
make: 'test.exe' is up to date. # 可执行程序(目标文件)是最新生成的了
1. 为什么再次输入make命令会不让我们继续生成目标文件呢???
2. 编译器怎么知道哪个文件是没有改变的源代码???
3. 想要输入make命令则生成目标文件该怎么办???
举例:想要make总是执行,可以将makefile改成如下内容:
.PHONY:test.exe
test.exe:test.c
gcc test.c -o test.exe
此时输入make则会生成可执行程序。
4. 我们像VS编译一个程序可以生成解决方案,还可以清理解决方案,我们makefile如何清理解决方案呢???
test.exe:test.c
gcc test.c -o test.exe
.PHONY:clean # 总是执行该依赖关系中的方法
clean: # 删除可执行程序
rm -f test.exe
5. 从上面我们可以看到,删除可执行程序是第二个依赖方法,我们前面知道make默认执行第一个依赖方法,那我们想要执行第二个依赖方法应该怎么办呢??
[jkl@VMCentos7 lesson4]$ ls
makefile Makefile test.c test.exe
[jkl@VMCentos7 lesson4]$ make clean # 删除可执行程序
rm -f test.exe
[jkl@VMCentos7 lesson4]$ ls # 确实删除了
makefile Makefile test.c
6. 虽然知道了如何执行其他时候的依赖方法,但是此时又有一个问题,如果我执行依赖方法之后不想看到执行的是什么,怎么解决呢???
[jkl@VMCentos7 lesson4]$ cat makefile # 查看文件内容
.PHONY:test.exe
test.exe:test.c
@gcc test.c -o test.exe # 依赖方法中有@
.PHONY:clean
clean:
rm -f test.exe # 依赖方法中没有@
[jkl@VMCentos7 lesson4]$ make # 不显示执行的是什么
[jkl@VMCentos7 lesson4]$ ls
makefile Makefile test.c test.exe # 生成了可执行程序
[jkl@VMCentos7 lesson4]$ make clean # 显示执行的是什么
rm -f test.exe
[jkl@VMCentos7 lesson4]$ ls # 删除了可执行程序
makefile Makefile test.c
4、优化makefile
前面我们理解了makefile中内容的意义,但是在依赖关系和依赖方法之间的文件名基本是重复的,有没有一种方法让它更简便一些呢???
下面我们则对上面写的makefile文件进行优化:
1.如下为单个依赖关系的举例:
test.exe:test.c
gcc -o $@ $< # 自动化变量需要在最后面 $@代表test.exe $<表示test.c
.PHONY:clean
clean:
rm -f test.exe
2.如下为多个依赖关系的举例:
test.exe:test.c test.h
gcc -o $@ $^ # 自动化变量需要在最后面 $@代表test.exe $^表示test.c 和 test.h
.PHONY:clean
clean:
rm -f test.exe
注意:依赖关系以空格间隔!!!
除了makefile中的自动化变量以外,其实我们还可以自己创建变量。
[jkl@VMCentos7 lesson5]$ cat makefile
bin=test.exe # 创建目标文件变量
src=test.c # 创建被编译文件变量
$(bin):$(src) # 使用需要加$符号
gcc -o $@ $^
.PHONY:clean
clean:
rm -f $(bin)
注意:创建变量跟C语言相似,但是不用加类型。
总结
本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!