summaryrefslogtreecommitdiff
path: root/tmk_core/rules.mk
diff options
context:
space:
mode:
authorStephen Christie <undersampled@live.com>2016-08-02 22:51:30 -0400
committerStephen Christie <undersampled@live.com>2016-08-02 22:51:30 -0400
commitbf2b260429dbc015d49d005065a37441c8f15753 (patch)
treeff87f04b747ce54870e8fb2a56af205079f9415c /tmk_core/rules.mk
parent0acb394ac41f56895d4287d950a79bca5437a45c (diff)
parent79a9e04706919b4cc684f9ee9420ef38470bcd66 (diff)
Merge branch 'master' of http://github.com/jackhumbert/qmk_firmware
Diffstat (limited to 'tmk_core/rules.mk')
-rw-r--r--tmk_core/rules.mk140
1 files changed, 87 insertions, 53 deletions
diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk
index f13351ea19..d2350f27c1 100644
--- a/tmk_core/rules.mk
+++ b/tmk_core/rules.mk
@@ -15,6 +15,16 @@
# Carlos Lamas
#
+# Enable vpath seraching for source files only
+# Without this, output files, could be read from the wrong .build directories
+VPATH_SRC := $(VPATH)
+vpath %.c $(VPATH_SRC)
+vpath %.h $(VPATH_SRC)
+vpath %.cpp $(VPATH_SRC)
+vpath %.hpp $(VPATH_SRC)
+vpath %.S $(VPATH_SRC)
+VPATH :=
+
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
@@ -35,11 +45,6 @@ ifeq ($(COLOR),true)
BOLD=\033[1m
endif
-ifdef quick
- QUICK = $(quick)
-endif
-
-QUICK ?= false
AUTOGEN ?= false
ifneq ($(shell awk --version 2>/dev/null),)
@@ -60,9 +65,9 @@ TAB_LOG = printf "\n$$LOG\n\n" | $(AWK) '{ sub(/^/," | "); print }'
TAB_LOG_PLAIN = printf "$$LOG\n"
AWK_STATUS = $(AWK) '{ printf " %-10s\n", $$1; }'
AWK_CMD = $(AWK) '{ printf "%-99s", $$0; }'
-PRINT_ERROR = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG) && false
+PRINT_ERROR = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG) && exit 1
PRINT_WARNING = ($(SILENT) || printf " $(WARN_STRING)" | $(AWK_STATUS)) && $(TAB_LOG)
-PRINT_ERROR_PLAIN = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG_PLAIN) && false && break
+PRINT_ERROR_PLAIN = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG_PLAIN) && exit 1
PRINT_WARNING_PLAIN = ($(SILENT) || printf " $(WARN_STRING)" | $(AWK_STATUS)) && $(TAB_LOG_PLAIN)
PRINT_OK = $(SILENT) || printf " $(OK_STRING)" | $(AWK_STATUS)
BUILD_CMD = LOG=$$($(CMD) 2>&1) ; if [ $$? -gt 0 ]; then $(PRINT_ERROR); elif [ "$$LOG" != "" ] ; then $(PRINT_WARNING); else $(PRINT_OK); fi;
@@ -71,7 +76,7 @@ BUILD_CMD = LOG=$$($(CMD) 2>&1) ; if [ $$? -gt 0 ]; then $(PRINT_ERROR); elif [
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
-EXTRAINCDIRS += $(subst :, ,$(VPATH))
+EXTRAINCDIRS += $(subst :, ,$(VPATH_SRC))
# Compiler flag to set the C Standard level.
@@ -253,6 +258,14 @@ MSG_SUBMODULE_DIRTY = $(WARN_COLOR)WARNING:$(NO_COLOR)\n \
# Define all object files.
OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(patsubst %.cpp,$(OBJDIR)/%.o,$(patsubst %.S,$(OBJDIR)/%.o,$(SRC))))
+# The files in the lib folder are shared between all keymaps, so generate that folder name by removing
+# the keymap from the name
+KBOBJDIR=$(subst _$(KEYMAP),,$(OBJDIR))
+# And fixup the object files to match
+LIBOBJ = $(foreach v,$(OBJ),$(if $(findstring /lib/,$v),$v))
+NONLIBOBJ := $(filter-out $(LIBOBJ),$(OBJ))
+LIBOBJ := $(subst _$(KEYMAP)/,/,$(LIBOBJ))
+OBJ := $(LIBOBJ) $(NONLIBOBJ)
# Define all listing files.
LST = $(patsubst %.c,$(OBJDIR)/%.lst,$(patsubst %.cpp,$(OBJDIR)/%.lst,$(patsubst %.S,$(OBJDIR)/%.lst,$(SRC))))
@@ -260,22 +273,21 @@ LST = $(patsubst %.c,$(OBJDIR)/%.lst,$(patsubst %.cpp,$(OBJDIR)/%.lst,$(patsubst
# Compiler flags to generate dependency files.
#GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
-GENDEPFLAGS = -MMD -MP -MF $(BUILD_DIR)/.dep/$(subst /,_,$(subst $(BUILD_DIR)/,,$@)).d
+GENDEPFLAGS = -MMD -MP -MF $(patsubst %.o,%.td,$@)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
# You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar
-ALL_CFLAGS = $(MCUFLAGS) $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
-ALL_CPPFLAGS = $(MCUFLAGS) -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
+ALL_CFLAGS = $(MCUFLAGS) $(CFLAGS) $(EXTRAFLAGS)
+ALL_CPPFLAGS = $(MCUFLAGS) -x c++ $(CPPFLAGS) $(EXTRAFLAGS)
ALL_ASFLAGS = $(MCUFLAGS) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)
+MOVE_DEP = mv -f $(patsubst %.o,%.td,$@) $(patsubst %.o,%.d,$@)
+
# Default target.
all: build sizeafter
-# Quick make that doesn't clean
-quick: build sizeafter
-
# Change the build target to build a HEX file or a library.
build: elf hex
#build: elf hex eep lss sym
@@ -365,25 +377,67 @@ BEGIN = gccversion check_submodule sizebefore
# Link: create ELF output file from object files.
.SECONDARY : $(BUILD_DIR)/$(TARGET).elf
.PRECIOUS : $(OBJ)
-%.elf: $(OBJ) | $(BEGIN)
+# Note the obj.txt depeendency is there to force linking if a source file is deleted
+%.elf: $(OBJ) $(OBJDIR)/cflags.txt $(OBJDIR)/ldflags.txt $(OBJDIR)/obj.txt | $(BEGIN)
@$(SILENT) || printf "$(MSG_LINKING) $@" | $(AWK_CMD)
- $(eval CMD=$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS))
+ $(eval CMD=$(CC) $(ALL_CFLAGS) $(filter-out %.txt,$^) --output $@ $(LDFLAGS))
@$(BUILD_CMD)
+define GEN_OBJRULE
# Compile: create object files from C source files.
-$(OBJDIR)/%.o : %.c | $(BEGIN)
- @mkdir -p $(@D)
- @$(SILENT) || printf "$(MSG_COMPILING) $<" | $(AWK_CMD)
- $(eval CMD=$(CC) -c $(ALL_CFLAGS) $< -o $@)
- @$(BUILD_CMD)
+$1/%.o : %.c $1/%.d $1/cflags.txt $1/compiler.txt | $(BEGIN)
+ @mkdir -p $$(@D)
+ @$$(SILENT) || printf "$$(MSG_COMPILING) $$<" | $$(AWK_CMD)
+ $$(eval CMD=$$(CC) -c $$(ALL_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
+ @$$(BUILD_CMD)
# Compile: create object files from C++ source files.
-$(OBJDIR)/%.o : %.cpp | $(BEGIN)
- @mkdir -p $(@D)
- @$(SILENT) || printf "$(MSG_COMPILING_CPP) $<" | $(AWK_CMD)
- $(eval CMD=$(CC) -c $(ALL_CPPFLAGS) $< -o $@)
+$1/%.o : %.cpp $1/%.d $1/cppflags.txt $1/compiler.txt | $(BEGIN)
+ @mkdir -p $$(@D)
+ @$$(SILENT) || printf "$$(MSG_COMPILING_CPP) $$<" | $$(AWK_CMD)
+ $$(eval CMD=$$(CC) -c $$(ALL_CPPFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
@$(BUILD_CMD)
+# Assemble: create object files from assembler source files.
+$1/%.o : %.S $1/asflags.txt $1/compiler.txt | $(BEGIN)
+ @mkdir -p $$(@D)
+ @$(SILENT) || printf "$$(MSG_ASSEMBLING) $$<" | $$(AWK_CMD)
+ $$(eval CMD=$$(CC) -c $$(ALL_ASFLAGS) $$< -o $$@)
+ @$$(BUILD_CMD)
+
+$1/force:
+
+$1/cflags.txt: $1/force
+ echo '$$(ALL_CFLAGS)' | cmp -s - $$@ || echo '$$(ALL_CFLAGS)' > $$@
+
+$1/cppflags.txt: $1/force
+ echo '$$(ALL_CPPFLAGS)' | cmp -s - $$@ || echo '$$(ALL_CPPFLAGS)' > $$@
+
+$1/asflags.txt: $1/force
+ echo '$$(ALL_ASFLAGS)' | cmp -s - $$@ || echo '$$(ALL_ASFLAGS)' > $$@
+
+$1/ldflags.txt: $1/force
+ echo '$$(LDFLAGS)' | cmp -s - $$@ || echo '$$(LDFLAGS)' > $$@
+
+$1/obj.txt: $1/force
+ echo '$$(OBJ)' | cmp -s - $$@ || echo '$$(OBJ)' > $$@
+
+$1/compiler.txt: $1/force
+ $$(CC) --version | cmp -s - $$@ || $$(CC) --version > $$@
+endef
+
+# We have to use static rules for the .d files for some reason
+DEPS = $(patsubst %.o,%.d,$(OBJ))
+# Keep the .d files
+.PRECIOUS: $(DEPS)
+# Empty rule to force recompilation if the .d file is missing
+$(DEPS):
+
+# Since the object files could be in two different folders, generate
+# separate rules for them, rather than having too generic rules
+$(eval $(call GEN_OBJRULE,$(OBJDIR)))
+$(eval $(call GEN_OBJRULE,$(KBOBJDIR)))
+
# Compile: create assembler files from C source files.
%.s : %.c | $(BEGIN)
@$(SILENT) || printf "$(MSG_ASSEMBLING) $<" | $(AWK_CMD)
@@ -396,19 +450,15 @@ $(OBJDIR)/%.o : %.cpp | $(BEGIN)
$(eval CMD=$(CC) -S $(ALL_CPPFLAGS) $< -o $@)
@$(BUILD_CMD)
-# Assemble: create object files from assembler source files.
-$(OBJDIR)/%.o : %.S | $(BEGIN)
- @mkdir -p $(@D)
- @$(SILENT) || printf "$(MSG_ASSEMBLING) $<" | $(AWK_CMD)
- $(eval CMD=$(CC) -c $(ALL_ASFLAGS) $< -o $@)
- @$(BUILD_CMD)
-
# Create preprocessed source for use in sending a bug report.
%.i : %.c | $(BEGIN)
$(CC) -E -mmcu=$(MCU) $(CFLAGS) $< -o $@
# Target: clean project.
-clean:
+clean:
+ $(REMOVE) -r $(OBJDIR) 2>/dev/null
+ $(REMOVE) -r $(KBOBJDIR) 2>/dev/null
+ $(REMOVE) $(BUILD_DIR)/$(TARGET).*
show_path:
@echo VPATH=$(VPATH)
@@ -428,7 +478,6 @@ all-keyboards-defaults: all-keyboards-defaults-all
KEYBOARDS := $(SUBDIRS:$(TOP_DIR)/keyboards/%/=/keyboards/%)
all-keyboards-all: $(addsuffix -all,$(KEYBOARDS))
-all-keyboards-quick: $(addsuffix -quick,$(KEYBOARDS))
all-keyboards-clean: $(addsuffix -clean,$(KEYBOARDS))
all-keyboards: all-keyboards-all
@@ -445,12 +494,10 @@ done
endef
define make_keyboard_helper
-# Just remove the -quick, -all and so on from the first argument and pass it forward
+# Just remove the -all and so on from the first argument and pass it forward
$(call make_keyboard,$(subst -$2,,$1),$2)
endef
-/keyboards/%-quick:
- $(call make_keyboard_helper,$@,quick)
/keyboards/%-all:
$(call make_keyboard_helper,$@,all)
/keyboards/%-clean:
@@ -468,32 +515,19 @@ all-keymaps-%:
all-keymaps: all-keymaps-all
-GOAL=$(MAKECMDGOALS)
-ifeq ($(MAKECMDGOALS),)
-GOAL = all
-endif
-CLEANING_GOALS=clean clean_list all
-ifneq ($(findstring $(GOAL),$(CLEANING_GOALS)),)
-$(shell $(REMOVE) -r $(BUILD_DIR) 2>/dev/null)
-$(shell $(REMOVE) -r $(TOP_DIR)/$(BUILD_DIR))
-$(shell $(REMOVE) -r $(KEYBOARD_PATH)/$(BUILD_DIR))
-$(shell if $$SUBPROJECT; then $(REMOVE) -r $(SUBPROJECT_PATH)/$(BUILD_DIR); fi)
-$(shell $(REMOVE) -r $(KEYMAP_PATH)/$(BUILD_DIR))
-endif
-
# Create build directory
$(shell mkdir $(BUILD_DIR) 2>/dev/null)
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
-
+$(shell mkdir $(KBOBJDIR) 2>/dev/null)
# Include the dependency files.
--include $(shell mkdir $(BUILD_DIR)/.dep 2>/dev/null) $(wildcard $(BUILD_DIR)/.dep/*)
+-include $(patsubst %.o,%.d,$(OBJ))
# Listing of phony targets.
-.PHONY : all quick finish sizebefore sizeafter gccversion \
+.PHONY : all finish sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff check_submodule \
clean clean_list debug gdb-config show_path \
program teensy dfu flip dfu-ee flip-ee dfu-start \