#--------- # # ComponentMakefile # # Include this file in your makefile # It makes # A static library # A test executable # # The necessary parameters are shown in # ComponentMakefileExampleParameters # # Inputs # SRC_FILES - Specific source files to build into library # SRC_DIRS - Directories of source files to build into the library # TEST_SRC - unit test code build into the unit test runner # MOCKS_SRC - mock objects built into the test runner # INCLUDES - List of -I files # CPPUTEST_CXXFLAGS - flags for the C++ compiler # CPPUTEST_CPPFLAGS - flags for the C++ AND C compiler # CPPUTEST_CFLAGS - C complier # CPPUTEST_LDFLAGS - Linker flags # LIB_DIR - the directory for the created library # COMPONENT_NAME - the name of the thing being created # OTHER_MAKEFILE_TO_INCLUDE - a hook to use this makefile to make # other targets. Like CSlim, which is part of fitnesse #---------- ifeq ("$(COMPONENT_NAME)", "") COMPONENT_NAME = name_this_in_the_makefile endif ifeq ("$(OBJS_DIR)", "") OBJS_DIR = objs endif ifeq ("$(LIB_DIR)", "") LIB_DIR = lib endif ifeq ("$CPPUTEST_USE_MALLOC_LEAK_DETECTION","") CPPUTEST_USE_MALLOC_LEAK_DETECTION = Y echo "leak on by default" endif #CPPUTEST_USE_OPERATOR_NEW_LEAK_DETECTION = Y #CXXFLAGS += -include $(CPPUTEST_HOME)/include/CppUTest/MemoryLeakDetectorNewMacros.h #CFLAGS += -include $(CPPUTEST_HOME)/include/CppUTest/MemoryLeakDetectorMallocMacros.h TARGET_LIB = \ $(LIB_DIR)/lib$(COMPONENT_NAME).a TEST_TARGET = \ $(COMPONENT_NAME)_tests #Helper Functions get_src_from_dir = $(wildcard $1/*.cpp) $(wildcard $1/*.c) get_dirs_from_dirspec = $(wildcard $1) get_src_from_dir_list = $(foreach dir, $1, $(call get_src_from_dir,$(dir))) src_to_o = $(subst .c,.o, $(subst .cpp,.o,$1)) src_to_d = $(subst .c,.d, $(subst .cpp,.d,$1)) change_o_file_location = $(patsubst %.o,$(OBJS_DIR)/%.o, $1) change_d_file_location = $(patsubst %.d,$(OBJS_DIR)/%.d, $1) src_to = $(subst .c,$1, $(subst .cpp,$1,$2)) #Derived STUFF_TO_CLEAN += $(TEST_TARGET) $(TEST_TARGET).exe $(TARGET_LIB) SRC += $(call get_src_from_dir_list, $(SRC_DIRS)) $(SRC_FILES) #OBJ = $(call src_to_o,$(SRC)) OBJ = $(call change_o_file_location, $(call src_to_o,$(SRC))) STUFF_TO_CLEAN += $(OBJ) TEST_SRC = $(call get_src_from_dir_list, $(TEST_SRC_DIRS)) #TEST_OBJS = $(call src_to_o,$(TEST_SRC)) TEST_OBJS = $(call change_o_file_location, $(call src_to_o,$(TEST_SRC))) STUFF_TO_CLEAN += $(TEST_OBJS) MOCKS_SRC = $(call get_src_from_dir_list, $(MOCKS_SRC_DIRS)) #MOCKS_OBJS = $(call src_to_o,$(MOCKS_SRC)) MOCKS_OBJS = $(call change_o_file_location, $(call src_to_o,$(MOCKS_SRC))) STUFF_TO_CLEAN += $(MOCKS_OBJS) ALL_SRC = $(SRC) $(TEST_SRC) $(MOCKS_SRC) #Test coverage with gcov GCOV_OUTPUT = gcov_output.txt GCOV_REPORT = gcov_report.txt GCOV_ERROR = gcov_error.txt GCOV_GCDA_FILES = $(call src_to,.gcda, $(ALL_SRC)) GCOV_GCNO_FILES = $(call src_to,.gcno, $(ALL_SRC)) TEST_OUTPUT = $(TEST_TARGET).txt STUFF_TO_CLEAN += \ $(GCOV_OUTPUT)\ $(GCOV_REPORT)\ $(GCOV_ERROR)\ $(GCOV_GCDA_FILES)\ $(GCOV_GCNO_FILES)\ $(TEST_OUTPUT) #Other stuff needed CPPUTEST_LIB = $(CPPUTEST_HOME)/lib/libCppUTest.a ifdef CPPUTEST_USE_EXTENSIONS CPPUTEST_LIB += $(CPPUTEST_HOME)/lib/libCppUTestExt.a endif CPPUTEST_CPPFLAGS += $(INCLUDES) $(GCOVFLAGS) #The gcda files for gcov need to be deleted before each run #To avoid annoying messages. GCOV_CLEAN = $(SILENCE)rm -f $(GCOV_GCDA_FILES) $(GCOV_OUTPUT) $(GCOV_REPORT) $(GCOV_ERROR) RUN_TEST_TARGET = $(SILENCE) $(GCOV_CLEAN) ; echo "Running $(TEST_TARGET)"; ./$(TEST_TARGET) $(CPPUTEST_EXE_FLAGS) ifneq "$(OTHER_MAKEFILE_TO_INCLUDE)" "" -include $(OTHER_MAKEFILE_TO_INCLUDE) endif ifneq "$(MAP_FILE)" "" CPPUTEST_LDFLAGS += -Wl,-map,$(MAP_FILE) endif INCLUDES_DIRS_EXPANDED = $(call get_dirs_from_dirspec, $(INCLUDE_DIRS)) INCLUDES += $(foreach dir, $(INCLUDES_DIRS_EXPANDED), -I$(dir)) MOCK_DIRS_EXPANDED = $(call get_dirs_from_dirspec, $(MOCKS_SRC_DIRS)) INCLUDES += $(foreach dir, $(MOCK_DIRS_EXPANDED), -I$(dir)) DEP_FILES = $(call src_to_d, $(ALL_SRC)) STUFF_TO_CLEAN += $(DEP_FILES) + $(PRODUCTION_CODE_START) + $(PRODUCTION_CODE_END) STUFF_TO_CLEAN += $(STDLIB_CODE_START) + $(MAP_FILE) + cpputest_*.xml junit_run_output # We'll use the CPPUTEST_CFLAGS etc so that you can override AND add to the CppUTest flags CFLAGS = $(CPPUTEST_CFLAGS) $(CPPUTEST_ADDITIONAL_CFLAGS) CPPFLAGS = $(CPPUTEST_CPPFLAGS) $(CPPUTEST_ADDITIONAL_CPPFLAGS) CXXFLAGS = $(CPPUTEST_CXXFLAGS) $(CPPUTEST_ADDITIONAL_CXXFLAGS) LDFLAGS = $(CPPUTEST_LDFLAGS) $(CPPUTEST_ADDITIONAL_LDFLAGS) # Targets .PHONY: all all: $(TEST_TARGET) $(RUN_TEST_TARGET) @echo "Component makefile is no longer supported, convert to MakefileInclude.mk" .PHONY: all_no_tests all_no_tests: $(TEST_TARGET) .PHONY: flags flags: $(SILENCE)echo Compile with these flags: $(SILENCE)for f in $(CPPFLAGS) ; do \ echo " C++ $$f" ; \ done $(SILENCE)for f in $(CFLAGS) ; do \ echo " C $$f" ; \ done $(SILENCE)for f in $(LDFLAGS) ; do \ echo " LD $$f" ; \ done $(SILENCE)for f in $(ARFLAGS) ; do \ echo " AR $$f" ; \ done $(TEST_TARGET): $(TEST_OBJS) $(MOCKS_OBJS) $(PRODUCTION_CODE_START) $(TARGET_LIB) $(USER_LIBS) $(PRODUCTION_CODE_END) $(CPPUTEST_LIB) $(STDLIB_CODE_START) $(SILENCE)echo Linking $@ $(SILENCE)$(LINK.o) -o $@ $^ $(LD_LIBRARIES) $(TARGET_LIB): $(OBJ) $(SILENCE)echo Building archive $@ $(SILENCE)mkdir -p lib $(SILENCE)$(AR) $(ARFLAGS) $@ $^ $(SILENCE)$(RANLIB) $@ test: $(TEST_TARGET) $(RUN_TEST_TARGET) | tee $(TEST_OUTPUT) vtest: $(TEST_TARGET) $(RUN_TEST_TARGET) -v | tee $(TEST_OUTPUT) $(OBJS_DIR)/%.o: %.cpp @echo compiling $(notdir $<) $(SILENCE)mkdir -p $(dir $@) $(SILENCE)$(COMPILE.cpp) -M -MF $(subst .o,.d,$@) -MT "$@ $(subst .o,.d,$@)" $< $(SILENCE)$(COMPILE.cpp) $(OUTPUT_OPTION) $< $(OBJS_DIR)/%.o: %.c @echo compiling $(notdir $<) $(SILENCE)mkdir -p $(dir $@) $(SILENCE)$(COMPILE.c) -M -MF $(subst .o,.d,$@) -MT "$@ $(subst .o,.d,$@)" $< $(SILENCE)$(COMPILE.c) $(OUTPUT_OPTION) $< ifneq "$(MAKECMDGOALS)" "clean" -include $(DEP_FILES) endif .PHONY: clean clean: $(SILENCE)echo Making clean $(SILENCE)$(RM) $(STUFF_TO_CLEAN) $(SILENCE)find . -name "*.gcov" | xargs rm -f $(SILENCE)find . -name "*.[do]" | xargs rm -f gcov: test $(SILENCE)for d in $(SRC_DIRS) ; do \ gcov -o $$d $$d/*.c $$d/*.cpp >> $(GCOV_OUTPUT) 2>>$(GCOV_ERROR) ; \ done $(CPPUTEST_HOME)/scripts/filterGcov.sh $(GCOV_OUTPUT) $(GCOV_ERROR) $(GCOV_REPORT) $(TEST_OUTPUT) cat $(GCOV_REPORT) .PHONY: format format: $(CPPUTEST_HOME)/scripts/reformat.sh $(PROJECT_HOME_DIR) debug: echo Stuff to clean $(SILENCE)for f in $(STUFF_TO_CLEAN) ; do \ echo "$$f" ; \ done echo Includes $(SILENCE)for i in $(INCLUDES) ; do \ echo "$$i" ; \ done