一个自动管理项目的Makefile(C语言)
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语言)的更多相关文章
- 自动生成项目的Makefile文件
自动生成项目的Makefile文件 理论基础 跟我一起写 Makefile: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4 ...
- 一个电商项目的Web服务化改造
一个电商项目的Web服务化改造 项目,早期是随便瞎做的,没啥架构,连基本的设计也没. 有需求,实现需求,再反复修改. 大致就是这么做的. 最近,项目要重新架构,和某boss协商的结果是,采用阿里开源的 ...
- 一个项目的Makefile编写及调试
父Makefile 在src目录下包含很多文件夹,那么需要遍历所有的目录执行Makefile,那么给一个在src目录下的Makefile. # 需要排除的目录 exclude_dirs := incl ...
- maven(四):一个基本maven项目的pom.xml配置
继续之前创建的test项目,一个基本项目的pom.xml文件,通常至少有三个部分 第一部分,项目坐标,信息描述等 <modelVersion>4.0.0</modelVersion& ...
- 一个电商项目的Web服务化改造6:单元测试4步走,构造数据、执行操作、断言、回滚
最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA. 有点挑战,做完了,会有很大进步. 单元测试,在很早之前的文章已经介绍过. 可以在这里看到相关的 ...
- 一个电商项目的Web服务化改造2:现有项目的5个问题
最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA. 有点挑战,做完了,会有很大进步, 1.现有项目的问题 1.1代码风格不统一 不同的 ...
- webpack自动生成项目的html
1 自动生成多个html页面 设置webpack.config.js中的plugins属性,多次调用plugin插件(new htmlWebpackPlugin()),同时设置对应数量的.js入口文件 ...
- 一个电商项目的Web服务化改造5:面向服务的分层架构设计(有图有真相)
最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA. 有点挑战,做完了,会有很大进步. 本篇,以我亲自画的3个图,阐述一下架构设计. 一.分层架构-总体图 ...
- 一个电商项目的Web服务化改造4:方案和架构,通用接口的定义和实现
最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA. 有点挑战,做完了,会有很大进步. 上一篇,我们明确了我们的"规范和约定". 从 ...
随机推荐
- 记录一次redis cpu异常升高的排插思路
好久没有写博客 现在重新捡起来 记录工作中遇到的问题 方便以后在遇到类似的问题也有一个参考. 背景:有一天生产服务器redis cpu 频繁报警 单核cpu 所以在想是不是业务量上来了. ...
- ELK 学习笔记之 elasticsearch 版本控制
版本控制: elasticsearch 版本控制: 内部版本控制 外部版本控制 内部版本控制: 内部版本会检查你提供的版本值和文档的版本值是否一致,如果不一致就报错,一致则可以更新. curl -XP ...
- 死磕 java线程系列之自己动手写一个线程池(续)
(手机横屏看源码更方便) 问题 (1)自己动手写的线程池如何支持带返回值的任务呢? (2)如果任务执行的过程中抛出异常了该怎么处理呢? 简介 上一章我们自己动手写了一个线程池,但是它是不支持带返回值的 ...
- golang的生产者消费者模型示例
package main import "fmt" func Producer(ch chan int) { for i := 1; i <= 10; i++ { ch &l ...
- 移动端border-radius的几个BUG
个人博客: http://mcchen.club 一.Android 2.3 自带浏览器不支持 % 通常我们实现一个正圆只需要border-radius: 50%即可,大致代码如下 .foo { wi ...
- Redis单线程架构以及工作方式
一.单线程模型 Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程.其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的每一条到达服务端的命令都不会 ...
- 导图梳理springboot手动、自动装配,让springboot不再难懂
什么是springboot 在学springboot之前,你必须有spring.spring mvc基础,springboot的诞生其实就是用来简化新Spring应用的初始搭建以及开发过程,该框架使用 ...
- Unreal Engine 4 系列教程 Part 3:材质教程
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- 设置Linux支持中文
1.首先在command输入locale,可以看到Linux下默认的系统语言的是英文 2.vim ~/.bashrc打开这个文件,该文件夹相当于系统配置文件 3.打开后,将后三行命令输入到文档中,最后 ...
- [CF722C] Destroying Array
C. Destroying Array time limit per test 1 second memory limit per test 256 megabytes input standard ...