-include $(PROJ) ####### Cross-platform settings ifneq (,$(findstring Windows,$(PATH))) UNAME := Windows TARGET_EXT := .exe DEL := del /q SEPERATOR := $(subst /,\,/) MKDIR = if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1)) else UNAME := $(shell uname -s) TARGET_EXT := # LFLAGS := -Wl,-s LFLAGS := DEL := rm SEPERATOR := / MKDIR = mkdir -p $(1) endif ####### Output directory TARGET_DIR = bin TEMP_DIR = build/objs TARGET_BIN = $(TARGET_DIR)/$(TARGET)$(TARGET_EXT) TARGET_DIR = bin # TODO: This is a hack to put the tags file in the parent directory so # vim can find it when looking at the toolkit code. Probably projects # should have a project root, something like PROJECT_ROOT= PROJECT_ROOT = .. TAGS_FILE = $(PROJECT_ROOT)/tags PROJ_FILE = $(PROJECT_ROOT)/proj ####### Compiler, tools and commands CC = gcc CXX = g++ LINK = g++ STRIP = strip TAGS = ctags ####### Command parameters # CFLAGS = -MMD -O0 -Wall $(DEFINES) $(INCLUDES) CFLAGS = -MMD -Wall $(DEFINES) $(FLAGS) $(INCLUDES) # CXXFLAGS = -fno-exceptions -fno-rtti $(CFLAGS) CXXFLAGS = $(CFLAGS) LINKFLAGS = $(LFLAGS) STRIPFLAGS = -SXTnx ####### Intermediate files INCLUDES = $(patsubst %,-I%,$(SEARCH_PATHS)) OBJECTS = $(patsubst %.cpp,$(TEMP_DIR)/%.o,$(filter %.cpp,$(SOURCES))) DEPENDS = $(patsubst %.o,%.d,$(OBJECTS)) PDFS = $(patsubst %.md,../docs/pdfs/%.pdf,$(DOCS)) ####### Build rules all: $(TAGS_FILE) $(TARGET_BIN) $(PDFS) .PHONY: clean targets project dependancies paths system_paths clean: $(DEL) $(subst /,$(SEPERATOR),$(OBJECTS) $(DEPENDS) $(TARGET_BIN)) ####### Implicit rules -include $(DEPENDS) .SUFFIXES: .cpp .c $(TEMP_DIR)/%.o : %.cpp $(call MKDIR,$(dir $@)) $(CXX) -c $(CXXFLAGS) -o $@ $< -MQ $@ -MQ $(TAGS_FILE) -MQ project $(TEMP_DIR)/%.o : %.c $(call MKDIR,$(dir $@)) $(CC) -c $(CFLAGS) -o $@ $< -MQ $@ -MQ $(TAGS_FILE) -MQ project ../docs/pdfs/%.pdf : ../docs/%.md mdpdf $< --header ../docs/tools/header.html --hHeight 55 mv $(basename $<).pdf $@ ####### Compile/Link rules $(TARGET_BIN): $(OBJECTS) $(call MKDIR,$(dir $@)) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) # $(TARGET_BIN) $(STRIP) $(STRIPFLAGS) $@ ####### Tags/Editor rules $(TAGS_FILE): @echo "Rebuilding tags" cscope -ub $^ $(TAGS) -f $@ --tag-relative=yes --sort=yes --c++-kinds=+p --fields=+iaS --extras=+q $^ $(PROJ_FILE): @$(MAKE) project > $@ define item_svn_status $(eval TMP := $(word 1,$(subst _, ,$(filter %$(abspath $F),$(SVN_ST)))))$(if $(TMP),$(TMP), ) endef define generate_tree_items @printf '$(2)' $(eval ITEMS := $(3)) $(eval LAST := $(if $(ITEMS),$(word $(words $(ITEMS)), $(ITEMS)),)) @printf '$(foreach F, $(ITEMS),\n$(1) $(if $(filter $F,$(LAST)),┗━,┣━)$(call item_svn_status) $(notdir $F)\t\t\t\t\t\t\t $(abspath $F))\n' endef project: $(eval SVN_ST := $(shell svn st `svn info --show-item wc-root` | tr ' ' '_')) $(call generate_tree_items,┃ ,┣━ Target, $(TARGET)) $(call generate_tree_items,┃ ,┃\n┣━ Sources, $(filter %.cpp,$^)) $(call generate_tree_items,┃ ,┃\n┣━ Includes, $(filter %.h,$^)) $(call generate_tree_items,┃ ,┃\n┣━ Docs, $(filter %.md,$(DOCS))) $(call generate_tree_items, ,┃\n┗━ Project, $(filter-out %.d,$(MAKEFILE_LIST))) paths: @printf '$(SEARCH_PATHS)' system_paths: @g++ -E -xc++ -v /dev/null 2>&1 | grep "^ /" | sed 's/\(.*\) (framework directory)/\1/g' | tr -d '\n' dependancies: @$(MAKE) project | sed -n 's/.* \(.*\)/\1/gp' targets: @$(MAKE) -p $(PROJ_FILE) | sed -n 's/^\([a-zA-Z0-9]*\):.*/\1/gp'