目录
一、make/Makefile
1.1 相关知识
在Linux项目中,make和Makefile是常用的自动化构建工具和构建脚本语言,用于管理项目的编译、链接和打包等过程。
☀️make:make是一个命令行工具,用于根据Makefile文件中的规则和依赖关系来自动构建项目。通过执行make命令,可以根据项目的源代码文件和Makefile文件来进行自动化构建,编译生成可执行文件或库文件等。
☀️Makefile:Makefile是一种文本文件,其中包含了项目的编译规则、依赖关系和构建命令等信息。Makefile通常包括了一系列的规则,每个规则定义了如何将源文件编译成目标文件,以及如何将目标文件链接成最终的可执行文件或库文件。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中, makefile 定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。makefile 带来的好处就是 ——“ 自动化编译 ” ,一旦写好,只需要一个 make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。make 是一个命令工具,是一个解释 makefile 中指令的命令工具,一般来说,大多数的 IDE 都有这个命令,比如:Delphi 的 make , Visual C++ 的 nmake , Linux 下 GNU 的 make 。可见, makefile 都成为了一种在工程方面的编译方法。make 是一条命令, makefile 是一个文件,两个搭配使用,完成项目自动化构建。
1.2 代码示例
先创建一个code.c文件,再用vim编辑
再创建一个Makefile文件,内部编写如下图所示
这时候编译code.c时,只需要使用make命令
可以看到已经生成了可执行文件mybin,然后执行
二、依赖关系和依赖方法
在Makefile中,依赖关系指的是目标文件(target)依赖于哪些源文件(prerequisites)以及其他目标文件。依赖关系定义了在构建目标文件时所需的输入文件,以及构建目标文件的规则。
在Makefile中,可以使用依赖关系来指定目标文件所依赖的源文件、头文件以及其他目标文件,以确保在构建过程中正确地处理文件之间的依赖关系。
依赖关系
上面的文件mybin , 它依赖 code.ocode.o , 它依赖 code.scode.s , 它依赖 code.icode.i , 它依赖 code.c
这样只是为了理解过程,但是实际上还是建议写成
mybin:code.c
gcc -o mybin code.c
这样使用起来才最为方便。
依赖方法
gcc hello.* - option hello.* , 就是与之对应的依赖关系
makefile支持定义变量,
这样也是可以使用的,注意要用$()来引用
目标文件可以用$@代替,源文件可以用$^代替。
三、make工作原理
make 是如何工作的 , 在默认的方式下,也就是我们只输入 make 命令。那么,1. make 会在当前目录下找名字叫 “Makefile” 或 “makefile” 的文件。2. 如果找到,它会找文件中的第一个目标文件( target ),在上面的例子中,他会找到 “hello” 这个文件,并把这个文件作为最终的目标文件。3. 如果 hello 文件不存在,或是 hello 所依赖的后面的 hello.o 文件的文件修改时间要比 hello 这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成 hello 这个文件。4. 如果 hello 所依赖的 hello.o 文件不存在,那么 make 会在当前文件中找目标为 hello.o 文件的依赖性,如果找到则再根据那一个规则生成hello.o 文件。(这有点像一个堆栈的过程)5. 当然,你的 C 文件和 H 文件是存在的啦,于是 make 会生成 hello.o 文件,然后再用 hello.o 文件声明make的终极任务,也就是执行文件 hello 了。6. 这就是整个 make 的依赖性, make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么 make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make 根本不理。8. make 只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起, 我就不工作啦。
make只会编译最新的mybin
那么如何知道mybin是最新的呢?
是通过对比时间出来的,只要可执行程序比所有源文件最近修改时间新,那么它就是最新的。
用vim改变内容,属性时间也发生改变
Access是对文件的访问时间 为避免Access时间一直更新,采用特定策略不会每次访问都更新时间
make判断最新文件时间是根据Modify时间的。(touch原文件也可以更新这个时间,而内容不发生变化)
☀️读取Makefile文件:
make
命令会首先读取当前目录下的名为Makefile
或makefile
的文件,以获取项目构建的规则和信息。☀️解析Makefile文件:
make
会解析Makefile
文件中的规则,包括目标文件、依赖关系、命令等信息。它会根据这些规则来确定哪些文件需要被构建,以及构建它们的方式。☀️确定构建顺序:根据
Makefile
文件中的依赖关系,make
会确定需要构建的目标文件以及构建它们的顺序。它会检查目标文件和依赖文件的时间戳来确定哪些文件需要被重新构建。☀️执行构建命令:一旦确定了需要构建的目标文件,
make
会执行Makefile
中定义的构建命令。这些命令可以是编译源文件、链接目标文件、复制文件等操作。☀️更新目标文件:在执行构建命令后,
make
会根据命令的执行结果来更新目标文件。如果构建成功,目标文件的时间戳会被更新;如果构建失败,make
会输出错误信息。通过这个流程,
make
能够自动地根据Makefile
文件中定义的规则来构建项目,确保源文件的正确编译、链接和部署。这使得项目的构建过程更加高效和可靠。
四、项目清理
在Linux中,make工具通常提供了一些目标来清理项目,以便删除生成的目标文件、可执行文件和其他中间文件。这有助于确保项目处于干净的状态,以便重新构建或分发。
工程是需要被清理的像clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make 执行。即命令 ——“make clean”,以此来清除所有的目标文件,以便重编译。makefile和Makefile形成目标文件时,默认是从上到下扫描makefile文件的,默认形成的是第一个文件。但是一般我们这种 clean 的目标文件,我们将它设置为伪目标 , 用 .PHONY 修饰 , 伪目标的特性是,总是被执行的。一般建议把clean修饰成伪目标,符合编译器规则。