# # Makefile for utl Unit test # # Copyright (C) 2019-2020 Christos Choutouridis # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation, either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # # ========== Project settings ========== # Excecutable's name TARGET := utlTest # List(space seperated) of source directories # ex: # SRC_DIR_LIST := src1 /var/src2 ../src3 SRC_DIR_LIST := tests gtest # List(space seperated) of include directories # ex: # INC_DIR_LIST := inc /var/inc ../include2 INC_DIR_LIST := ../include gtest # List(space seperated) of exclude files (filenames only) # ex: # EXC_FILE_LIST := bad.cpp old.cpp EXC_FILE_LIST := # build directories BUILD_DIR := bin OBJ_DIR := $(BUILD_DIR)/obj DEP_DIR := $(BUILD_DIR)/.dep # ========== Compiler settings ========== CLANGXX := clang++ CLANGPP := clang++ -E GCCXX := g++ GCCPP := g++ -E CXX := $(GCCXX) CPP := $(GCCPP) CSIZE := size CFLAGS := -Wall -Wextra DEB_FLAGS := -DDEBUG -g3 REL_FLAGS := -O2 # example: LDFLAGS := -pthread -lm LDFLAGS := -pthread # example: MYCAB=1729 SUPER_MODE PRE_DEFS := MAP_FILE := $(BUILD_DIR)/output.map MAP_FLAG := -Xlinker -Map=$(MAP_FILE) # # =========== Main body and Patterns =========== # INC := $(foreach dir,$(INC_DIR_LIST),-I$(dir)) DEF := $(foreach def,$(PRE_DEFS),-D$(def)) EXC := $(foreach fil,$(EXC_FILE_LIST), \ $(foreach dir,$(SRC_DIR_LIST),$(wildcard $(dir)/$(fil))) \ ) # source files. object and dependencies list # recursive search into current and source directories SRC := $(wildcard *.cpp) SRC += $(foreach dir,$(SRC_DIR_LIST),$(wildcard $(dir)/*.cpp)) SRC += $(foreach dir,$(SRC_DIR_LIST),$(wildcard $(dir)/**/*.cpp)) SRC := $(abspath $(filter-out $(EXC),$(SRC))) OBJ := $(foreach file,$(SRC:%.cpp=%.o),$(OBJ_DIR)$(file)) DEP := $(foreach file,$(SRC:%.cpp=%.d),$(DEP_DIR)$(file)) # Make Dependencies pattern. # This little trick enables recompilation only when dependencies change # and it does so for changes both in source AND header files ;) # # It is based on Tom Tromey's method. # # Invoke cpp to create makefile rules with dependencies for each source file $(DEP_DIR)%.d: %.cpp @mkdir -p $(@D) @$(CPP) $(CFLAGS) $(INC) $(DEF) -MM -MT $(OBJ_DIR)$(<:.cpp=.o) -MF $@ $< # objects depent on .cpp AND dependency files, which have an empty recipe $(OBJ_DIR)%.o: %.cpp $(DEP_DIR)%.d @mkdir -p $(@D) $(CXX) -c $(CFLAGS) $(INC) $(DEF) -o $@ $< # empty recipe for dependency files. This prevents make errors $(DEP): # now include all dependencies # After all they are makefile dependency rules ;) include $(wildcard $(DEP)) # main target rule $(BUILD_DIR)/$(TARGET): $(OBJ) @mkdir -p $(@D) @echo Linking to target: $(TARGET) @echo $(CXX) $(LDFLAGS) $(MAP_FLAG) -o $(@D)/$(TARGET) '$$(OBJ)' @$(CXX) $(LDFLAGS) $(MAP_FLAG) -o $(@D)/$(TARGET) $(OBJ) @echo @echo Print size information @$(CSIZE) $(@D)/$(TARGET) @echo Done .PHONY: clean clean: @echo Cleaning build directories @rm -rf $(OBJ_DIR) @rm -rf $(DEP_DIR) @rm -rf $(BUILD_DIR) # # ============ User Rules ============= # .PHONY: gcc14 gcc14: CFLAGS += $(DEB_FLAGS) gcc14: CFLAGS += -std=c++14 gcc14: $(BUILD_DIR)/$(TARGET) .PHONY: gcc14_conc gcc14_conc: CFLAGS += $(DEB_FLAGS) gcc14_conc: CFLAGS += -std=c++14 -fconcepts gcc14_conc: $(BUILD_DIR)/$(TARGET) .PHONY: gcc17 gcc17: CFLAGS += $(DEB_FLAGS) gcc17: CFLAGS += -std=c++17 gcc17: $(BUILD_DIR)/$(TARGET) .PHONY: gcc17_conc gcc17_conc: CFLAGS += $(DEB_FLAGS) gcc17_conc: CFLAGS += -std=c++17 -fconcepts gcc17_conc: $(BUILD_DIR)/$(TARGET) .PHONY: gcc2a gcc2a: CFLAGS += $(DEB_FLAGS) gcc2a: CFLAGS += -std=c++2a gcc2a: $(BUILD_DIR)/$(TARGET) .PHONY: clang14 clang14: CXX := $(CLANGXX) clang14: CPP := $(CLANGPP) clang14: CFLAGS += $(DEB_FLAGS) clang14: CFLAGS += -std=c++14 clang14: $(BUILD_DIR)/$(TARGET) .PHONY: clang17 clang14: CXX := $(CLANGXX) clang14: CPP := $(CLANGPP) clang14: CFLAGS += $(DEB_FLAGS) clang14: CFLAGS += -std=c++17 clang14: $(BUILD_DIR)/$(TARGET) .PHONY: clang2a clang14: CXX := $(CLANGXX) clang14: CPP := $(CLANGPP) clang14: CFLAGS += $(DEB_FLAGS) clang14: CFLAGS += -std=c++2a clang14: $(BUILD_DIR)/$(TARGET) .PHONY: debug debug: CFLAGS += $(DEB_FLAGS) debug: $(BUILD_DIR)/$(TARGET) .PHONY: release release: CFLAGS += $(REL_FLAGS) release: clean $(BUILD_DIR)/$(TARGET) .PHONY: all all: clean release