手工制作庞大的c ++项目makefile

时间:2016-06-03 17:17:18

标签: c++ makefile generic-programming

我使用CODEO(Eclipse + overlay)为ELinOS RTOS构建应用程序。 事实是,我失去了使用eclipse CDT自动生成Makefile的能力,我生成了一个通用的Makefile。

我没有输入这个巨大的Makefile(很多很多的包含和源目录),而是尝试使用addprefix patsubst和一些wildcard,但这并没有成功,主要是因为我吮吸通用makefile!

关于图书馆,只使用了少数图书馆,所以我会手工编写。

以下是我的代码的结构。

Top directory
|
---> common ---> inc/
|                src/
---> pack_AAA ---> comp_AAA ---> inc/
|            |                   src/
|            ----> comp_AAB ---> inc/
|                                src/
---> comp_BBB ---> inc/
|                  src/
---> main.cpp

我只想枚举热门文件夹(commonpack_AAAcomp_BBB等等,主要是因为不是每个TOP文件夹都必须编译,我的{ {1}}位于其中一个顶级文件夹中)。 下面是可变数量的子目录。叶子总是Makefile(。hpp文件)和inc/(如你所猜,.cpp文件)文件夹。

此外,TOP文件夹的数量不会改变,所以我介意声明它们,但子文件夹会。

对象文件可以在任何他们想要的位置(单独的顶级src/目录,在build/ ...内),只要生成的可执行文件,我们称之为src/即可在顶级目录

提前致谢!

SOKS

这是我必须以

开头的生成的makefile
HUGE_PROJECT

1 个答案:

答案 0 :(得分:0)

这是我最终的Makefile。 我不得不隐藏组件名称。

#Executables
RM := rm -rf
CXX=YOUR_CXX_COMPILER
CC=YOUR_CC_COMPILER

PROG=YOUR_PROGRAM

#Root directory of your program (all files should be in it)
ROOT_DIR := ../../

#####################################

########################################
#      Define here all directories     #
#   containing src/ and inc/ folders   #
########################################

#pack_AAA folders
#Modules containing both src/ and inc/.
AAA_MODULES         := moduleA moduleB
#Modules with an include folder only + module with both
AAA_DIRS_INC        := moduleD moduleEF $(AAA_MODULES)

#pack_BBB modules list
BBB_MODULES         := comp_A comp_B comp_C comp_B/comp_D comp_B/comp_E

MMM_MODULES     := comp_F comp_G comp_H

PPP_MODULES     := . I

CCC_MODULES     := J comp_K comp_L \
                    comp_L/comp_M \ 
                    $(addprefix pack_BBB/,$(BBB_MODULES)) \
                    $(addprefix pack_MMM/,$(MMM_MODULES)) \
                    $(addprefix comp_PPP/,$(PPP_MODULES))

#pack_DDD
DDD_MODULES         := M comp_N comp_N/comp_O

#comp_EEE
EEE_MODULES     := . P Q

OTHER_MODULES       := R S comp_T

#All folders containing src/ subdir
SRC_MODULES         := $(OTHER_MODULES) \
                    $(addprefix comp_EEE/,$(EEE_MODULES)) \
                    $(addprefix pack_DDD/,$(DDD_MODULES)) \
                    $(addprefix pack_AAA/,$(AAA_MODULES)) \
                    $(addprefix pack_CCC/, $(CCC_MODULES))

#All folders containing inc/ subdir
INCLUDE_MODULES     := $(OTHER_MODULES) \
                    $(addprefix comp_EEE/,$(EEE_MODULES)) \
                    $(addprefix pack_DDD/,$(DDD_MODULES)) \
                    $(addprefix pack_AAA/,$(AAA_DIRS_INC)) \
                    $(addprefix pack_CCC/, $(CCC_MODULES))

#####################################

#WRAPPERS
ROOT_DIR_WRAPPERS       := $(ROOT_DIR)../WRAPPERS/

LIST_WRAPPERS           := WA WB WC WD

SRC_WRAPPERS            := $(addprefix pack_Wrappers/csc_Wrapper,$(LIST_WRAPPERS))

#DRIVERS
LIST_DRIVERS            := DA DB DC DD
DIR_DRIVERS             := $(addprefix pack_Drivers/csc_Driver,$(LIST_DRIVERS))

SRC_DIRS_WRAPPERS       := $(addsuffix /src,$(SRC_WRAPPERS))

INCLUDE_DIRS_WRAPPERS   := $(addsuffix /inc,$(SRC_WRAPPERS)) \
                            $(addsuffix /inc,$(DIR_DRIVERS)) \
                            Common


#####################################
#LIB_1 INCLUDE
ROOT_DIR_LIB_1          := $(ROOT_DIR)../../ObjetsCompiles/LIB_1/
INCLUDE_DIRS_LIB_1      := dir1 dir2 dir3

#####################################
#LIB_2 INCLUDE
ROOT_DIR_LIB_2      := $(ROOT_DIR)../../ObjetsCompiles/LIB_2/include
INCLUDE_DIRS_LIB_2  := . dir1 dir2 dir3/subdir dir4


#####################################
#Add "." to find main.cpp
SRC_DIRS        := $(addsuffix /src,$(SRC_MODULES)) .
INCLUDE_DIRS_SRC:= $(addsuffix /inc,$(INCLUDE_MODULES)) pack_ZZZ/comp_Without_Inc_Folder

#All include dirs, LIB_1 + LIB_2
INCLUDE_DIRS    := $(addprefix -I$(ROOT_DIR),$(INCLUDE_DIRS_SRC)) \
                    $(addprefix -I$(ROOT_DIR_LIB_1),$(INCLUDE_DIRS_LIB_1)) \
                    $(addprefix -I$(ROOT_DIR_LIB_2),$(INCLUDE_DIRS_LIB_2))

INCLUDE_DIRS_CC := $(addprefix -I$(ROOT_DIR_WRAPPERS),$(INCLUDE_DIRS_WRAPPERS)) \
                    $(addprefix -I$(ROOT_DIR_LIB_2),$(INCLUDE_DIRS_LIB_2))

#All objects (all .cpp & all .c)
OBJS            := $(foreach dir,$(SRC_DIRS), \
                    $(patsubst %.cpp,%.o,$(wildcard $(ROOT_DIR)$(dir)/*.cpp))) \
                    $(foreach dirs,$(SRC_DIRS_WRAPPERS), \
                    $(patsubst %.c,%.o,$(wildcard $(ROOT_DIR_WRAPPERS)$(dirs)/*.c)))

#All dependencies (same list as OBJS)
DEPS            := $(foreach dir,$(SRC_DIRS), \
                    $(patsubst %.cpp,%.d,$(wildcard $(ROOT_DIR)$(dir)/*.cpp))) \
                    $(foreach dirs,$(SRC_DIRS_WRAPPERS), \
                    $(patsubst %.c,%.d,$(wildcard $(ROOT_DIR_WRAPPERS)$(dirs)/*.c)))

#Exclude files from build
#Win32 socket files + some misc
EXCLUDED_FILES_LIST     := pack_AAA/comp_BBB/src/SocketWindowsOnLinuxForExample.cpp \
                        pack_BBB/comp_CCC/src/SomeOtherThingForWindows.cpp
EXCLUDED_FILES_PATH     := $(addprefix $(ROOT_DIR),$(EXCLUDED_FILES_LIST))

#Remove some objects (compilation is done, but no link)
EXCLUDED_OBJS   := $(patsubst %.cpp,%.o,$(EXCLUDED_FILES_PATH))
EXCLUDED_DEPS   := $(patsubst %.cpp,%.d,$(EXCLUDED_FILES_PATH))

#Update OBJS & DEPS list with excluded files
OBJS := $(filter-out $(EXCLUDED_OBJS),$(OBJS))
DEPS := $(filter-out $(EXCLUDED_DEPS),$(DEPS))

#FLAGS for DEBUG and RELEASE compilation
CPPFLAGS    := -D__CPPFLAG1__ -D__CPPFLAG2__
CFLAGS_D    := -O0 -g2 -Wall -c -fmessage-length=0
CXXFLAGS_D  := -O0 -g2 -Wall -c -fmessage-length=0 -m32 -mcpu=powerpc -Winline
CFLAGS_R    := -O2 -g0 -Wall -c -fmessage-length=0
CXXFLAGS_R  := -O2 -g0 -Wall -c -fmessage-length=0 -m32 -mcpu=powerpc -Winline

# L
LD_PATH     := -L../../path_library_1 -L../../path_library_2
LD_LIBS     := -lpthread_rt -lROHC -lpthread -lnative -lrtdm -lrt
MAP         := $(PROG).map
# -s (to strip)
LD_FLAGS_D  := -Wl,--wrap,pthread_create -Wl,--wrap,pthread_kill -Wl,-Map,$(MAP)
LD_FLAGS_R  := -s -Wl,--wrap,pthread_create -Wl,--wrap,pthread_kill -Wl,-Map,$(MAP)

##################################################
#TARGETS

default: release

#Debug flags (-00 + -g2)
debug: CFLAGS       := $(CFLAGS_D)
debug: CXXFLAGS     := $(CXXFLAGS_D)
debug: LD_FLAGS     := $(LD_FLAGS_D)
debug: all

#Release flags (-s + -02 + -g0)
release: CFLAGS     := $(CFLAGS_R)
release: CXXFLAGS   := $(CXXFLAGS_R)
release: LD_FLAGS   := $(LD_FLAGS_R)
release: all

all: $(PROG)

# Tool invocations
$(PROG): $(OBJS)
    @echo 'Building target: $@'
    @$(CXX)  $(LD_FLAGS) $(LD_PATH) -o "$(PROG)" $(OBJS) $(LD_LIBS)
    @echo 'Finished building target: $@'
    @echo ' '

# CXX compiler used by most of the code
%.o: %.cpp
    @echo 'Building file: $<'
    @$(CXX) $(CPPFLAGS) $(INCLUDE_DIRS) $(CXXFLAGS) -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"

# CC compiler used by Wrappers only
%.o: %.c
    @echo 'Building file: $<'
    @$(CC) $(INCLUDE_DIRS_CC) $(CFLAGS) -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"

# Other Targets
clean:
    -$(RM) $(OBJS) $(DEPS) $(PROG) $(MAP)
    -@echo ' '

.PHONY: all clean dependents
.SECONDARY: