这一节我们来研究一下上一节中makefile存在的问题:

 

第一个问题导致了项目的文件夹不能移动,一旦移动则编译失败。

 

 

这样可以使得工程文件夹随意移动。

顶层makefile改动后的部分程序如下:

第35、36行我们通过命令行变量将路径传到模块makefile中,因此,模块makefile中的这两个相应的写死的路径可以删掉了。

 

 

 模块makefile怎么知道配置文件的位置呢?

 工程makefile的重构:

 

 重构后的目录如下:

 每个模块下有makefile文件,顶层工程也有一个makefile文件。mod-cfg.mk和mod-rule.mk都是和模块makefile相关的。

 

顶层makefile:

1 include pro-cfg.mk
2 include cmd-cfg.mk
3 include pro-rule.mk

 

cmd-cfg.mk:

 1 AR := ar
 2 ARFLAGS := crs
 3 
 4 CC := gcc
 5 LFLAGS := 
 6 CFLAGS := -I$(DIR_INC) -I$(DIR_COMMON_INC)
 7 
 8 ifeq ($(DEBUG),true)
 9 CFLAGS += -g
10 endif
11 
12 MKDIR := mkdir
13 RM := rm -fr

 

pro-cfg.mk:

 1 MODULES := common \
 2            module \
 3            main
 4            
 5 MOD_CFG := mod-cfg.mk
 6 MOD_RULE := mod-rule.mk
 7 CMD_CFG := cmd-cfg.mk
 8 
 9 DIR_BUILD := build
10 DIR_COMMON_INC := common/inc
11 
12 APP := app.out

 

pro-rule.mk:

 1 .PHONY : all compile link clean rebuild
 2 
 3 DIR_PROJECT := $(realpath .)
 4 DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))
 5 MODULE_LIB := $(addsuffix .a, $(MODULES))
 6 MODULE_LIB := $(addprefix $(DIR_BUILD)/, $(MODULE_LIB))
 7 
 8 
 9 APP := $(addprefix $(DIR_BUILD)/, $(APP))
10 
11 all : compile $(APP)
12     @echo "Success! Target ==> $(APP)"
13 
14 compile : $(DIR_BUILD) $(DIR_BUILD_SUB)
15     @echo "Begin to compile ..."
16     @set -e; \
17     for dir in $(MODULES); \
18     do \
19         cd $$dir && \
20         $(MAKE) all \
21                 DEBUG:=$(DEBUG) \
22                 DIR_BUILD:=$(addprefix $(DIR_PROJECT)/, $(DIR_BUILD)) \
23                 DIR_COMMON_INC:=$(addprefix $(DIR_PROJECT)/, $(DIR_COMMON_INC)) \
24                 CMD_CFG:=$(addprefix $(DIR_PROJECT)/, $(CMD_CFG)) \
25                 MOD_CFG:=$(addprefix $(DIR_PROJECT)/, $(MOD_CFG)) \
26                 MOD_RULE:=$(addprefix $(DIR_PROJECT)/, $(MOD_RULE)) && \
27         cd .. ; \
28     done
29     @echo "Compile Success!"
30     
31 link $(APP) : $(MODULE_LIB)
32     @echo "Begin to link ..."
33     $(CC) -o $(APP) -Xlinker "-(" $^ -Xlinker "-)" $(LFLAGS)
34     @echo "Link Success!"
35     
36 $(DIR_BUILD) $(DIR_BUILD_SUB) : 
37     $(MKDIR) $@
38     
39 clean : 
40     @echo "Begin to clean ..."
41     $(RM) $(DIR_BUILD)
42     @echo "Clean Success!"
43     
44 rebuild : clean all

 

模块相关的文件:

mod-cfg.mk:

1 DIR_SRC := src
2 DIR_INC := inc
3 
4 TYPE_INC := .h
5 TYPE_SRC := .c
6 TYPE_OBJ := .o
7 TYPE_DEP := .dep

 

mode-rule.mk:

 1 .PHONY : all
 2 
 3 MODULE := $(realpath .)
 4 MODULE := $(notdir $(MODULE))
 5 DIR_OUTPUT := $(addprefix $(DIR_BUILD)/, $(MODULE))
 6 
 7 OUTPUT := $(MODULE).a
 8 OUTPUT := $(addprefix $(DIR_BUILD)/, $(OUTPUT))
 9 
10 SRCS := $(wildcard $(DIR_SRC)/*$(TYPE_SRC))
11 OBJS := $(SRCS:$(TYPE_SRC)=$(TYPE_OBJ))
12 OBJS := $(patsubst $(DIR_SRC)/%, $(DIR_OUTPUT)/%, $(OBJS))
13 DEPS := $(SRCS:$(TYPE_SRC)=$(TYPE_DEP))
14 DEPS := $(patsubst $(DIR_SRC)/%, $(DIR_OUTPUT)/%, $(DEPS))
15 
16 vpath %$(TYPE_INC) $(DIR_INC)
17 vpath %$(TYPE_INC) $(DIR_COMMON_INC)
18 vpath %$(TYPE_SRC) $(DIR_SRC)
19 
20 -include $(DEPS)
21 
22 all : $(OUTPUT)
23     @echo "Success! Target ==> $(OUTPUT)"
24     
25 $(OUTPUT) : $(OBJS)
26     $(AR) $(ARFLAGS) $@ $^
27     
28 $(DIR_OUTPUT)/%$(TYPE_OBJ) : %$(TYPE_SRC)
29     $(CC) $(CFLAGS) -o $@ -c $(filter %$(TYPE_SRC), $^)
30     
31     
32 $(DIR_OUTPUT)/%$(TYPE_DEP) : %$(TYPE_SRC)
33     @echo "Creating $@ ..."
34     @set -e; \
35     $(CC) $(CFLAGS) -MM -E $(filter %$(TYPE_SRC), $^) | sed 's,\(.*\)\.o[ :]*,$(DIR_OUTPUT)/\1$(TYPE_OBJ) $@ : ,g' > $@

 

module文件夹下的makefile:

 1 include $(MOD_CFG)
 2 
 3 # Custmization Begin
 4 # 
 5 # DIR_SRC := src
 6 # DIR_INC := inc
 7 #
 8 # TYPE_INC := .h
 9 # TYPE_SRC := .c
10 # TYPE_OBJ := .o
11 # TYPE_DEP := .dep
12 #
13 # Custmization End
14 
15 include $(CMD_CFG)
16 
17 include $(MOD_RULE)

 

main文件夹下的makefile:

 1 include $(MOD_CFG)
 2 
 3 # Custmization Begin
 4 # 
 5 # DIR_SRC := src
 6 # DIR_INC := inc
 7 #
 8 # TYPE_INC := .h
 9 # TYPE_SRC := .c
10 # TYPE_OBJ := .o
11 # TYPE_DEP := .dep
12 #
13 # Custmization End
14 
15 include $(CMD_CFG)
16 
17 include $(MOD_RULE)

 

common文件夹下的makefile:

 1 include $(MOD_CFG)
 2 
 3 # Custmization Begin
 4 # 
 5 # DIR_SRC := src
 6 # DIR_INC := inc
 7 #
 8 # TYPE_INC := .h
 9 # TYPE_SRC := .c
10 # TYPE_OBJ := .o
11 # TYPE_DEP := .dep
12 #
13 # Custmization End
14 
15 include $(CMD_CFG)
16 
17 include $(MOD_RULE)

 mod-cfg.mk全局配置文件是通用的配置,也许有一些模块有特殊的配置,需要特殊配置的时候我们只需要去模块的makefile中改动即可,或者覆盖掉通用配置中的一些变量。

小结:

 

参考:

  狄泰软件学院视频教程

posted on 2018-10-01 18:15  周伯通789  阅读(192)  评论(0编辑  收藏  举报