首先让我描述一下我的文件夹结构
| SourceCode folder
| | Build folder
| | | makefile
| | | buildrules.mak
| | Integration_Tests folder
| | | Subsystem_1_Test folder
| | | | buildfiles folder
| | | | test.cpp
| | | | makefile
| | Subsystem_1 folder
| | | buildfiles folder
| | | source1.cpp
| | | source2.cpp
| | | source3.cpp
| | | makefile
| | Subsystem_2 folder
| | | buildfiles folder
| | | source4.cpp
| | | source5.cpp
| | | source6.cpp
| | | makefile
因此 build 文件夹中的 makefile 将通过调用较低的 makefile 来构建所有子系统和集成测试。每个子系统创建一个可执行文件,每个子系统测试创建一个可执行文件。buildfiles 文件夹存储依赖文件、目标文件和最终的可执行代码。这些都是在构建时由 makefile 填充的。
集成测试是使用被测子系统代码构建的,并且也构建子系统,但在子系统文件夹中本地。每个子系统集成测试的 makefile 使用 vpath 来设置子系统文件夹的路径。即,对于子系统 1 测试,vpath 是:
vpath = ../../Subsystem_1
我面前没有确切的代码,但编译行基本上定义如下,它位于 buildrules.mak 中并被所有 makefile 使用
./buildfiles/%.o : %.cpp
compile the code
所以我看到的问题是当我构建集成测试时,虽然它在技术上应该构建和链接正常,但它似乎是在 Subsystem_1/buildfiles 文件夹中找到目标文件并说子系统代码已构建并且仅构建 test.cpp。
这是一个错误,因为测试已经定义了构建定义,它需要再次构建子系统以进行正确的测试。
现在,如果子系统 1 尚未构建,即没有目标文件,那么我的集成测试将按预期构建文件,将目标文件放入本地集成测试构建文件文件夹中。
我相信这是由于在集成测试 make 文件中设置了 vpath。似乎在 subsystem_1 文件夹中搜索目标文件并不幸找到了它们。
如果我正在构建 Subsystem_1 文件夹并且测试已经构建,我看不到任何问题,这可能是因为 Subsystem_1 中的 vpath 没有测试路径,它不应该。
我似乎无法弄清楚如何解决这个本质上是文件路径问题的问题。看来我需要更具体地说明我需要在编译行中匹配哪个 buildfiles 文件夹,但我没有路径。
我不能使用 $(CURDIR) 因为那是一个绝对路径,我被告知我必须使用相对路径。我猜路径有空格和括号存在问题。在使用它之前我可能会避开它们,但有人告诉我必须用相对路径来做所有事情。
我在 buildrules.mak 中有一个变量,它是从执行 make 的目录到 buildrules.mak 的相对路径。这是使用以下方法完成的:
BUILD_FOLDER_PATH := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
有没有办法解析 $(CURDIR) 让我进入像 sourcecod 这样的公共文件夹?然后可以做类似的事情:
$(BUILD_FOLDER_PATH)/../[path extracted from $(CURDIR)]/buildfiles
因此,如果 $(CURDIR) 是 c:/a/b/sourcecode/Integration_Tests/Subsystem_Test 那么我可以从中提取“/Integration_Tests/Subsystem_Test”以放入上述路径。
如果有其他方法可以做到这一点,我也愿意接受建议。
谢谢!
编辑:测试生成文件
# used when make is executed without any arguments, must be first thing in the file
all: default
##########################################################################
# #
# Source Files #
# #
##########################################################################
# These files are not shared with other processes
CPP_SRC := \
cmdclientmq.cpp \
cmdservermq.cpp \
ConvertUTF.cpp \
crcutil.cpp \
deka_cpu.cpp \
deka_debug.cpp \
deka_file.cpp \
deka_mutex.cpp \
deka_sem.cpp \
deka_serial.cpp \
deka_sharedMem.cpp \
deka_thread.cpp \
deka_time.cpp \
deka_timer.cpp \
encryptionutils.cpp \
exec_client.cpp \
logclient.cpp \
procstatus.cpp \
syserror.cpp
# These files are shared with other processes
EXPORTED_SRC :=
# These files are analyzed by the manifest tool
# Not all header files are listed because the manifest tool automatically checks if there is a .h file
# with the same name as a .cpp file
MANIFEST_SRC := \
$(CPP_SRC) \
$(EXPORTED_SRC)
##########################################################################
# #
# makefile includes #
# #
##########################################################################
# Basic compiler definitions, must be listed after source files
include ../../build/buildrules.mak
##########################################################################
# #
# build flags #
# #
##########################################################################
# Position Independent Code flag
GCC_FLAGS += -fPIC
##########################################################################
# #
# Subsystem build paths #
# #
##########################################################################
# directory include paths need for files external to the current subsystem
INCDIRS := \
$(EXECUTIVE_INC_PATH) \
$(LOGGER_INC_PATH) \
$(OS_INTERFACE_INC_PATH) \
$(SYSERROR_INC_PATH) \
$(SYSTEMDEFS_INC_PATH) \
$(UTILITIES_INC_PATH)
# list of directories in the current subsystem
VPATH := \
$(EXECUTIVE_PATH)/exec_client \
$(EXECUTIVE_PATH)/exec_core \
$(LOGGER_PATH)/main \
$(OS_INTERFACE_PATH) \
$(SYSERROR_PATH) \
$(UTILITIES_PATH)
##########################################################################
# #
# Targets #
# #
##########################################################################
# default target to build and link the subsystem code
default: $(LIB_DIR)/libpycommon.a
@echo
@echo Common Library default: Done.
@echo ----------------------------------------------------------------------------
@echo
# remove the subsystem build folders and create the neccessary directories
clean: REMOVE_INTEGRATION_DIRS CREATE_INTEGRATION_OUTPUT_DIRS
@echo
@echo Common Library clean: Done.
@echo ----------------------------------------------------------------------------
@echo
##########################################################################
# #
# Build Rules #
# #
##########################################################################
# Do not build archives or call ranlib in parallel:
# http://www.gnu.org/software/make/manual/make.html#Archive-Pitfalls
.NOTPARALLEL:
$(LIB_DIR)/libpycommon.a: $(LIB_DIR)/libpycommon.a($(CPP_OBJS))
$(RANLIB) $(LIB_DIR)/libpycommon.a
构建规则.mak
# get relative path to the current makefile by examining the $(MAKEFILE_LIST), which is
# dynamically updated. Determine the number of words in $(MAKEFILE_LIST) and grab the
# last word. Then extract the directory path up to the found last word.
# the include order is important, do not adjust
include $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))toolset.mak
include $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))common.mak
##########################################################################
# #
# Build rules for creating subsystem and project folder structure #
# #
##########################################################################
CREATE_SUBSYSTEM_OUTPUT_DIRS :
-@echo Creating directory: $(BUILD_PATH)
-@mkdir -p $(BUILD_PATH)
-@echo Creating directory: $(DEP_DIR)
-@mkdir -p $(DEP_DIR)
-@echo Creating directory: $(OBJ_DIR)
-@mkdir -p $(OBJ_DIR)
-@echo Creating directory: $(LINT_DIR)
-@mkdir -p $(LINT_DIR)
-@echo Creating directory: $(CCK_DIR)
-@mkdir -p $(CCK_DIR)
-@echo Creating directory: $(UNCRUST_DIR)
-@mkdir -p $(UNCRUST_DIR)
-@echo Creating directory: $(MET_DIR)
-@mkdir -p $(MET_DIR)
REMOVE_SUBSYSTEM_DIRS :
-@echo ----------------------------------------------------------------------------
-@echo Removing directory: $(BUILD_PATH)
-@echo ----------------------------------------------------------------------------
-@rm -rf $(BUILD_PATH)
-@echo
CREATE_PROJECT_OUTPUT_DIRS :
-@echo Creating directory: $(IMAGE_DIR)
-@mkdir -p $(IMAGE_DIR)
-@echo Creating directory: $(PROJECT_OBJ_DIR)
-@mkdir -p $(PROJECT_OBJ_DIR)
REMOVE_PROJECT_OUTPUT_DIRS :
-@echo Removing directory: $(DIALYSIS_DIR)
-@rm -rf $(DIALYSIS_DIR)
-@echo Removing directory: $(ETC_DIR)
-@rm -rf $(ETC_DIR)
-@echo Removing directory: $(IMAGE_DIR)
-@rm -rf $(IMAGE_DIR)
-@echo Removing directory: $(PROJECT_OBJ_DIR)
-@rm -rf $(PROJECT_OBJ_DIR)
-@echo Removing directory: $(TAR_DIR)
-@rm -rf $(TAR_DIR)
-@echo Removing directory: $(QUAL_DIR)
-@rm -rf $(QUAL_DIR)
-@echo Removing directory: $(PYTHON_OUT)
-@rm -rf $(PYTHON_OUT)
##########################################################################
# #
# Integration Build Rules #
# #
##########################################################################
CREATE_INTEGRATION_OUTPUT_DIRS :
-@echo Creating directory: $(BUILD_PATH)
-@mkdir -p $(BUILD_PATH)
-@echo Creating directory: $(DEP_DIR)
-@mkdir -p $(DEP_DIR)
-@echo Creating directory: $(OBJ_DIR)
-@mkdir -p $(OBJ_DIR)
-@echo Creating directory: $(LIB_DIR)
-@mkdir -p $(LIB_DIR)
-@echo Creating directory: $(PYTHON_OUT)
-@mkdir -p $(PYTHON_OUT)
REMOVE_INTEGRATION_DIRS :
@echo Removing directory: $(BUILD_PATH)
@rm -rf $(BUILD_PATH)
@echo
##########################################################################
# #
# Unit Test Build Rules #
# #
##########################################################################
CREATE_UNIT_TEST_OUTPUT_DIRS :
-@echo Creating directory: $(BUILD_PATH)
-@mkdir -p $(BUILD_PATH)
-@echo Creating directory: $(DEP_DIR)
-@mkdir -p $(DEP_DIR)
-@echo Creating directory: $(OBJ_DIR)
-@mkdir -p $(OBJ_DIR)
REMOVE_UNIT_TEST_DIRS :
@echo Removing directory: $(BUILD_PATH)
-@rm -rf $(BUILD_PATH)
@echo
##########################################################################
# #
# Create dependancy files from all cpp files #
# #
##########################################################################
# convert the file extensions from .o to .d and strip the relative path and add the dependancy path
DEP_OBJS = $(patsubst %.o, $(DEP_DIR)/%.d, $(Call_OBJ))
##########################################################################
# #
# Create object files from all cpp files #
# #
##########################################################################
# convert the file extensions from .cpp to .o
Cxx_OBJS = $(CPP_SRC:.cpp=.o)
# strip the relative path and add the object path
CPP_OBJS = $(patsubst %.o, $(OBJ_DIR)/%.o, $(Cxx_OBJS))
##########################################################################
# #
# Create object files from all exported files #
# #
##########################################################################
# Files needed by other subsystems
# convert the file extensions from .cpp to .o
Exx_OBJS = $(EXPORTED_SRC:.cpp=.o)
# strip the relative path and add the path to the subsystem object folder
EXPORTED_OBJ = $(patsubst %.o, $(OBJ_DIR)/%.o, $(Exx_OBJS))
# strip the relative path and add the project object folder
EXPORTED_OUT = $(patsubst %.o, $(PROJECT_OBJ_DIR)/%.o, $(Exx_OBJS))
##########################################################################
# #
# List of files within the subsystem #
# #
##########################################################################
# create the list of all files associated with this subsystem
Call_OBJ = $(Cxx_OBJS) $(Exx_OBJS)
##########################################################################
# #
# Files needed by Lint #
# #
##########################################################################
# convert the file extensions from .o to .lob and strip the relative path and add the lint path
LINT_OBJS = $(patsubst %.o, $(LINT_DIR)/%.lob, $(Call_OBJ))
##########################################################################
# #
# Interface Rules to create dependancy files from project source code #
# #
##########################################################################
# function used to create dependancy files
define DEPENDS_COMMAND
@echo
@echo ----------------------------------------------------------------------------
@echo -Depend: $@
@echo ----------------------------------------------------------------------------
@$(CC_DEP) -MM -MT '$(OBJ_DIR)/$*'.o $(INCDIRS) $< > $ $@.tmp
@$(SED) 's,\($*\)\.o[ :]*,\1.o $(LINT_DIR)/\1.lob $@ : ,g' < $@.tmp > $@;
@rm -f $@.tmp
endef
# rule to create dependency for C++ code
$(DEP_DIR)/%.d: %.cpp
$(DEPENDS_COMMAND)
##########################################################################
# #
# Interface Rules to compile project source code #
# #
##########################################################################
# function used to compile code
define COMPILE_COMMAND
@echo
@echo ----------------------------------------------------------------------------
@echo -Compiling: $@
@echo ----------------------------------------------------------------------------
@$(CC) $(CPU_GCC_FLAGS) $(GCC_FLAGS) $(INCDIRS) $< -o $@
endef
# build object files in subsytem ojbect folder for all cpp files
$(OBJ_DIR)/%.o: %.cpp
@$(COMPILE_COMMAND)
##########################################################################
# #
# Build exported object files and copy them to the build folder #
# #
##########################################################################
# move shared object files to the proper directory
$(EXPORTED_OUT): $(PROJECT_OBJ_DIR)/%.o : $(OBJ_DIR)/%.o
@echo
@echo Copying Shared File $< to $@ ...
@cp $< $@
##########################################################################
# #
# Build Rules to link files to create the final executable #
# #
##########################################################################
# Commands for linking final executable [LINK_DB_LIBS vs LINK_LIBS]
define LINK_EXECUTABLE
@echo
@echo "**********************************"
@echo "**** Linux Linking $@"
@echo "**********************************"
$(CC) $^ $(LINK_LIBS) $(LIB_FLAGS) -o $(IMAGE_DIR)/$@
@$(DEKA_TOOLS)/imagecrc.exe $(IMAGE_DIR)/$@ 2>&1
@echo
@echo LINK_EXECUTABLE Completed
@echo ----------------------------------------------------------------------------
endef
# Commands for linking final executable for subsystems using the database [LINK_DB_LIBS vs LINK_LIBS]
define LINK_DB_EXECUTABLE
@echo
@echo "********************************************"
@echo "**** Linux Linking $@"
@echo "********************************************"
@$(CC) $^ $(LINK_DB_LIBS) $(LIB_FLAGS) -o $(IMAGE_DIR)/$@
@$(DEKA_TOOLS)/imagecrc.exe $(IMAGE_DIR)/$@ 2>&1
@echo
@echo LINK_DB_EXECUTABLE Completed
@echo ----------------------------------------------------------------------------
endef
define LINK_EXECUTABLE_INTEGRATION
@echo
@echo "**********************************"
@echo "**** Linux Linking $@"
@echo "**********************************"
$(CC) $^ $(LINK_LIBS) $(LIB_FLAGS) -o $(PYTHON_OUT)/$@
@$(DEKA_TOOLS)/imagecrc.exe $(PYTHON_OUT)/$@ 2>&1
@echo ----------------------------------------------------------------------------
endef
define LINK_EXECUTABLE_UNIT_TEST
@echo
@echo "**********************************"
@echo "**** Linux Linking $@"
@echo "**********************************"
$(CC) $^ $(LINK_LIBS) $(LIB_FLAGS) $(CANTPP_LIB) -L$(GCC_LIB_PATH) -o $(OBJ_DIR_UT)/$@
@echo ----------------------------------------------------------------------------
endef
##########################################################################
# #
# Build rules for Lint of C++ files #
# #
##########################################################################
# function used to lint C++ files
define LINT_COMMAND
@echo
@echo ----------------------------------------------------------------------------
@echo -Lint: $<
@echo ----------------------------------------------------------------------------
-@$(LINT) -dRELEASE_BUILD -u -b $(LINT_SYS_DIRS) $(INCDIRS) $(LINT_RULES) '-passes(2)' '-oo($@)' '-os($(@D)/$(*F).txt)' $<
@$(PYTHON) $(LINT_PYTHON_SCRIPT) --out $(@D)/$(*F).txt --src $(CURDIR)/$<
endef
# rule to create lint output for C++ code
$(LINT_DIR)/%.lob: %.cpp
@$(LINT_COMMAND)
lint: $(LINT_OBJS)
@echo
@echo lint: Done.
@echo ----------------------------------------------------------------------------
lintclean:
@rm -rf $(LINT_DIR)
@mkdir $(LINT_DIR)
@echo
@echo lintclean: Done
@echo ----------------------------------------------------------------------------
##########################################################################
# #
# Build rules for Uncrustify of C++ files #
# #
##########################################################################
uncrustify: $(UNCRUST_DIR)
@python $(UNCRUST_PYTHON_FILE) $(UNCRUST_EXECUTABLE) -nooverwrite
@echo
@echo uncrustify: Done
@echo ----------------------------------------------------------------------------
uncrustifyclean:
@rm -rf $(UNCRUST_DIR)
@mkdir $(UNCRUST_DIR)
@echo
@echo uncrustifyclean: Done
@echo ----------------------------------------------------------------------------
##########################################################################
# #
# Build rules for Understand CodeCheck of C++ files #
# #
##########################################################################
codecheck.udb: $(CCK_DIR)
@echo
@cp -rf $(UND_RULES_ARCHIVE) $(UND_RULES)
@$(UND) create -db $@ -languages c++
@$(UND) -db $@ settings -c++MacrosAdd RELEASE_BUILD=1
@$(UND) add $(CURDIR) -db $@
-@$(UND) remove unittest -db $@
@$(UND) analyze -all -db $(CURDIR)/$@ > $(CCK_DIR)/analyze.log 2>&1
@$(UND) -db $(CURDIR)/$@ codecheck -html $(CCK_RULES_FILE) $(CCK_DIR) > $(CCK_DIR)/codecheck.log 2>&1
@$(UPERL) $(UND_PERL_SCRIPT) $(CURDIR) -db $@
@rm $@
@echo
@echo codecheck: Done
@echo ----------------------------------------------------------------------------
codecheckclean:
@rm -rf $(CCK_DIR)
@mkdir $(CCK_DIR)
@echo
@echo codecheckclean: Done
@echo ----------------------------------------------------------------------------
##########################################################################
# #
# Build rules for Metrics/Complexity of C++ files using Understand #
# #
##########################################################################
metric.udb: $(MET_DIR)
@echo
@$(UND) create -db $@ -languages c++
@$(UND) -db $@ settings -c++MacrosAdd RELEASE_BUILD=1
@$(UND) settings -metricsShowDeclaredInFile on -db $@
@$(UND) settings -metrics MaxNesting CyclomaticModified -db $@
@$(UND) add $(CURDIR) -db $@
-@$(UND) remove unittest -db $@
@$(UND) analyze -all -db $@ > $(UND_METRICS_LOG) 2>&1
@$(UND) metrics -db $@
-@mv -f metric.csv $(MET_DIR)/
@rm $@
@echo
@echo metrics: Done
@echo ----------------------------------------------------------------------------
metricclean:
@rm -rf $(MET_DIR)
@mkdir $(MET_DIR)
@echo
@echo metricclean: Done
@echo ----------------------------------------------------------------------------
##########################################################################
# #
# Build Rules to create a manifest of static analysis tool results #
# #
##########################################################################
manifestall: manifestclean uncrustifyclean lintclean codecheckclean metricclean uncrustify codecheck.udb metric.udb
@$(MAKE) -j $(NUMBER_OF_PROCESSORS) lint
@python $(MANIFEST_SCRIPT_LOCATION) --cpp $(MANIFEST_SRC) --searchpath $(VPATH)
@echo
@echo manifestall: Done
@echo ----------------------------------------------------------------------------
manifest:
@python $(MANIFEST_SCRIPT_LOCATION) --cpp $(MANIFEST_SRC) --searchpath $(VPATH)
@echo manifest: Done
@echo ----------------------------------------------------------------------------
manifestclean:
@rm -f $(CURDIR)/manifest.csv
@echo manifestclean: Done
@echo ----------------------------------------------------------------------------
##########################################################################
# #
# Build rules for PyLint of Python files #
# #
##########################################################################
# TODO in the future
# rule to create lint output for Python code
#$(PYLINT_DIR)/%.pylint: %.py
# @echo ----------------------------------------------
# @echo -PyLint: $<
# @echo ----------------------------------------------
# @$(PYTHON) $(PYLINT) --include-ids=y --rcfile=$(PYLINT_CONFIG) $< > $@
##########################################################################
# #
# Build rules for PEP8 (CodeCheck) of Python files #
# #
##########################################################################
# TODO in the future
# rule to create codecheck for Python code
#$(CCK_DIR)/%.pep8: %.py
# @echo ----------------------------------------------
# @echo PEP8: $<
# @echo ----------------------------------------------
# @$(PYTHON) $(PEP) --statistics --show-source --repeat $< > $@
##########################################################################
# #
# Dependancy File Creation #
# #
##########################################################################
# alwawys try to create a dependancy file unless $(MAKECMDGOALS) is one of the listed targets
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),lint)
ifneq ($(MAKECMDGOALS),lintclean)
ifneq ($(MAKECMDGOALS),uncrustify)
ifneq ($(MAKECMDGOALS),uncrustifyclean)
ifneq ($(MAKECMDGOALS),codecheck.udb)
ifneq ($(MAKECMDGOALS),codecheckclean)
ifneq ($(MAKECMDGOALS),metric.udb)
ifneq ($(MAKECMDGOALS),metricclean)
ifneq ($(MAKECMDGOALS),manifestall)
ifneq ($(MAKECMDGOALS),manifest)
ifneq ($(MAKECMDGOALS),manifestclean)
include $(DEP_OBJS)
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif