快速编写“专家级”makefile(4.打造更专业的编译环境——增进复用性)

    可以将共用部分放入一个独立的文件中——这就是 build 目录下的 make.rule 文件的作用
    那么,在 foo 模块的 Makefile 中,哪些是不能共用的呢?
  1. 变量 EXE 和 LIB 的定义对于每一个软件模块是不同的
  2. DIR_EXES 变量和 DIR_LIBS 变量由于运用了相对路径,所以也是每个模块特有的。但是可以采用绝对路径的方式解决这个问题。比如,可以定义一个 ROOT 环境变量,其值设置为 huge 项目的根目录,这样的话,DIR_EXES 和 DIR_LIBS 就可以以 ROOT 为相对路径,而使对于所有的模块的相同
    在考虑复用的情形下,foo 模块的 Makefile 有两部分组成,分别是 build 的 make.rule 和 code / foo / src 的 Makefile:
    huge / build / make.rule
  
  
  1. .PHONY : all clean
  2. NKDIR = mkdir
  3. RM = rm
  4. RMFLAG = -rf
  5. CC = gcc
  6. AR = ar
  7. ARFLAG = crs
  8. DIR_OBJS = objs
  9. DIR_EXES = $(ROOT)/build/exes
  10. DIR_DEPS = deps
  11. DIR_LIBS = $(ROOT)/build/libs
  12. DIRS = $(DIR_OBJS) $(DIR_EXES) $(DIR_DEPS) $(DIR_LIBS)
  13. RMS = $(DIR_OBJS) $(DIR_DEPS)
  14. ifneq("$(EXE)", "")
  15. EXE := $(addprefix $(DIR_EXES)/, $(EXE))
  16. RMS += $(EXE)
  17. endif
  18. ifneq("$(LIB)", "")
  19. LIB := $(addprefix $(DIR_LIBS)/, $(LIB))
  20. RMS += $(LIB)
  21. endif
  22. SRCS = $(wildcard *.c)
  23. OBJS = $(SRCS :.c = .o)
  24. OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))
  25. DEPS = $(SRCS :.c = .dep)
  26. DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
  27. ifeq("$(wildcard $(DIR_OBJS))", "")
  28. DEP_DIR_OBJS := $(DIR_OBJS)
  29. endif
  30. ifeq("$(wildcard $(DIR_EXES))", "")
  31. DEP_DIR_EXES := $(DIR_EXES)
  32. endif
  33. ifeq("$(wildcard $(DIR_DEPS))", "")
  34. DEP_DIR_DEPS := $(DIR_DEPS)
  35. endif
  36. ifeq("$(wildcard $(DIR_LIBS))", "")
  37. DEP_DIR_LIBS := $(DIR_LIBS)
  38. endif
  39. all : $(EXE) $(LIB)
  40. ifneq($MAKECMDGOALS, clean)
  41. include $(DEPS)
  42. endif
  43. $(DIRS) :
  44. $(MKDIR) $@
  45. $(EXE) : $(DEP_DIR_EXE) $(OBJS)
  46. $(CC) -o $@ $(filter %.o, $^)
  47. $(LIB) : $(DEP_DIR_LIB) $(OBJS)
  48. $(AR) $(ARFLAG) $@ $(filter %.o, $^)
  49. $(DIR_OBJS) / %.o : $(DEP_DIR_OBJS) %.c
  50. $(CC) -o $@ -c $(filter %.c, $^)
  51. $(DIR_DEPS) / %.dep : $(DEP_DIR_DEPS) %.c
  52. @echo "Creating $@ ..."
  53. @set -e;\
  54. $(RM) $(RMFLAG) $@.tmp;\
  55. $(CC) -E -MM $(filter %.c, $^) > $@.tmp;\
  56. sed 's,\(.*\)\.o[ :]*,objs/\1.o $@: ,g' < $@.tmp > $@;\
  57. $(RM) $(RMFLAG) $@.tmp
  58. clean :
  59. $(RM) $(RMFLAG) $(RMS)
    huge / code / foo / src / Makefile
  
  
  1. EXE =
  2. LIB = libfoo.a
  3. 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
  
  
  1. #innclude <stdio.h>
  2. int main()
  3. {
  4. return 0;
  5. }
    huge / code / huge / src / Makefile
  
  
  1. EXE = huge.exe
  2. LIB =
  3. 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日,星期二
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值