设计一个通用的makefile

只说一下思路。

 

先说说make吧。make这个工具只用来编译软件太可惜了,它最强大的地方其实是在模式推导,我觉得用它来编译软件只有一个理由,就是你希望做增量编译,而实际上仔细一想,它的增量编译只能做到比较文件修改时间上,这太粗糙了,想一下你有一个头文件,被100个.cpp包含,你只改其实一个类的实现,而只有一个实现的.cpp文件用到了它,那其它99个也会被增量编译出来,它没办法做到‘发现’更小的修改单元。而对于‘增量编译’的需求,往往是程序员自己写程序的过程中,实际软件发布构建的时候都是rebuild,所以make真是一把巨大的牛刀杀了只小鸡。反过来想,如果make不能做到增量编译,那干嘛要用make,bash脚本能做的事更多。

 

make执行的过程大致为,先执行一遍make中的脚本,把所有变量的值求出来,它的求值很诡异,它是反复求的,你不能写出这样的var = $(var)cc,类似这种。然后依次执行make 给出的参数中的目标,如果不给目标,就执行第一个目标,然后停止。执行目标的时候就可能引发推导:

 

目标1 目标2 。。。: 依赖1 依赖2 。。。

    模式动作

 

如果当前在make目标1,那它通过这条规则需要依赖后面那些目标,如果后面那些是文件,就会比较和目标的最后修改时间,如果依赖更新,就执行动作,如果目标1不存在,或者是伪目标,也会执行动作,如果依赖本身不存在,或者是伪目标,就会递归的make它,直到需要的目标全部make出来。它的执行可能会失败,因为没有规则可供make出依赖的目标。

 

软件构建的过程,通常一个软件源码会放在某个目录下,你可以分很多目录,这里放模块1,那里放模块2等等。首先需要告诉make,我们有哪些source要编译,很简单比如:

 

source = a.c b.c main.c

 

有了source,后面的过程就很机械化,编译到.o,连接到目标程序,目标库等

通过make的脚本函数,求出object = a.o b.o main.o,写出规则:

$(product) : $(object)

  连接

 

%.o : %.c

  编译

 

后面这个是模式规则,它说形如这样的目标,可以被形如那样的目标这样make,%是通配符。

 

大概过程是这样,还有一些,比如用什么编译,编译参数是什么,用什么连接,连接器参数是什么,我们可以用另外一个配置文件来控制,另外那个文件也是一个makefile,只不过是一部分,用来配置的部分,像这样:

 

CC = gcc

CFLAGS = xxx

 

product = hello

等等

 

这部分可以做成成套的配置,比如用一个脚本变量表示你需要在哪种环境下构建,env=linux env=macos等,用type表示你要构建执行程序 静态库还是动态库等,它们会影响到后面的规则中的动作,这样只要在make命令中加参数 #make env=linux type=exe中控制就好了。

 

更复杂的事情:自动依赖,和自动搜索源

.d文件是GNUC推荐的依赖描述文件,它表示对应的.o文件依赖于哪些文件,通常会是一个源文件和一些头文件,我们不需要自己去写,使用gcc -M参数就能求出来,于是一个通用的规则就出来了:

 

%.d : %.c

  gcc -M $< > $@

 

这些.d文件这样make出来后,怎样包含进来呢?include $(depend)。include会被执行2次,第一次失败,因为确实没有$(depend),报错,但是make不会马上失败,它会尝试make $(depend),然后再include,如果成功继续执行,第一次include会报错,所以改成-include,安静的包含。

 

自动搜索的意思就是,我不需要指定source,我只指定一个目录或多个目录,我就是要编译这些目录下的源文件,这个功能很淫荡,你不用每次向项目中添加一个.cpp文件就要改工程配置,我们的makefile会察觉出你的新增文件,在下次构建时自动编译进来。

 

先写一个bash脚本,名叫findsource,递归的把当前目录下的源文件,以及目录的目录下的所有源文件找出来,这不难办到,这个脚本直接输出到标准输出流,格式是:

source = ...

 

在makefile里先写:

-include __auto_source__

 

再写一条规则:

__auto_source__ :

  findsource > $@

 

make里还能写clean install,这些就不多说了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
韦东山通用makefile文件是一个用于管理和组织代码的文件,在软件开发过程中起着非常重要的作用。它包含了编译和链接代码的规则,可以帮助开发者自动化构建整个项目。通用makefile文件的设计使得开发者无需重复编写复杂的构建脚本,只需在makefile文件中定义编译器选项、源文件列表和编译规则,就可以轻松地构建整个项目。 韦东山通用makefile文件能够大大简化代码的管理和维护工作,使得团队成员可以更加高效地协作开发。通过makefile文件,开发者可以一键编译整个项目,生成可执行文件或者库文件,同时还能够方便地清理和重建代码。这种自动化的构建过程不仅能够提高开发效率,还能够减少人为错误,保证代码的质量和稳定性。 除此之外,韦东山通用makefile文件还可以方便地进行项目的扩展和维护。开发者可以通过简单地修改makefile文件来增加新的源文件或者目标文件,而无需修改大量的构建脚本。这种灵活的设计使得项目的管理变得更加轻松和高效。 总的来说,韦东山通用makefile文件是一个非常有用的工具,它能够帮助开发者简化项目的构建过程,提高开发效率,减少错误,同时还能够方便地进行项目的扩展和维护。因此,makefile文件在软件开发中扮演着非常重要的角色,是每个开发者都应该掌握和使用的技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值