欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

跟我一起写makefile入门笔记

程序员文章站 2024-03-21 23:15:10
...

Table of Contents

 

一、makefile是如何工作的(依赖关系)

二、文件搜寻 VPATH

三、makefile函数的使用:

1、$(patsubst%.c,%.o,x.c.c bar.c) 把.c字符串换成.o的字符串

2、files:=$(foreach n,$(names),$(n).o) 把name文件名中含有.o 名字文件提取出来给files

         awk刷选文件及文件夹



 

一、makefile是如何工作的(依赖关系)

在默认的方式下,也就是我们只输入make命令。那么,

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

这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就
不工作啦。

通过上述分析,我们知道,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——make clean,以此来清除所有的目标文件,以便重编译。

于是在我们编程中,如果这个工程已被编译过了,当我们修改了其中一个源文件,比如file.c,那么根据我们的依赖性,我们的目标file.o会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o的文件也是最新的啦,于是file.o的文件修改时间要比edit要新,所以edit也会被重新链接了(详见edit目标文件后定义的命令)。而如果我们改变了command.h,那么,kdb.o、command.o和files.o都会被重编译,并且,edit会被重链接。

重点总结:

当已经编译完后的工程,如果修改了某个文件后,再次make, 自会重新编译修改过的文件,而不会修改其它文件,原因是:目标文件是否更新要看依赖文件,如果依赖文件更新了,目标文件也要更新

 

二、文件搜寻 VPATH

在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。

Makefile文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。

    VPATH = src:../headers

上面的的定义指定两个目录,“src”和“../headers”,make会按照这个顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)

另一个设置文件搜索路径的方法是使用make的“vpath”关键字(注意,它是全小写的),这不是变量,这是一个make的关键字,这和上面提到的那个VPATH变量很类似,但是它更为灵活。它可以指定不同的文件在不同的搜索目录中。这是一个很灵活的功能。它的使用方法有三种:

 为符合模式<pattern>的文件指定搜索目录<directories>。

    1、vpath <pattern> <directories>

     清除符合模式<pattern>的文件的搜索目录。

    2、vpath <pattern>

      清除所有已被设置好了的文件搜索目录。

    3、vpath

 

vapth使用方法中的<pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符,例如,“%.h”表示所有以“.h”结尾的文件。<pattern>指定了要搜索的文件集,而<directories>则指定了<pattern>的文件集的搜索的目录。例如:

    vpath %.h ../headers

该语句表示,要求make在“../headers”目录下搜索所有以“.h”结尾的文件。(如果某文件在当前目录没有找到的话)

我们可以连续地使用vpath语句,以指定不同搜索策略。如果连续的vpath语句中出现了相同的<pattern>,或是被重复了的<pattern>,那么,make会按照vpath语句的先后顺序来执行搜索。如:

    vpath %.c foo
    vpath %   blish
    vpath %.c bar

其表示“.c”结尾的文件,先在“foo”目录,然后是“blish”,最后是“bar”目录。

    vpath %.c foo:bar
    vpath %   blish

而上面的语句则表示“.c”结尾的文件,先在“foo”目录,然后是“bar”目录,最后才是“blish”目录。
 

 

三、makefile函数的使用:

函数调用,很像变量的使用,也是以$来标识的,其法如下

$(<function><arguments>)

或是:

${<function><arguments>}

函数调用以$开头  <arguments>为函数的参数,

1、$(patsubst%.c,%.o,x.c.c bar.c) 把.c字符串换成.o的字符串

 

$(patsubst<pattern>,<replacement>,<text>)

跟我一起写makefile入门笔记

 

2、files:=$(foreach n,$(names),$(n).o) 把name文件名中含有.o 名字文件提取出来给files

 

$(foreach<var>,<list>,<text>) 

跟我一起写makefile入门笔记

awk刷选文件及文件夹

参考https://blog.csdn.net/shenlong1356/article/details/91554209

 

取出DEBUG目录

DEBUG=$(shell ls -l | grep ^d | awk '{if($9 == "debug") print $9}')

 

待更新