A Makefile example

文件组织结构

UserApp
|-Binary
|    |-X11                    存放可执行文件
|
|-Library
|    |-X11                    存放各种库
|
|-Include                    存放公共头文件
|-Source                    源代码主目录
|    |-Makefile             主makefile文件,编译起始点
|    |-Makefile_Dep    辅助makefile文件,用于自动生成依赖文件
|    |-Makefile_Lib       辅助makefile文件,用于连接生成库和可执行文件
|    |
|    |-UIFrameWork    UIFrameWork源代码主目录
|    |    |-Build             存放编译产生的log文件
|    |    |-DynamicLib 动态库主目录
|    |    |    |-DLib1       动态库1
|    |    |    |    |-Inc      动态库1的头文件
|    |    |    |    |-Src      动态库1的.c和.cpp文件
|    |    |    |    |-UserLibs 动态库1对其它库的依赖关系说明
|    |    |    |
|    |    |    |-DLib2     动态库2
|    |    |    ...
|    |    |
|    |    |-StaticLib       静态库主目录
|    |    |    |-SLib1       静态库1
|    |    |    |    |-Inc      静态库1的头文件
|    |    |    |    |-Src      静态库1的.c和.cpp文件
|    |    |    |
|    |    |    |-SLib2       静态库2
|    |    |    ...
|    |    |
|    |    |-Exec             可执行文件主目录
|    |    |    |-Exec1      可执行文件1
|    |    |    |    |-Inc      可执行文件1的头文件
|    |    |    |    |-Src      可执行文件1的.c和.cpp文件
|    |    |    |    |-UserLibs   可执行文件1对其它库的依赖关系说明
|    |    |    |
|    |    |    |-Exec2      可执行文件2
|    |    |    ...

针对上述文件结构可以使用如下makefile进行编译
#######################################
# filename : Makefile
#######################################
# Every Makefile should contain this line, to avoid trouble
# on systems where the SHELL variable might be inherited
# from the environment.
export SHELL             = /bin/sh

# Different make programs have incompatible suffix lists
# and implicit rules, and this sometimes creates confusion
# or misbehavior. So it is a good idea to set the suffix
# list explicitly using only the suffixes you need in the
# particular Makefile
.SUFFIXES:
.SUFFIXES: .cpp .c .o

# define working path
export APP_BASE_PATH         := $(shell pwd)/..
export APP_BINARY_PATH         := $(APP_BASE_PATH)/Binary/X11
export APP_LIBRARY_PATH     := $(APP_BASE_PATH)/Library/X11

export APP_INCLUDE_PATH        := $(APP_BASE_PATH)/Include

export STATIC_LIB_PATH        := $(APP_BASE_PATH)/Source/UIFrameWork/StaticLib
export DYNAMIC_LIB_PATH        := $(APP_BASE_PATH)/Source/UIFrameWork/DynamicLib
export EXEC_PATH        := $(APP_BASE_PATH)/Source/UIFrameWork/Exec

export STATIC_LIB_PATHS        := $(wildcard $(STATIC_LIB_PATH)/*)
export DYNAMIC_LIB_PATHS    := $(wildcard $(DYNAMIC_LIB_PATH)/*)
export EXEC_PATHS        := $(wildcard $(EXEC_PATH)/*)

export STATIC_LIB_INC_PATHS    :=
export DYNAMIC_LIB_INC_PATHS    :=
export EXEC_INC_PATHS        :=

export STATIC_LIB_INC_PATHS    += $(foreach static_lib_path, $(STATIC_LIB_PATHS), $(static_lib_path)/Inc)
export DYNAMIC_LIB_INC_PATHS    += $(foreach dynamic_lib_path, $(DYNAMIC_LIB_PATHS), $(dynamic_lib_path)/Inc)
export EXEC_INC_PATHS        += $(foreach exec_lib_path, $(EXEC_PATHS), $(exec_lib_path)/Inc)

export INCLUDE_PATHS        = $(APP_INCLUDE_PATH) /
                   $(STATIC_LIB_INC_PATHS) /
                   $(DYNAMIC_LIB_INC_PATHS) /
                   $(EXEC_INC_PATHS)

export COMPILE_LOG_FILE        := $(APP_BASE_PATH)/Source/UIFrameWork/Build/CompileLog.txt
export COMPILE_LOG_FILE_OLD    := $(APP_BASE_PATH)/Source/UIFrameWork/Build/CompileLog_old.txt
export MAKE_FLAGS        := >>$(COMPILE_LOG_FILE) 2>>$(COMPILE_LOG_FILE)
export COMPILE_STAMP_FILE    := $(APP_BASE_PATH)/Source/UIFrameWork/Build/CompileTime.txt

export MAKEFILE_DEP        = $(shell pwd)/Makefile_Dep
export MAKEFILE_LIB        = $(shell pwd)/Makefile_Lib

# define variables used as names of programs in built-in rules
export AR             := ar
export CC             := gcc
export CXX             := g++
export RM             := rm -rf
export CP             := cp -f
export RANLIB             := ranlib
export MKDIR            := mkdir -p
export ARFLAGS             := curS
export CFLAGS             := -O2 -g -Wall -fmessage-length=0
export CXXFLAGS         := -O2 -g -Wall -fmessage-length=0
export LDFLAGS             :=
export STRIP            := strip

.PHONY:all
all:
    @ echo "================make all start================"
    @ echo "[Make start]" >> $(COMPILE_STAMP_FILE)
    @ date >> $(COMPILE_STAMP_FILE)
    @ -cat $(COMPILE_LOG_FILE) > $(COMPILE_LOG_FILE_OLD)
    @ echo "" > $(COMPILE_LOG_FILE)
    @ echo "Compiling static libs"
    @ for i in $(STATIC_LIB_PATHS); do /
        echo "    $$i"; /
        cd $$i /
        && $(MAKE) all -f $(MAKEFILE_DEP) $(MAKE_FLAGS) /
        && $(MAKE) staticlib -f $(MAKEFILE_LIB) $(MAKE_FLAGS) /
        || exit $$?; /
        done
    @ echo "Compiling dynamic libs"
    @ for i in $(DYNAMIC_LIB_PATHS); do /
        echo "    $$i"; /
        cd $$i /
        && $(MAKE) all -f $(MAKEFILE_DEP) $(MAKE_FLAGS) POS_INDEP=-fPIC /
        && $(MAKE) dynamiclib -f $(MAKEFILE_LIB) $(MAKE_FLAGS) /
        ||exit $$?; /
        done
    @ echo "Compiling execs"
    @ for i in $(EXEC_PATHS); do /
        echo "    $$i"; /
        cd $$i /
        && $(MAKE) all -f $(MAKEFILE_DEP) $(MAKE_FLAGS) /
        && $(MAKE) exec -f $(MAKEFILE_LIB) $(MAKE_FLAGS) /
        ||exit $$?; /
        done
    @ echo "[Make done]" >> $(COMPILE_STAMP_FILE)
    @ date >> $(COMPILE_STAMP_FILE)
    @ echo "================make all done================="

.PHONY:strip
strip:
    @ echo "================strip start================"
    @ $(STRIP) $(wildcard $(APP_LIBRARY_PATH)/*)
    @ $(STRIP) $(wildcard $(APP_BINARY_PATH)/*)
    @ echo "================strip done================="

.PHONY:clean
clean:
    @ echo "================clean start================"
    @ for i in $(STATIC_LIB_PATHS) $(DYNAMIC_LIB_PATHS) $(EXEC_PATHS); /
        do cd $$i; /
        $(MAKE) clean -f $(MAKEFILE_DEP); /
        $(MAKE) clean -f $(MAKEFILE_LIB); /
        done
    @ echo "================clean done================="

#######################################
# filename : Makefile_Dep
#######################################
# Create the dependency files
# input:
#    POS_INDEP, if defined as "-fPIC",
#        create position independent
#        code for shared library.
# note:
#     1. create ./Dep/%_c.d   for ./Src/%.c
#     2. create ./Dep/%_cpp.d for ./Src/%.cpp

C_DEP_FILE_PATHS        = $(patsubst ./Src/%.c, /
                         ./Dep/%_c.d, /
                         $(wildcard ./Src/*.c))
$(C_DEP_FILE_PATHS): ./Dep/%_c.d: ./Src/%.c
    $(MKDIR) ./Dep
    $(CC) -MM $(patsubst %, -I%, $(INCLUDE_PATHS)) $< /
        -MT $(patsubst Dep/%.d, Obj/%.o, $@) > $@
    @ echo '    '$(MKDIR) ./Obj >> $@
    @ echo '    '$(CC) -c $(POS_INDEP) $< -o $(patsubst Dep/%.d, Obj/%.o, $@) /
        $(CFLAGS) $(patsubst %, -I%, $(INCLUDE_PATHS)) >> $@

CPP_DEP_FILE_PATHS        = $(patsubst ./Src/%.cpp, /
                         ./Dep/%_cpp.d, /
                         $(wildcard ./Src/*.cpp))
$(CPP_DEP_FILE_PATHS): ./Dep/%_cpp.d: ./Src/%.cpp
    $(MKDIR) ./Dep
    $(CXX) -MM $(patsubst %, -I%, $(INCLUDE_PATHS)) $< /
        -MT $(patsubst Dep/%.d, Obj/%.o, $@) > $@
    @ echo '    '$(MKDIR) ./Obj >> $@
    @ echo '    '$(CXX) -c $(POS_INDEP) $< -o $(patsubst Dep/%.d, Obj/%.o, $@) /
        $(CXXFLAGS) $(patsubst %, -I%, $(INCLUDE_PATHS)) >> $@

#
# Target: all
#
.PHONY: all
all: $(C_DEP_FILE_PATHS) $(CPP_DEP_FILE_PATHS)

CUR_FOLDER_NAME        = $(notdir $(shell pwd))
#
# Target: clean
#
clean:
    @ echo "clean dependent files [$(CUR_FOLDER_NAME)] start"
    $(RM) ./Dep
    @ echo "clean dependent files [$(CUR_FOLDER_NAME)] done"

#######################################
# filename : Makefile_Lib
#######################################
DEP_FILE_PATTEN        = ./Dep/*.d
ifneq ($(wildcard $(DEP_FILE_PATTEN)),)
    include $(wildcard $(DEP_FILE_PATTEN))
endif

FOLDER_NAME        = $(notdir $(shell pwd))
STATIC_LIB_TARGET    = $(APP_LIBRARY_PATH)/lib$(FOLDER_NAME).a
DYNAMIC_LIB_TARGET    = $(APP_LIBRARY_PATH)/lib$(FOLDER_NAME).so
EXEC_TARGET        = $(APP_BINARY_PATH)/$(FOLDER_NAME)

C_SRC_FILES        := $(wildcard ./Src/*.c)
C_OBJ_FILES        := $(patsubst ./Src/%.c, ./Obj/%_c.o, $(C_SRC_FILES))

CPP_SRC_FILES        := $(wildcard ./Src/*.cpp)
CPP_OBJ_FILES        := $(patsubst ./Src/%.cpp, ./Obj/%_cpp.o, $(CPP_SRC_FILES))

LIB_MEMBERS        := $(C_OBJ_FILES) $(CPP_OBJ_FILES)
$(STATIC_LIB_TARGET):$(LIB_MEMBERS)
    @ echo ========linking static lib [$@] start========
    $(AR) $(ARFLAGS) $@ $?
    $(RANLIB) $@
    @ echo ========linking static lib [$@] done=========

USER_LIBS_FILE        := $(shell pwd)/UserLibs
ifneq ($(wildcard $(USER_LIBS_FILE)),)
    include $(wildcard $(USER_LIBS_FILE))
USER_LIBS        := $(patsubst %, $(APP_LIBRARY_PATH)/lib%.a, $(USER_STATIC_LIBS))
USER_LIBS        += $(patsubst %, $(APP_LIBRARY_PATH)/lib%.so, $(USER_DYNAMIC_LIBS))
endif

$(DYNAMIC_LIB_TARGET):$(C_OBJ_FILES) $(CPP_OBJ_FILES) $(USER_LIBS)
    @ echo ========linking dynamic lib [$@] start========
    $(CXX) $(CFLAGS) -shared -Wl,-soname,$@ -o $@ /
        $(C_OBJ_FILES) $(CPP_OBJ_FILES) /
        $(patsubst %, -I%, $(INCLUDE_PATHS)) /
        -L$(APP_LIBRARY_PATH) $(USER_LIBS) $(COMMON_LIBS)
    @ echo ========linking dynamic lib [$@] done=========

$(EXEC_TARGET):$(C_OBJ_FILES) $(CPP_OBJ_FILES) $(USER_LIBS)
    @ echo ========linking exec [$@] start========
    $(CXX) $(CFLAGS) -o $@ /
        $(C_OBJ_FILES) $(CPP_OBJ_FILES) /
        $(patsubst %, -I%, $(INCLUDE_PATHS)) /
        -L$(APP_LIBRARY_PATH) $(USER_LIBS) $(COMMON_LIBS)
    @ echo ========linking exec [$@] done=========

.PHONY:staticlib
staticlib:$(STATIC_LIB_TARGET)

.PHONY:dynamiclib
dynamiclib:$(DYNAMIC_LIB_TARGET)

.PHONY:exec
exec:$(EXEC_TARGET)

CUR_FOLDER_NAME        = $(notdir $(shell pwd))

.PHONY:clean
clean:
    @ echo "clean dependent files [$(CUR_FOLDER_NAME)] start"
    $(RM) ./Obj $(STATIC_LIB_TARGET) $(DYNAMIC_LIB_TARGET) $(EXEC_TARGET)
    @ echo "clean dependent files [$(CUR_FOLDER_NAME)] done"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值