第五章 嵌入式Linux应用开发基础(3)

5.10 Makefile 的使用

    Gcc是可以编译文件,成千上万个文件都要编译的时候就头疼了,所以衍生出makefile。另外,参照Visual Studio中只去编译修改了的文件而不是所有文件都去修改,提高编译速度,节省时间,makefile要做就是学习VS的这种自动识别修改的文件并编译它。免责申明,应该不会侵权的吧。

objs := main.o sub.o

test : $(objs)
	gcc -o test $^

# 需要判断是否存在依赖文件
# .main.o.d .sub.o.d
dep_files := $(foreach f, $(objs), .$(f).d)
dep_files := $(wildcard $(dep_files))

# 把依赖文件包含进来
ifneq ($(dep_files),)
  include $(dep_files)
endif

%.o : %.c
	gcc -Wp,-MD,.$@.d  -c -o $@  $<
	
clean:
	rm *.o test -f

distclean:
	rm  $(dep_files) *.o test -f

     理清楚是怎么一步一步演变过来的,用到的函数都是什么意思作用是什么???

    make命令根据文件更新的时间戳来决定哪些文件需要重新编译,这使得可以避免编译已经编译过的、没有变化的程序,可以大大提高编译效率。

通用的格式是:

目标(target)…: 依赖(prerequiries)…   

    <tab>命令(command)   

    如果“依赖文件”比“目标文件”更加新,那么执行“命令”来重新生成“目标文件”。命令被执行的2个条件:依赖文件比目标文件新,或是目标文件还没生成

5.10.1makefile改进分析

演示main.c、sub.c和sub.h,

第1版Makefile:

test : main.c sub.c sub.h
    gcc -o test main.c sub.c

    这版Makefile有什么缺点呢?在执行make命令时,会把所有的依赖文件(.c和.h)都编译一遍,而不是像VS那样只编译修改的文件,怎么完善呢?

第2版Makefile:

test : main.o sub.o
    gcc -o test main.o sub.o
main.o : main.c
    gcc -c -o main.o main.c # -c是只编译不链接
sub.o : sub.c
    gcc -c -o sub.o sub.c
clean: 
    rm *.o test -f          #强制删除所有.o文件,test文件

改进:用.o文件替换.c文件作依赖文件,比如修改了sub.c,只会去编译生成sub.o,而main.c不会去编译,提高效率。

不足:如果有很多的.c文件,需要些很多的.o文件,能不能使用什么符号替代所有的.c文件和对应生成的.o文件。

第3版Makefile:

test : main.o sub.o
    gcc -o test main.o sub.o
%.o : %.c                 #使用%代替所有的文件
    gcc -c -o $@ $<       # $@代表所有的目标文件,$^代表所有的依赖文件,$< 第一个依赖文件
clean: 
    rm *.o test -f  

改进:用%代替对应的文件,用$@代替所有的目标文件,用$^代替所有的依赖文件,$<表示第一个依赖文件,这样就不用把所有的.c文件都写出来了。

不足:好像是没有体现依赖.h,如果修改.h中的内容,make会漏掉.h中的内容,参照前面的内容看可以把.h加到依赖文件中啊,%.o : %.c %.h,说是不好加,不知道为什么。

第4版Makefile:

test : main.o sub.o
    gcc -o test main.o sub.o
%.o : %.c                
    gcc -c -o $@ $<       
sub.o : sub.h              #只有目标和依赖,没有命令
clean: 
    rm *.o test -f   

改进:添加sub.o和sub.h的依赖关系,并不做什么命令,只是将sub.h也加到sub.o的依赖文件中。

不足:如果.h文件很多,岂不是也得一个一个手动添加,也是很麻烦的。

第5版Makefile:

test : main.o sub.o
    gcc -o test main.o sub.o
%.o : %.c                
    gcc -Wp,-MD,.$@.d -c -o $@ $<       
clean: 
    rm *.o test -f 

改进:添加-Wp,-MD,.$@.d,意思是.c文件生成依赖文件.main.o.d和.sub.o.d,打开.main.o.d如图x,看到其实就是一条封装的make指令,目标文件为sub.o,依赖文件是sub.c和各种.h(sub.h)头文件,它会自动把用到的.h头文件包含进来,这样就不用一个一个去手动添加头文件的包含了。

不足:需要判断是否存在这些依赖文件,。

第6版Makefile:

objs := main.o sub.o

test : $(objs )
    gcc -o test $^

#生成依赖文件.main.o.d  .sub.o.d
dep_files := $(foreach f, $(objs), .$(f).d)

#判断是否已经生成依赖文件
dep_files := $(wildcard $(dep_files))

#把依赖文件包含进来
ifneq($(dep_files),)
include $(dep_files)
endif

%.o : %.c                
    gcc -Wp,-MD,.$@.d -c -o $@ $<       

clean: 
    rm *.o test -f          
disclean:
    rm $(dep_files) *o test -f

改进:在原有的基础上有有所改进,用到2个函数,先说下2个函数。

A.$(foreach var,list,text),把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。

B.$(wildcard PATTERN…)在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard”,它的用法是:$(wildcard PATTERN…) 。

不足:不支持子目录文件。

5.10.2通用Makefile的使用

    韦老师参考Linux内核的Makefile编写了一个通用的Makefile,它可以用来编译应用程序:

① 支持多个目录、多层目录、多个文件;
② 支持给所有文件设置编译选项;
③ 支持给某个目录设置编译选项;
④ 支持给某个文件单独设置编译选项;
⑤ 简单、好用。

自己总结了一个执行顺序图:

图5.16 Makefile执行示意图

 

图5.17 Makefile实际执行过程

     makefile的具体内容和解释可以看韦老师的视频和分析文档。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值