1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
#---------
#
# 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
|