• 忘掉天地
  • 仿佛也想不起自己
  • 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2020-03-23 19:32 Aet 隐藏边栏 |   抢沙发  2 
文章评分 1 次,平均分 5.0

make

make是一个命令工具,是一个解释makefile中指令的命令工具。
make工程管理器是个“自动编译管理器”。
“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件文件的内容来执行大量的编译工作 。

编译&&链接

  • Windows下
    • 编译,把源文件编成.obj
    • 链接,链接库文件.lib
  • Linux下
    • 编译,把源文件编成.o
    • 链接,链接库文件.a

makefile

  • make命令执行时,需要一个makefile文件,以告诉make命令需要怎么样的去编译和链接程序。
  • makefile规则

target:目标文件,可以是Object file,也可以是执行文件。还可以是一个标签(伪目标)。
prerequisites:要生成那个target所需要的文件或目标。
command:make需要执行的命令。

这是一个文件的依赖关系。
target这一个或多个目标文件依赖于prerequisites中的文件,其生成规则定在command中。

换句话说

prerequisites里面的文件如果有一个以上的文件比target文件新,command所定义的命令就会被执行。

  • 变量
    • $@
      • 目标文件
    • $^
      • 所有的依赖文件
    • $<
      • 第一个依赖文件

make是如何工作的

  • make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  • 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
  • 如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
  • 如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。
  • 当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件声明make的终极任务,也就是执行文件edit了。

示例makefile

我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。
我们的规则是:

  1. 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
  2. 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
  3. 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

  • \ 是换行符
  • make clean 删除执行文件和所以的中间目标文件

在makefile中使用变量

如果makefile文件内容十分庞大,在不使用变量的情况下,添加了一个源文件,那么很可能需要在makefile文件内的好多地方添加这个源文件,就有可能漏掉,而且不便于维护

让make自动推导

gnu的make功能很强大。
它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。

  • .PHONY表示clean是个伪目标文件

另类风格

makefile内容

  • 显式规则。
    • 显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
  • 隐晦规则。
    • 由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
  • 变量的定义。
    • 在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
  • 文件指示。
    • 其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
  • 注释。
    • Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。

makefile文件名

默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解释这个文件。在这三个文件名中,最好使用“Makefile”这个文件名,因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好不要用“GNUmakefile”,这个文件是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,但是基本上来说,大多数的make都支持“makefile”和“Makefile”这两种默认文件名。

引用其他makefile文件

  • 在Makefile使用include关键字可以把别的Makefile包含进来

通配符

  • ~
  • *

文件搜索

  • vpath < pattern> < directories>
    • 为符合模式< pattern>的文件指定搜索目录
  • vpath < pattern>
    • 清除符合模式< pattern>的文件的搜索目录。
  • vpath
    • 清除所有已被设置好了的文件搜索目录

伪目标

“伪目标”并不是一个文件,只是一个标签,由于“伪目标”不是文件,所以make无法生成它的依赖关系和决定它是否要执行。我们只有通过显示地指明这个“目标”才能让其生效。当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。

为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。

命令回显

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2021-11-20
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享