转载的一篇文章,扩展性不强,但是基本揭露了大型工程build的过程。
最近一直在研究makefile ,看了网上比较流行的文章《跟我一起写 Makefile》,还有一篇是《GNU makefile中文手册》,两者的关系是前者是后者的子集,连《跟我一起写 Makefile》作者都说了是参考《GNU makefile中文手册》来写的,感叹linux下的开发真的是奥妙无穷,每一项技术都似一顿饕餮大餐,吃起来爽,消化掉难。
make 的技术目前还只是掌握了点皮毛而已,书上的范例只是针对了同目录下的多文件的编译讲解,可是我想通常一个简单的项目也不止一个目录,于是学着写一个多目录下的的makefile,搞了一天,居然不知从何下手,晕!baidu 一下,没几篇文章介绍的,而且仅有的几篇也写得比较模糊,方法也千差万别。。。
郁闷中,突然想起自己手头的项目的GUI模块的makefile 不是咱老大写的么,醍醐灌顶...,为什么最需要的总是最后才想起?只怪自己开窍太慢!废话少说,赶紧的!!
说实话,目前所做的项目技术含量低,嵌入式开发中的GUI模块,不过这个GUI模块的规模还不小,里面还细分了好几块,正好满足我的要求,打开老大的杰作仔细端倪,跟踪打印信息,一步一步推敲(笨人的高招),还真有点开窍了,老大就是老大阿。
下面就是我自己参考老大的技术写的针对多目录的makefile
我们要编译的工程是一个主目录proj, 它下面有4个子目录: /main /ui /math /obj
其中
main中包含文件 main.c
ui 中包含了文件 ui.h ui.c
math 中包含了文件 math.h math.c
obj 用于存放最终生成的目标
他们的关系是
main.c include "ui.h" "math.h"
ui.c include "ui.h" "math.h"
math.c include "math.h"
要求是在proj 目中的obj 目录中生成 out(主程序) ui.o main.o 以及一个动态库文件 libmath.so
第一种做法是在每一个子目录中都添加一个makefile文件, 当然主目录proj中的makefile必不可少,同时还在主目录中
创建一个env.mk文件,其作用就是包含了其他makefile都用到的模式规则
--------------------- env.mk----------------------------
CC := gcc
#头文件目录
INCLUDE_DIR := \
-I$(MAKEROOT)/ui \
-I$(MAKEROOT)/main \
-I$(MAKEROOT)/math
CFLAGS := $(INCLUDE_DIR)
#对所有的.o文件以.c文件创建它
%.o : %.c
${CC} ${CFLAGS} -c $< -o $(MAKEROOT)/obj/$@
--------------------------------------------------------
-------------------proj/makefile -----------------------
export MAKEROOT := $(shell pwd)
TARGET_DIRS := main \
include ./env.mk
define build_obj
for SubDir in $(TARGET_DIRS); do \ #对所每一个子目录如果其存在
echo "Building $$SubDir is failed !"; \
done
endef
all :
@$(call build_obj) #调用过程
gcc -fPIC -o out ./obj/*.o ./obj/*.so #生成最终目标
clean :
-rm ./obj/*.o ./out ./obj/*.so
--------------------------------------------------------
------------- ui/makefile main/makefile ----------------
include $(MAKEROOT)/env.mk #包括头文件,执行模式规则
SRCS := $(wildcard *.c)
OBJS := $(patsubst %.c,%.o,$(SRCS)) #生成所有.c文件对应的.o文件
.PHONY : all
all : $(OBJS)
--------------------------------------------------------
------------------ math/makefile -----------------------
.PHONY : all
all :
gcc -shared -o ../obj/libmath.so math.c math.h #生成动态库文件
--------------------------------------------------------
现在只要到proj主目录中,执行make all 命令就万事OK啦!!