文档章节

一个自动管理项目的Makefile(C语言)

o
 osc_isezqdgg
发布于 2019/09/18 11:32
字数 1355
阅读 9
收藏 0

精选30+云产品,助力企业轻松上云!>>>

Linux 是所有嵌入式软件工程师绕不过去的坎,

makefile 是在Linux系统中绕不过去的坎。

花了几天时间初步学习和了解了makefile 的作用以及功能,并且制作了一个通用型的makefile 用于管理后续可能的在Linux上独立开发的项目。

在此用笔记的方式记下。怕自己以后忘了。

 

makefile 思想: makefile 核心公式     

<target_file> : <source_file>

  command....

如果目标文件不存在或者 源文件中有 比目标文件修改日期还要新的,那么执行command 命令 ;

command命令的功能使用来更新生成目标文件

同时上一个 公式中的 源文件 又可以嵌套成为下一个公式的 目标文件。周而复始。

上述公式中,如果目标文件和源文件都是最新的,那么command命令就不会被执行。这样在很多大型项目中,会被更新的就只有修改了的文件和最终的输出文件大幅的降低的编译的时间

 

同时makefile中支持丰富的逻辑、变换等。深入研究完全可以作为一门新的编程语言进行开发。

以下分享自己借助网络大牛的力量优化编写的一个makefile文件。

此makefile放置在项目的根目录下。

  例如:Pro文件夹中有 Inc、Res、Img文件夹;

        里面有 头文件、源码文件、图片文件、项目文件等;

        所有关于Pro项目的文件都在Pro文件下,makefile文件应该被放置在Pro文件夹中

注意事项:获取绝对路径功能只适用于 GUN编译器

功能:  会将Pro文件中所有的*.c *.h 文件视为一个项目,整体编译、链接;

     递归扫描各文件夹

     只编译未编译的文件或者更新后与其相关的文件

     clean命令   删除所有makefile会生成的文件

       cleanO命令(大写字母 O) 删除除可执行文件外,makefile生成的文件。

     des命令     打印当前项目中的绝对路径以及 所有源文件的绝对路径。

 

 

  1 #此项目源文件后缀类型
  2 PROJECTTYPE = .c
  3 
  4 #您想要生成可执行文件的名字
  5 BinName :=obj.out
  6 
  7 
  8 #获取当前makefile绝对路径
  9 pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST))
 10 pes_parent_dir:=$(shell dirname $(pes_parent_dir))
 11 
 12 #首先跳转到makefile目录下,然后获取该目录下所有子目录
 13 AllDirs := $(shell cd $(pes_parent_dir); ls -R | grep '^\./.*:$$' | awk '{gsub(":","");print}') .
 14 
 15 #添加成为绝对路径
 16 AllDirs := $(foreach n,$(AllDirs),$(subst .,$(pes_parent_dir),$(n)))
 17 
 18 #获取所有 .c/.cpp文件路径
 19 Sources := $(foreach n,$(AllDirs) , $(wildcard $(n)/*$(PROJECTTYPE)))
 20 
 21 #处理得到*.o 后缀文件名
 22 OBJS = $(patsubst %$(PROJECTTYPE),%.o, $(Sources))
 23 
 24 #同理得到 *.d文件名
 25 Deps := $(patsubst %$(PROJECTTYPE),%.d, $(Sources))
 26 
 27 #需要用到的第三方静态库
 28 StaticLib :=
 29 
 30 #需要用到的第三方动态链接库
 31 DynamicLib :=
 32 
 33 #真实二进制文件输出路径(绝对)
 34 Bin :=$(pes_parent_dir)/$(BinName)
 35 
 36 #C语言编译器
 37 CC = gcc
 38 
 39 #C++编译器
 40 CXX = g++
 41 
 42 #简化rm -f
 43 RM = -rm -f
 44 
 45 #C语言配置参数
 46 CFLAGS = -g  -pedantic -std=c99 -Wall -o
 47 
 48 #C++配置参数
 49 CXXFLAGS = -g -Wall -std=c11
 50 
 51 #头文件搜索路径
 52 INCLUDE_PATH = $(foreach n,$(AllDirs) , -I$(n))
 53 
 54 
 55 LDFLAGS =
 56 
 57 #指定AllLibs为终极目标 即:最新的Bin
 58 AllLibs:$(Bin)
 59 
 60 #声明这个标签 des 用于观察当前的路径是否正确
 61 .PHONY:des
 62 des:
 63         @echo OBJS =  $(OBJS)
 64         @echo cur_makefile_path = $(pes_parent_dir)
 65         @echo AllDirs = $(AllDirs)
 66         @echo Sources = $(Sources)
 67         @echo Deps = $(Deps)
 68 
 69 #对应关系 在本makefile中以空格隔开的后缀为.c 都会为其生成一个新的.d文件 意图为更新所有*.c文件的include依赖关系
 70 %.d : %.c
 71            @echo 'finding $< depending head file'
 72            @$(CC) -MT"$(<:.c=.o) $@" -MM $(INCLUDE_PATH) $(CPPFLAGS) $< > $@
 73 
 74 #对于include中的*.d文件,只要里面任意有一个文件被修改,那么就会触发此规则生成一个新的*.o文件
 75 %.o: %.d
 76         @echo compile $(<:d=c)
 77         @$(CC) -c $(<:.d=.c) $(INCLUDE_PATH) $(CFLAGS) $@
 78 
 79 sinclude $(Sources:.c=.d)
 80 
 81 $(Bin) : $(OBJS)
 82         @echo bulding....
 83         @$(CC) $(OBJS)  $(CFLAGS) $(Bin)
 84         @echo created file: $(BinName)
 85 
 86 .PHONY : clean
 87 clean:
 88             @echo '清理所有文件'
 89             @$(RM) $(OBJS) $(Deps) $(Bin)
 90 
 91 .PHONY : cleanO
 92 cleanO:
 93             @echo '清理Obj && Dep'
 94             @$(RM) $(OBJS) $(Deps)
 95 #    #########################################################################
 96 #    单独的 < 符号代表 依存源文件(即冒号: 的左边) $< 代表将源文件展开成为字符
 97 #   单独的 @ 符号代表 目标文件   (冒号 : 的右边)  $@ 代表将目标文件名称展开成为字符
 98 #    符号 @ 后接命令则表示:此语句执行,但并不现实 
 99 #        例如:@$(CC) $(OBJS)  $(CFLAGS) $(Bin)   
100 #        只执行链接命令,但是不将此字符串打印至终端
101 #   关键字:@echo  表示该行后的命令只显示 不执行。 
102 #        注意:虽然只显示,但是他依旧会以执行命令的要求的解析文本,
103 #             只是不执行而已,如果需要输出字符串使用‘  ’将内容引用即可
104 #   重点符号 $ : 表示转义,在makefile中无论在哪里都会被识别为转义字符,
105 #                如果想表示 $符号,那么需要使用 $$ 
106 #        例如:@echo ‘$$$$’  终端将会输入 : "$$" 
107 #    其余makefile 知识参考  《跟我一起写 MakeFile》 ----陈皓  
108 #    #########################################################################
109
View Code

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
C项目构建管理辅助工具--buildc

buildc是一个C语言项目构建管理辅助工具(需python版本[2.4.3, 3.0.0))。 buildc目前主要实现了三个功能: 第三方依赖库的远程获取和本地管理 根据目标主机环境、目标主机本地缓存的第三方库情...

wfifi
2012/07/31
881
0
第一篇 make与makefile介绍

  我们在Linux系统中学习C语言或者C++语言时,大多数时候只是用gcc命令或者g++命令在命令行进行简单的编译、链接即可得到最终的可执行文件,进一步即可验证所写C/C++语言的正确性。但是,在...

osc_a6bn407a
2018/02/02
4
0
Linux中基于g++的makefile文件的总结与注意的地方

#makefile的作用就是定义一系列的依赖规则,在执行make命令的时候,依据这个规则执行就可以了! makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放...

osc_3z3urvvj
2019/07/16
2
0
uboot基础之shell和makefile

shell篇 一、shell介绍 1、shell是操作系统的终端命令行,shell可以理解为软件系统提供给用户操的命令行界面,可以说它是人机交互的 一种方式。 2、我们可以使用系统本身带的shell和操作系统...

雨于鱼
06/25
0
0
Make

一、make的功能: make是一个用来维护程序模块关系和生产可执行文件的工具,他可以根据程序修改的情况重新编译链接生成的中间代码或最终的可执行文件。执行make命令需要一个Makefile文件,来...

宅蓝三木
2014/04/24
48
0

没有更多内容

加载失败,请刷新页面

加载更多

使用命名管道承载gRPC

最近GRPC很火,感觉整RPC不用GRPC都快跟不上时髦了。 gRPC设计 gRPC是一种与语言无关的高性能远程过程调用 (RPC) 框架。刚好需要使用一个的RPC应用系统,自然而然就盯上了它,但是它真能够解...

osc_nq69o22c
55分钟前
16
0
06-敏捷开发框架-apis 脚本库 引用位置无关性设计

动态引入技术的设计,对我们来说非常重要。 同时也说明动态语言的使用对我们来说也是非常重要。 没有动态语言的支撑,有些想法可能不容易实现,或者有替代方案,可能会花更大的代价。 前端开...

osc_5zg9z6t1
57分钟前
21
0
(三)学习了解OrchardCore笔记——灵魂中间件ModularTenantContainerMiddleware的第一行①的模块部分

  了解到了OrchardCore主要由两个中间件(ModularTenantContainerMiddleware和ModularTenantRouterMiddleware)构成,下面开始了解ModularTenantContainerMiddleware中间件第一行代码。   ...

osc_kdarxvx0
58分钟前
15
0
50Mn18Cr4V锻锻环件

电机无磁护环怎么锻性能才能《高高》?50Mn18Cr4V高锰无磁钢在变形温度为900~1 100℃、应变速率为0.1 ~10s-1条件下的热变形行为. 结果,VC第二相的应变诱导析出对50Mn18Cr4V的热变形行为产生...

无磁钢
59分钟前
16
0
【遇见offer】一汽-大众实习生专场来啦!成长+学习+福利,一个也不能少~

在上次一汽-大众的社招直播之后,实习生的专场招聘也终于来啦! 针对2020年暑期,我们提供了非常多的实习岗位给大家选择。 如果你想得到大厂实习的宝贵经验,如果你想得到更快速的成长,如果...

osc_b88oux8w
今天
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部