网站图片切换,水果网页设计图片,基于wordpress 开发,广州专业网站制作一、背景
会不会写makefile#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数#xff0c;其按类型、功能、模块分别放在若干个目录中#xff0c;makefile定义了一系列的 规则来指定#xff0c;哪些文件需要先编译#xff0c;哪些文件…一、背景
会不会写makefile从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数其按类型、功能、模块分别放在若干个目录中makefile定义了一系列的 规则来指定哪些文件需要先编译哪些文件需要后编译哪些文件需要重新编译甚至于进行更复杂 的功能操作makefile带来的好处就是——“自动化编译”一旦写好只需要一个make命令整个工程完全自动编 译极大的提高了软件开发的效率。make是一个命令工具是一个解释makefile中指令的命令工具一般来说大多数的IDE都有这个命 令比如Delphi的makeVisual C的nmakeLinux下GNU的make。可见makefile都成为了一 种在工程方面的编译方法。make是一条命令makefile是一个文件两个搭配使用完成项目自动化构建
二、make/Makefile的初步认识
首先我们要知道make是一条命令makefile是一个文件两个搭配使用完成项目自动化构建
1、举例
我们先创建一个源文件源文件中写上我们需要编译运行的代码 再创建一个makefile文件可以写成makefile或者Makefile都可以创建后打开 我们在makefile文件中写一些程序具体作用后文会慢慢解释
我们将一个可执行程序命名为mytest生成源文件code.c的可执行程序名为mytest
clean部分 我在后面再做解释现在你知道他是一个清理功能命令为make clean 删除可执行程序mytest 我们直接使用make命令创建可执行程序mytest并执行。
我们发现make命令后生成了可执行程序mytest再使用命令make clean后将可执行程序mytest删除 这个举例就是对make/makefile的简单认识了解它的作用接下来我们深入讲解。
2、认清原理
一、依赖关系
我们先把在例子中对makefile文件中的代码给大家做一下解释
mytest与code.c的依赖关系就是源文件通过依赖方法生成可执行程序mytest。
make命令会根据makefile的内容完成编译/清理工作 clean和他的依赖方法是一种特殊情况因为它不需要依赖文件列表rm表示清理
二、PHONY的了解
首先我们要弄清楚为什么我们使用make命令就会直接生成可执行文件mytest而想清理的时候就必须在make命令后加上clean呢
因为make命令的执行推导规则是从上到下依次扫描默认形成第一个目标文件。
那么第三行的.PHONY是什么呢?
当我们make生成可执行程序时将同一个程序生成两次可以吗? 它会提醒我们目前存在的可执行程序是最新的不可以再生成会自动给你拦截
除非我们对源文件进行修改或者删除才可以继续make
那我们不想让他拦截想一直生成的话怎么办呢这就是.PHONY的作用
我们用.PHONY来修饰mytest表示mytest要总是被执行 再重新make多次这里make了三次也没有被拦截 具体使用方法如下
.PHONY:xxx
xxx对应的方法要总是被执行 我们之所以不在生成可执行程序这里使用是因为没有这个必要在大项目里编译时间会很长重复编译会浪费时间不重复生成也提高了编译效率在clean部分用是因为我们可能会用到多次清理。
这里有两个问题需要理解
1、为什么makefile对最新的可执行程序。默认不想重新生成呢?
我们之所以不在生成可执行程序这里使用是因为没有这个必要在大项目里编译时间会很长重复编译会浪费时间不重复生成也提高了编译效率在clean部分用是因为我们可能会用到多次清理。
2、makefile是怎么做到的呢
通过对时间的比较只要源文件的修改时间比可执行程序文件的修改时间早的话就不会继续生成而源文件的修改时间比可执行程序文件的修改时间晚的话就可以再生成。
我们可以使用命令stat查看文件的修改时间
stat 文件名 通过Modify的时间比较就可以确定是否要重新编译
我们也可以使用touch命令更新文件Modify的时间touch命令本来是创建新文件但是在这里用来更新Modify时间。
3、依赖关系的深入理解 在我们makefile文件中我们是直接从code.c生成可执行程序mytest但是我们在上文讲过程序的编译过程整个流程应该是code.c→code.i→code.s→code.o→mytest,那我们在makefile文件中应该怎么写呢 我们已经知道make的工作推导规则是从上到下生成第一个目标文件所以mytest还是应该在第一行mytest的依赖文件列表是code.o那么依赖方法就是gcc code.o -o code.exe。 剩下的以此类推得 他们之间的依赖关系就是 mytest依赖code.o、code.o依赖code.s、code.s依赖code.i、code.i依赖code.c. 这里大家可能会有疑问我想生成目标文件mytest时我并没有code.o文件啊 我用一张图给大家作答 make/makefile会根据文件中的依赖关系进行自动推导帮助我们执行所有相关得依赖方法 这个其实就是我们所知道得递归算法。
三、make/makefile的符号替换和变量
1、符号替换 $代表的是依赖文件列表$代表的是目标文件make之后会自动替换 2、变量
我们在c语言中定义变量是需要变量类型、初始化的。比如int a0
我们在Liunx中的makefile中不是我们直接
变量xxx
再与符号替换结合 之后我们修改目标文件或者依赖文件列表直接修改变量就可以了会方便很多。
四、总结
1、make工作原理
1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。2. 如果找到它会找文件中的第一个目标文件target3. 如果mytest所依赖的code.o文件不存在那么make会在当前文件中找目标为code.o文件的依赖性如果找到则再根据那一个规则生成code.o文件。这有点像一个堆栈的过程4. 这就是整个make的依赖性make会一层又一层地去找文件的依赖关系直到最终编译出第一个目标文件。5. 在找寻的过程中如果出现错误比如最后被依赖的文件找不到那么make就会直接退出并报错 而对于所定义的命令的错误或是编译不成功make根本不理。6. make只管文件的依赖性即如果在我找了依赖关系之后冒号后面的文件还是不在那么对不起 我就不工作啦。
2、项目清理
工程是需要被清理的像clean这种没有被第一个目标文件直接或间接关联那么它后面所定义的命令将不会被自动执行 不过我们可以显示要make执行。即命令——“make clean”以此来清除所有的目标文件以便重新编译。但是一般我们这种clean的目标文件我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是总是被执行的。