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命令     打印当前项目中的绝对路径以及 所有源文件的绝对路径。

 #此项目源文件后缀类型
PROJECTTYPE = .c #您想要生成可执行文件的名字
BinName :=obj.out #获取当前makefile绝对路径
pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST))
pes_parent_dir:=$(shell dirname $(pes_parent_dir)) #首先跳转到makefile目录下,然后获取该目录下所有子目录
AllDirs := $(shell cd $(pes_parent_dir); ls -R | grep '^\./.*:$$' | awk '{gsub(":","");print}') . #添加成为绝对路径
AllDirs := $(foreach n,$(AllDirs),$(subst .,$(pes_parent_dir),$(n))) #获取所有 .c/.cpp文件路径
Sources := $(foreach n,$(AllDirs) , $(wildcard $(n)/*$(PROJECTTYPE))) #处理得到*.o 后缀文件名
OBJS = $(patsubst %$(PROJECTTYPE),%.o, $(Sources)) #同理得到 *.d文件名
Deps := $(patsubst %$(PROJECTTYPE),%.d, $(Sources)) #需要用到的第三方静态库
StaticLib := #需要用到的第三方动态链接库
DynamicLib := #真实二进制文件输出路径(绝对)
Bin :=$(pes_parent_dir)/$(BinName) #C语言编译器
CC = gcc #C++编译器
CXX = g++ #简化rm -f
RM = -rm -f #C语言配置参数
CFLAGS = -g -pedantic -std=c99 -Wall -o #C++配置参数
CXXFLAGS = -g -Wall -std=c11 #头文件搜索路径
INCLUDE_PATH = $(foreach n,$(AllDirs) , -I$(n)) LDFLAGS = #指定AllLibs为终极目标 即:最新的Bin
AllLibs:$(Bin) #声明这个标签 des 用于观察当前的路径是否正确
.PHONY:des
des:
@echo OBJS = $(OBJS)
@echo cur_makefile_path = $(pes_parent_dir)
@echo AllDirs = $(AllDirs)
@echo Sources = $(Sources)
@echo Deps = $(Deps) #对应关系 在本makefile中以空格隔开的后缀为.c 都会为其生成一个新的.d文件 意图为更新所有*.c文件的include依赖关系
%.d : %.c
@echo 'finding $< depending head file'
@$(CC) -MT"$(<:.c=.o) $@" -MM $(INCLUDE_PATH) $(CPPFLAGS) $< > $@ #对于include中的*.d文件,只要里面任意有一个文件被修改,那么就会触发此规则生成一个新的*.o文件
%.o: %.d
@echo compile $(<:d=c)
@$(CC) -c $(<:.d=.c) $(INCLUDE_PATH) $(CFLAGS) $@ sinclude $(Sources:.c=.d) $(Bin) : $(OBJS)
@echo bulding....
@$(CC) $(OBJS) $(CFLAGS) $(Bin)
@echo created file: $(BinName) .PHONY : clean
clean:
@echo '清理所有文件'
@$(RM) $(OBJS) $(Deps) $(Bin) .PHONY : cleanO
cleanO:
@echo '清理Obj && Dep'
@$(RM) $(OBJS) $(Deps)
# #########################################################################
# 单独的 < 符号代表 依存源文件(即冒号: 的左边) $< 代表将源文件展开成为字符
# 单独的 @ 符号代表 目标文件 (冒号 : 的右边) $@ 代表将目标文件名称展开成为字符
# 符号 @ 后接命令则表示:此语句执行,但并不现实
# 例如:@$(CC) $(OBJS) $(CFLAGS) $(Bin)
# 只执行链接命令,但是不将此字符串打印至终端
# 关键字:@echo 表示该行后的命令只显示 不执行。
# 注意:虽然只显示,但是他依旧会以执行命令的要求的解析文本,
# 只是不执行而已,如果需要输出字符串使用‘ ’将内容引用即可
# 重点符号 $ : 表示转义,在makefile中无论在哪里都会被识别为转义字符,
# 如果想表示 $符号,那么需要使用 $$
# 例如:@echo ‘$$$$’ 终端将会输入 : "$$"
# 其余makefile 知识参考 《跟我一起写 MakeFile》 ----陈皓
# #########################################################################

一个自动管理项目的Makefile(C语言)的更多相关文章

  1. 自动生成项目的Makefile文件

    自动生成项目的Makefile文件 理论基础 跟我一起写 Makefile:   http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4 ...

  2. 一个电商项目的Web服务化改造

    一个电商项目的Web服务化改造 项目,早期是随便瞎做的,没啥架构,连基本的设计也没. 有需求,实现需求,再反复修改. 大致就是这么做的. 最近,项目要重新架构,和某boss协商的结果是,采用阿里开源的 ...

  3. 一个项目的Makefile编写及调试

    父Makefile 在src目录下包含很多文件夹,那么需要遍历所有的目录执行Makefile,那么给一个在src目录下的Makefile. # 需要排除的目录 exclude_dirs := incl ...

  4. maven(四):一个基本maven项目的pom.xml配置

    继续之前创建的test项目,一个基本项目的pom.xml文件,通常至少有三个部分 第一部分,项目坐标,信息描述等 <modelVersion>4.0.0</modelVersion& ...

  5. 一个电商项目的Web服务化改造6:单元测试4步走,构造数据、执行操作、断言、回滚

      最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA.     有点挑战,做完了,会有很大进步. 单元测试,在很早之前的文章已经介绍过.     可以在这里看到相关的 ...

  6. 一个电商项目的Web服务化改造2:现有项目的5个问题

         最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA.      有点挑战,做完了,会有很大进步, 1.现有项目的问题   1.1代码风格不统一     不同的 ...

  7. webpack自动生成项目的html

    1 自动生成多个html页面 设置webpack.config.js中的plugins属性,多次调用plugin插件(new htmlWebpackPlugin()),同时设置对应数量的.js入口文件 ...

  8. 一个电商项目的Web服务化改造5:面向服务的分层架构设计(有图有真相)

    最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA.     有点挑战,做完了,会有很大进步. 本篇,以我亲自画的3个图,阐述一下架构设计.   一.分层架构-总体图 ...

  9. 一个电商项目的Web服务化改造4:方案和架构,通用接口的定义和实现

        最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA.     有点挑战,做完了,会有很大进步. 上一篇,我们明确了我们的"规范和约定". 从 ...

随机推荐

  1. 完美实现保存和加载easyui datagrid自定义调整列宽位置隐藏属性功能

    需求&场景 例表查询是业务系统中使用最多也是最基础功能,但也是调整最平凡,不同的用户对数据的要求也不一样,所以在系统正式使用后,做为开发恨不得坐在业务边上,根据他们的要求进行调整,需要调整最多 ...

  2. java架构之路-(JVM优化与原理)JVM类的加载机制

    话不多说,先上图. ***.class文件执行大概就是这样来走的.我们都知道我们的java文件经过编译以后会生成对应的class文件.先经过类装载子系统,然后塞进运行时内存模型的元空间,开始执行方法, ...

  3. SpringBoot 连接kafka ssl 报 CertificateException: No subject alternative names present 异常解决

    当使用较新版本SpringBoot时,对应的 kafka-client 版本也比较新,如果使用了 2.x 以上的 kafka-client ,并且配置了 kafka ssl 连接方式时,可能会报如下异 ...

  4. Grafana 6.4 正式发布!

    原文链接:Grafana 6.4 正式发布! 2019 年 10 月 2 日,也就是国内小伙伴们的放假期间,Grafana 实验室正式发布了 Grafana 6.4 版本.这个版本主要围绕数据模型和指 ...

  5. MyEclipse注册代码

    package test;    import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputSt ...

  6. 彻底修改eclipse中项目的名称

    需要四个步骤: 一.右键工程:Refactor->Rename,或选中工程按F2,修改名称 二.修改项目目录下:.project文件 三.项目右键属性 --> Web Project Se ...

  7. Fibonacci 数列和 Lucas 数列的性质、推论及其证明

    Fibonacci 数列 设f(x)=1,x∈{1,2}=f(x−1)+f(x−2),x∈[3,∞)\begin{aligned}f(x)&=1,\quad\quad\quad\quad\qu ...

  8. php后端开发要学什么

    PHP历史: 1994年创建,1995年对外发表第一个版本,名为:personal home page tools,之后发表PHP1.0.1995年中期,PHP2.0,从此建立了PHP在动态网站开发的 ...

  9. js转换页面为图片并下载

    <div style="background:red;width: 600px;height: 600px;" class="test"> < ...

  10. 玩转ArduinoJson库 V5版本

    1.前言     一直以来,博主的事例代码中都一直使用到JSON数据格式.而很多初学者一直对JSON格式有很大疑惑,所以博主特意分出一篇博文来重点讲解Arduino平台下的JSON库--Arduino ...