第二十课 打造专业的编译环境(上)

 本节我们研究大型项目的编译。大型项目的结构如下:

大型项目会划分不同的模块,不同的模块负责不同的功能。在模块文件夹中还有更深一层的文件夹管理,如上图中的module模块中的样子。

每个模块都有一个makefile,负责当前模块的编译工作。

最顶层的makefile负责整体控制。

build文件夹负责存储编译结果,这样可以防止污染源代码。

build文件夹中也有相应的管理结构,和每个模块相关。和project文件夹中的一一对应。

每个模块中的.o文件统一打包成.a文件放到build文件夹根目录下,最终链接.a文件。

模块之间有互相依赖关系,因此,模块需要将功能函数提供出去,每个模块的功能可以通过common模块下的include文件夹提供出去(通过头文件的方式)。

 需要的编译环境需求如下:

 具体实现:

第一阶段:每个模块编译成一个.a打包文件。

 第二阶段:将模块静态库链接在一起生成可执行文件。

任务:

 模块makefile的构成:

  include部分:用来自动生成依赖关系

  all(真正的编译部分):链接静态库文件

实验代码目录如下:

 小实验:

当前工作目录在common文件夹下,makefile也在common文件夹下:

在本节中,这个makefile暂时不是顶层makefile,而是模块makefile,将这个makefile分别放到common、module、main文件夹下分别编译:

 1 .PHONY : all
 2 
 3 DIR_BUILD := /home/delphi/make/build
 4 DIR_COMMON_INC := /home/delphi/make/common/inc
 5 
 6 DIR_SRC := src
 7 DIR_INC := inc
 8 
 9 TYPE_INC := .h
10 TYPE_SRC := .c
11 TYPE_OBJ := .o
12 TYPE_DEP := .dep
13 
14 AR := ar
15 ARFLAGS := crs
16 
17 CC := gcc
18 CFLAGS := -I$(DIR_INC) -I$(DIR_COMMON_INC)
19 
20 ifeq ($(DEBUG),true)
21 CFLAGS += -g
22 endif
23 
24 MODULE := $(realpath .)
25 MODULE := $(notdir $(MODULE))
26 DIR_OUTPUT := $(addprefix $(DIR_BUILD)/, $(MODULE))
27 
28 OUTPUT := $(MODULE).a
29 OUTPUT := $(addprefix $(DIR_BUILD)/, $(OUTPUT))
30 
31 SRCS := $(wildcard $(DIR_SRC)/*$(TYPE_SRC))
32 OBJS := $(SRCS:$(TYPE_SRC)=$(TYPE_OBJ))
33 OBJS := $(patsubst $(DIR_SRC)/%, $(DIR_OUTPUT)/%, $(OBJS))
34 DEPS := $(SRCS:$(TYPE_SRC)=$(TYPE_DEP))
35 DEPS := $(patsubst $(DIR_SRC)/%, $(DIR_OUTPUT)/%, $(DEPS))
36 
37 vpath %$(TYPE_INC) $(DIR_INC)
38 vpath %$(TYPE_INC) $(DIR_COMMON_INC)
39 vpath %$(TYPE_SRC) $(DIR_SRC)
40 
41 -include $(DEPS)
42 
43 all : $(OUTPUT)
44     @echo "Success! Target ==> $(OUTPUT)"
45     
46 $(OUTPUT) : $(OBJS)
47     $(AR) $(ARFLAGS) $@ $^
48     
49 $(DIR_OUTPUT)/%$(TYPE_OBJ) : %$(TYPE_SRC)
50     $(CC) $(CFLAGS) -o $@ -c $(filter %$(TYPE_SRC), $^)
51     
52     
53 $(DIR_OUTPUT)/%$(TYPE_DEP) : %$(TYPE_SRC)
54     @echo "Creating $@ ..."
55     @set -e; 
56     $(CC) $(CFLAGS) -MM -E $(filter %$(TYPE_SRC), $^) | sed 's,(.*).o[ :]*,$(DIR_OUTPUT)/1$(TYPE_OBJ) $@ : ,g' > $@

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9735204.html