快速编写“专家级”makefile(4.打造更专业的编译环境——增进复用性)
2016-07-22 13:22
447 查看
可以将共用部分放入一个独立的文件中——这就是 build 目录下的 make.rule 文件的作用
那么,在 foo 模块的 Makefile 中,哪些是不能共用的呢?
变量 EXE 和 LIB 的定义对于每一个软件模块是不同的
DIR_EXES 变量和 DIR_LIBS 变量由于运用了相对路径,所以也是每个模块特有的。但是可以采用绝对路径的方式解决这个问题。比如,可以定义一个 ROOT 环境变量,其值设置为 huge 项目的根目录,这样的话,DIR_EXES 和 DIR_LIBS 就可以以 ROOT 为相对路径,而使对于所有的模块的相同
在考虑复用的情形下,foo 模块的 Makefile 有两部分组成,分别是 build 的 make.rule 和 code / foo / src 的 Makefile:
huge / build / make.rule
huge / code / foo / src / Makefile
这样 foo 模块的 Makefile 变得非常简单,因为大部分内容都被移到 make.rule 中。如果要运行 make ,必须先在 Shell 中导出所需的 ROOT 环境变量
/Makefile/huge
$ export ROOT = `pwd`
$ echo $ROOT
/Makefile/huge
$ cd code/foo/src
$ make
mkdir deps
Creating deps / foo.dep ...
mkdir objs
gcc -o objs / foo.o -c foo.c
ar crs /Makefile/huge/build/libs/libfoo.a objs/foo.o
$ make clean
rm -rf objs deps /Makefile/huge/build/libs/libfoo.a
接下来需要考虑 code / huge / src 目录中的 Makefile 了,我们需要在此目录下放置一个 main.c 文件,生成一个可执行程序:
huge / code / huge / src / main.c
huge / code / huge / src / Makefile
运行结果:
$ make
mkdir deps
Creating deps / main.dep ...
mkdir objs
gcc -o objs / main.o -c main.c
gcc -o /Makefile/huge/build/exes/huge.exe objs/main.o
$ ls $ROOT/build/exes
huge.exe
$ make clean
rm -rf objs deps / Makefile / huge / build / exes / huge.exe
参考文献:《专业嵌入式软件开发》李云·著
2016年7月5日,星期二
那么,在 foo 模块的 Makefile 中,哪些是不能共用的呢?
变量 EXE 和 LIB 的定义对于每一个软件模块是不同的
DIR_EXES 变量和 DIR_LIBS 变量由于运用了相对路径,所以也是每个模块特有的。但是可以采用绝对路径的方式解决这个问题。比如,可以定义一个 ROOT 环境变量,其值设置为 huge 项目的根目录,这样的话,DIR_EXES 和 DIR_LIBS 就可以以 ROOT 为相对路径,而使对于所有的模块的相同
在考虑复用的情形下,foo 模块的 Makefile 有两部分组成,分别是 build 的 make.rule 和 code / foo / src 的 Makefile:
huge / build / make.rule
.PHONY : all clean
NKDIR = mkdir
RM = rm
RMFLAG = -rf
CC = gcc
AR = ar
ARFLAG = crs
DIR_OBJS = objs
DIR_EXES = $(ROOT)/build/exes
DIR_DEPS = deps
DIR_LIBS = $(ROOT)/build/libs
DIRS = $(DIR_OBJS) $(DIR_EXES) $(DIR_DEPS) $(DIR_LIBS)
RMS = $(DIR_OBJS) $(DIR_DEPS)
ifneq("$(EXE)", "")
EXE := $(addprefix $(DIR_EXES)/, $(EXE))
RMS += $(EXE)
endif
ifneq("$(LIB)", "")
LIB := $(addprefix $(DIR_LIBS)/, $(LIB))
RMS += $(LIB)
endif
SRCS = $(wildcard *.c)
OBJS = $(SRCS :.c = .o)
OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))
DEPS = $(SRCS :.c = .dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
ifeq("$(wildcard $(DIR_OBJS))", "")
DEP_DIR_OBJS := $(DIR_OBJS)
endif
ifeq("$(wildcard $(DIR_EXES))", "")
DEP_DIR_EXES := $(DIR_EXES)
endif
ifeq("$(wildcard $(DIR_DEPS))", "")
DEP_DIR_DEPS := $(DIR_DEPS)
endif
ifeq("$(wildcard $(DIR_LIBS))", "")
DEP_DIR_LIBS := $(DIR_LIBS)
endif
all : $(EXE) $(LIB)
ifneq($MAKECMDGOALS, clean)
include $(DEPS)
endif
$(DIRS) :
$(MKDIR) $@
$(EXE) : $(DEP_DIR_EXE) $(OBJS)
$(CC) -o $@ $(filter %.o, $^)
$(LIB) : $(DEP_DIR_LIB) $(OBJS)
$(AR) $(ARFLAG) $@ $(filter %.o, $^)
$(DIR_OBJS) / %.o : $(DEP_DIR_OBJS) %.c
$(CC) -o $@ -c $(filter %.c, $^)
$(DIR_DEPS) / %.dep : $(DEP_DIR_DEPS) %.c
@echo "Creating $@ ..."
@set -e;\
$(RM) $(RMFLAG) $@.tmp;\
$(CC) -E -MM $(filter %.c, $^) > $@.tmp;\
sed 's,\(.*\)\.o[ :]*,objs/\1.o $@: ,g' < $@.tmp > $@;\
$(RM) $(RMFLAG) $@.tmp
clean :
$(RM) $(RMFLAG) $(RMS)
huge / code / foo / src / Makefile
EXE =
LIB =libfoo.a
include $(ROOT)/build/make.rule
这样 foo 模块的 Makefile 变得非常简单,因为大部分内容都被移到 make.rule 中。如果要运行 make ,必须先在 Shell 中导出所需的 ROOT 环境变量
/Makefile/huge
$ export ROOT = `pwd`
$ echo $ROOT
/Makefile/huge
$ cd code/foo/src
$ make
mkdir deps
Creating deps / foo.dep ...
mkdir objs
gcc -o objs / foo.o -c foo.c
ar crs /Makefile/huge/build/libs/libfoo.a objs/foo.o
$ make clean
rm -rf objs deps /Makefile/huge/build/libs/libfoo.a
接下来需要考虑 code / huge / src 目录中的 Makefile 了,我们需要在此目录下放置一个 main.c 文件,生成一个可执行程序:
huge / code / huge / src / main.c
#innclude <stdio.h>
int main()
{
return 0;
}
huge / code / huge / src / Makefile
EXE =huge.exe
LIB =
include $(ROOT)/build/make.rule
运行结果:
$ make
mkdir deps
Creating deps / main.dep ...
mkdir objs
gcc -o objs / main.o -c main.c
gcc -o /Makefile/huge/build/exes/huge.exe objs/main.o
$ ls $ROOT/build/exes
huge.exe
$ make clean
rm -rf objs deps / Makefile / huge / build / exes / huge.exe
参考文献:《专业嵌入式软件开发》李云·著
2016年7月5日,星期二
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍