zoukankan      html  css  js  c++  java
  • 多层级makefile

    多层级makefile

    当项目变大之后,需要多层级的makefile来编译,每个makefile的具体功能实现参考单源文件目录makefile。然后再在顶层目录写一个总的makefile来实现编译逻辑就行。
    这里假设存在main模块和libdevcore模块。

    顶层makefile

    # 项目根目录
    TOP_DIR:=$(patsubst %/, %, $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
    export TOP_DIR
    
    # 各项目录
    BUILD_DIR:=$(TOP_DIR)/build
    BIN_DIR:=$(BUILD_DIR)/bin
    export BUILD_DIR
    
    #编译器
    CXX:=g++
    CXXFLAGS:=-std=c++11 -Wall -Wextra -Og -g
    INCS:=-I $(TOP_DIR)
    MACROS:=
    export CXX CXXFLAGS INCS MACROS
    
    # 链接器
    LD:=g++
    LDFLAGS:=
    LIBS:=
    
    # 各个模块
    MODULES:=libmain libdevcore
    
    # 各个模块对应的库
    MODULE_LIBS:=$(BUILD_DIR)/libmain/lib/libmain.a
                 $(BUILD_DIR)/libdevcore/lib/libdevcore.a
    
    # 最终目标文件
    TARGET:=$(BIN_DIR)/hello
    
    # 默认最终目标
    .PHONY:all
    all:$(TARGET)
    
    # 最终目标依赖关系
    $(TARGET):FORCE | $(BIN_DIR)
    	@for n in $(MODULES); do make -s -f $(TOP_DIR)/$$n/makefile MODULE=$$n || exit "$$?"; done
    	@echo -e "e[32m""Linking executable $(TARGET)""e[0m"
    	@$(LD) $(LDFLAGS) -o $@ $(MODULE_LIBS) $(LIBS)
    
    # 若没有bin目录则自动生成
    $(BIN_DIR):
    	@mkdir -p $@
    
    # 强制执行命令
    .PHONY:FORCE
    FORCE:
    
    # make clean直接删除整个build目录
    .PHONY:clean
    clean:
    	@rm -rf $(BUILD_DIR)
    

    各模块makefile

    # 各项目录
    LIB_DIR:=$(BUILD_DIR)/$(MODULE)/lib
    DEP_DIR:=$(BUILD_DIR)/$(MODULE)/.dep
    OBJ_DIR:=$(BUILD_DIR)/$(MODULE)/obj
    SRC_DIR:=$(TOP_DIR)/$(MODULE)
    
    # 源文件以及中间目标文件和依赖文件
    SRCS:=$(notdir $(wildcard $(SRC_DIR)/*.cpp))
    OBJS:=$(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(SRCS)))
    DEPS:=$(addprefix $(DEP_DIR)/, $(patsubst %.cpp, %.d,a $(SRCS)))
    
    # 自动生成头文件依赖选项
    DEPFLAGS=-MT $@ -MMD -MP -MF $(DEP_DIR)/$*.d
    
    # 最终目标文件
    TARGET:=$(LIB_DIR)/$(MODULE).a
    
    # 默认最终目标
    .PHONY:all
    all:$(TARGET)
    
    # 生成最终目标
    $(TARGET):$(OBJS) | $(LIB_DIR)
    	@echo -e "e[32m""Linking static library $(TARGET)""e[0m"
    	@ar -rc $@ $^
    
    # 若没有lib目录则自动生成
    $(LIB_DIR):
    	@mkdir -p $@
    
    # 生成中间目标文件
    $(OBJ_DIR)/%.o:$(SRC_DIR)/%.cpp $(DEP_DIR)/%.d | $(OBJ_DIR) $(DEP_DIR)
    	@echo -e "e[33m""Building object $@""e[0m"
    	@$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) $(INCS) $(MACROS) -o $@ $<
    
    # 若没有obj目录则自动生成
    $(OBJ_DIR):
    	@mkdir -p $@
    
    # 若没有.dep目录则自动生成
    $(DEP_DIR):
    	@mkdir -p $@
    
    # 依赖文件会在生成中间文件的时候自动生成,这里只是为了防止报错
    $(DEPS):
    
    # 引入中间目标文件头文件依赖关系
    include $(wildcard $(DEPS))
    
    # 直接删除组件build目录
    .PHONY:clean
    clean:
    	@rm -rf $(BUILD_DIR)/$(MODULE)
    
  • 相关阅读:
    细说Unity3D(一)——移动平台动态读取外部文件全解析
    React16新增生命周期与旧版本生命周期的区别
    refs的作用是什么,你在什么业务场景下使用过refs
    react setState 的用法
    webpack中,是借助loader完成的JSX代码的转化,还是babel?
    虚拟dom是什么?为什么虚拟dom会提升代码性能?
    react 性能优化的最佳实践?
    你会把数据统一放在 redux 中管理,还是共享数据放在 redux 中管理?
    redux 中间件的原理是什么?
    谈谈你对This对象的理解?
  • 原文地址:https://www.cnblogs.com/HachikoT/p/12722487.html
Copyright © 2011-2022 走看看