多目录工程构建Makefile的编写
2013-06-05 10:12
190 查看
转载的一篇文章,扩展性不强,但是基本揭露了大型工程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 \
ui \
math
include ./env.mk
define build_obj
for SubDir in $(TARGET_DIRS); do \ #对所每一个子目录如果其存在
if ! [ -d $$SubDir ]; then \
echo "The $$SubDir is not exist !"; \
exit 11; \
fi; \
echo "Building $$SubDir ..."; \
make -C $$SubDir ; \ #执行子目录的makefile
if [ $$? -ne 0 ]; then \
echo "Building $$SubDir is failed !"; \
exit 12; \
fi; \
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啦!!
最近一直在研究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 \
ui \
math
include ./env.mk
define build_obj
for SubDir in $(TARGET_DIRS); do \ #对所每一个子目录如果其存在
if ! [ -d $$SubDir ]; then \
echo "The $$SubDir is not exist !"; \
exit 11; \
fi; \
echo "Building $$SubDir ..."; \
make -C $$SubDir ; \ #执行子目录的makefile
if [ $$? -ne 0 ]; then \
echo "Building $$SubDir is failed !"; \
exit 12; \
fi; \
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啦!!
相关文章推荐
- Makefile构建工程设计——工程构建与编写规则
- makefile编写---多目录工程范例
- linux下C工程层级目录的Makefile编写
- makefile 进阶--可以用于实际嵌入式工程中的文件编写2目录引入
- 一个较为通用的linux工程目录架构和Makefile
- 使用Gradle构建SpringBoot工程系列:第五篇:编写Spring Boot主类及第一次运行
- 单目录下多文件 makefile编写
- 工程中编写自己的makefile---2 实例
- Eclipse 使用 Maven 构建动态 Web 工程,默认无 java 目录的解决方法
- makefile 多级目录如何编写
- 多文件及多目录下MakeFile文件的编写
- cmake使用总结(转)---工程主目录CMakeList文件编写
- linux Makefile : 编译包含非当前目录的工程
- 简单工程Makefile的编写
- GCC 编译动态链接库和静态链接库 + 大型工程Makefile编写 + Linux环境变量的设置和查看方法
- 工程中编写自己的makefile---3 交叉编译工具
- 简单工程Makefile的编写
- 工程中编写自己的makefile---4 库文件
- 多目录时Makefile 的编写方法
- 编写多文件,多目录makefile(借鉴网上的一篇文章来自己练手)