zoukankan      html  css  js  c++  java
  • 第二十课 打造专业的编译环境(上)

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

    大型项目会划分不同的模块,不同的模块负责不同的功能。在模块文件夹中还有更深一层的文件夹管理,如上图中的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' > $@

  • 相关阅读:
    c#中的委托和事件
    C++STL中的vector
    java中的static
    java中public private protected区别
    java中抽象类与接口
    c++中的namespace
    北京“新城卓越”黑中介租房感受
    如何删除当前正在使用的SQLLite文件?
    SVN将一台服务器上的代码迁移到另一台服务器上
    使用PowerDesigner对NAME和COMMENT互相转换
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9735204.html
Copyright © 2011-2022 走看看