Linux 是所有嵌入式软件工程师绕不过去的坎,
makefile 是在Linux系统中绕不过去的坎。
花了几天时间初步学习和了解了makefile 的作用以及功能,并且制作了一个通用型的makefile 用于管理后续可能的在Linux上独立开发的项目。
在此用笔记的方式记下。怕自己以后忘了。
makefile 思想: makefile 核心公式
:
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 =.c3
4 #您想要生成可执行文件的名字5 BinName :=obj.out6
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 =gcc38
39 #C++编译器40 CXX = g++
41
42 #简化rm -f43 RM = -rm -f44
45 #C语言配置参数46 CFLAGS = -g -pedantic -std=c99 -Wall -o47
48 #C++配置参数49 CXXFLAGS = -g -Wall -std=c1150
51 #头文件搜索路径52 INCLUDE_PATH = $(foreach n,$(AllDirs) , -I$(n))53
54
55 LDFLAGS =
56
57 #指定AllLibs为终极目标 即:最新的Bin58 AllLibs:$(Bin)59
60 #声明这个标签 des 用于观察当前的路径是否正确61 .PHONY:des62 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 : %.c71 @echo 'finding $< depending head file'
72 @$(CC) -MT"$(<:.c> $@
73
74 #对于include中的*.d文件,只要里面任意有一个文件被修改,那么就会触发此规则生成一个新的*.o文件75 %.o: %.d76 @echo compile $(<:d>
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 : clean87 clean:88 @echo '清理所有文件'
89 @$(RM) $(OBJS) $(Deps) $(Bin)90
91 .PHONY : cleanO92 cleanO:93 @echo '清理Obj && Dep'
94 @$(RM) $(OBJS) $(Deps)95 # #########################################################################96 # 单独的 < 符号代表 依存源文件(即冒号: 的左边) $
107 # 其余makefile 知识参考 《跟我一起写 MakeFile》 ----陈皓108 # #########################################################################109
View Code