diff --git a/.gitignore b/.gitignore index 8491433524d..8c85d6ffa88 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ build/ .build/ *.bak .vagrant/ +quantum/version.h .idea/ CMakeLists.txt .DS_STORE @@ -26,4 +27,4 @@ CMakeLists.txt .project .settings/ .idea -.browse.VC.db* \ No newline at end of file +.browse.VC.db* diff --git a/.travis.yml b/.travis.yml index 26deac0cebc..297cf19a686 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ env: global: - secure: vBTSL34BDPxDilKUuTXqU4CJ26Pv5hogD2nghatkxSQkI1/jbdnLj/DQdPUrMJFDIY6TK3AltsBx72MaMsLQ1JO/Ou24IeHINHXzUC1FlS9yQa48cpxnhX5kzXNyGs3oa0qaFbvnr7RgYRWtmD52n4bIZuSuW+xpBv05x2OCizdT2ZonH33nATaHGFasxROm4qYZ241VfzcUv766V6RVHgL4x9V08warugs+RENVkfzxxwhk3NmkrISabze0gSVJLHBPHxroZC6EUcf/ocobcuDrCwFqtEt90i7pNIAFUE7gZsN2uE75LmpzAWin21G7lLPcPL2k4FJVd8an1HiP2WmscJU6U89fOfMb2viObnKcCzebozBCmKGtHEuXZo9FcReOx49AnQSpmESJGs+q2dL/FApkTjQiyT4J6O5dJpoww0/r57Wx0cmmqjETKBb5rSgXM51Etk3wO09mvcPHsEwrT7qH8r9XWdyCDoEn7FCLX3/LYnf/D4SmZ633YPl5gv3v9XEwxR5+04akjgnvWDSNIaDbWBdxHNb7l4pMc+WR1bwCyMyA7KXj0RrftEGOrm9ZRLe6BkbT4cycA+j77nbPOMcyZChliV9pPQos+4TOJoTzcK2L8yWVoY409aDNVuAjdP6Yum0R2maBGl/etLmIMpJC35C5/lZ+dUNjJAM= script: -- make all-keyboards-quick AUTOGEN=true +- make all-keyboards AUTOGEN=true addons: apt: packages: diff --git a/Makefile b/Makefile index 980ab26b220..053c8532af1 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,9 @@ endif .DEFAULT_GOAL := all space := $(subst ,, ) -starting_makefile := $(subst $(space),_SPACE_,$(abspath $(firstword $(MAKEFILE_LIST)))) -mkfile_path := $(subst $(space),_SPACE_,$(abspath $(lastword $(MAKEFILE_LIST)))) +ESCAPED_ABS_PATH = $(subst $(space),_SPACE_,$(abspath $1)) +starting_makefile := $(call ESCAPED_ABS_PATH,$(firstword $(MAKEFILE_LIST))) +mkfile_path := $(call ESCAPED_ABS_PATH,$(lastword $(MAKEFILE_LIST)))) abs_tmk_root := $(patsubst %/,%,$(dir $(mkfile_path))) ifneq (,$(findstring /keyboards/,$(starting_makefile))) @@ -83,10 +84,8 @@ endif ifneq ("$(wildcard $(KEYBOARD_PATH)/$(KEYBOARD).c)","") KEYBOARD_FILE = keyboards/$(KEYBOARD)/$(KEYBOARD).c - ifndef ARCH - ifneq ("$(wildcard $(KEYBOARD_PATH)/Makefile)","") - include $(KEYBOARD_PATH)/Makefile - endif + ifneq ($(call ESCAPED_ABS_PATH,$(KEYBOARD_PATH)/Makefile),$(starting_makefile)) + -include $(KEYBOARD_PATH)/Makefile endif else $(error "$(KEYBOARD_PATH)/$(KEYBOARD).c" does not exist) @@ -101,7 +100,9 @@ ifdef SUBPROJECT ifneq ("$(wildcard $(SUBPROJECT_PATH)/$(SUBPROJECT).c)","") OPT_DEFS += -DSUBPROJECT_$(SUBPROJECT) SUBPROJECT_FILE = keyboards/$(KEYBOARD)/$(SUBPROJECT)/$(SUBPROJECT).c - -include $(SUBPROJECT_PATH)/Makefile + ifneq ($(call ESCAPED_ABS_PATH,$(SUBPROJECT_PATH)/Makefile),$(starting_makefile)) + -include $(SUBPROJECT_PATH)/Makefile + endif else $(error "$(SUBPROJECT_PATH)/$(SUBPROJECT).c" does not exist) endif @@ -119,14 +120,18 @@ endif KEYMAP_PATH = $(KEYBOARD_PATH)/keymaps/$(KEYMAP) ifneq ("$(wildcard $(KEYMAP_PATH)/keymap.c)","") KEYMAP_FILE = keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/keymap.c - -include $(KEYMAP_PATH)/Makefile + ifneq ($(call ESCAPED_ABS_PATH,$(KEYMAP_PATH)/Makefile),$(starting_makefile)) + -include $(KEYMAP_PATH)/Makefile + endif else ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/keymap.c)","") $(error "$(KEYMAP_PATH)/keymap.c" does not exist) else KEYMAP_PATH = $(SUBPROJECT_PATH)/keymaps/$(KEYMAP) KEYMAP_FILE = keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/keymap.c - -include $(KEYMAP_PATH)/Makefile + ifneq ($(call ESCAPED_ABS_PATH,$(KEYMAP_PATH)/Makefile),$(starting_makefile)) + -include $(KEYMAP_PATH)/Makefile + endif endif endif @@ -135,7 +140,8 @@ ifdef SUBPROJECT else TARGET ?= $(KEYBOARD)_$(KEYMAP) endif -BUILD_DIR = .build + +BUILD_DIR = $(TOP_DIR)/.build # Object files directory # To put object files in current directory, use a dot (.), do NOT make @@ -265,4 +271,6 @@ include $(TMK_PATH)/rules.mk GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S") BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S") OPT_DEFS += -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\" -OPT_DEFS += -DQMK_VERSION=\"$(GIT_VERSION)\" -DQMK_BUILDDATE=\"$(BUILD_DATE)\" + +$(shell echo '#define QMK_VERSION "$(GIT_VERSION)"' > $(QUANTUM_PATH)/version.h) +$(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(QUANTUM_PATH)/version.h) \ No newline at end of file diff --git a/keyboards/ergodox/keymaps/algernon/keymap.c b/keyboards/ergodox/keymaps/algernon/keymap.c index 6a14ef46762..c4de53da27c 100644 --- a/keyboards/ergodox/keymaps/algernon/keymap.c +++ b/keyboards/ergodox/keymaps/algernon/keymap.c @@ -12,6 +12,7 @@ #include "keymap_plover.h" #include "eeconfig.h" #include "wait.h" +#include "version.h" /* Layers */ diff --git a/keyboards/ergodox/keymaps/default/keymap.c b/keyboards/ergodox/keymaps/default/keymap.c index f1a83f4e792..1b80cb3a236 100644 --- a/keyboards/ergodox/keymaps/default/keymap.c +++ b/keyboards/ergodox/keymaps/default/keymap.c @@ -1,6 +1,7 @@ #include "ergodox.h" #include "debug.h" #include "action_layer.h" +#include "version.h" #define BASE 0 // default layer #define SYMB 1 // symbols diff --git a/keyboards/ergodox/keymaps/josh/keymap.c b/keyboards/ergodox/keymaps/josh/keymap.c index 488b2142736..b5463873a90 100644 --- a/keyboards/ergodox/keymaps/josh/keymap.c +++ b/keyboards/ergodox/keymaps/josh/keymap.c @@ -1,6 +1,7 @@ #include "ergodox.h" #include "debug.h" #include "action_layer.h" +#include "version.h" #define BASE 0 // default layer #define SYMB 1 // symbols diff --git a/keyboards/planck/keymaps/cbbrowne/keymap.c b/keyboards/planck/keymaps/cbbrowne/keymap.c index 14a5be17082..70eaefb7bea 100644 --- a/keyboards/planck/keymaps/cbbrowne/keymap.c +++ b/keyboards/planck/keymaps/cbbrowne/keymap.c @@ -4,6 +4,7 @@ #endif #include "config.h" #include "quantum.h" +#include "version.h" /* Each layer is given a name to aid in readability, which is then used in the keymap matrix below. The underscores do not denote diff --git a/keyboards/planck/keymaps/experimental/keymap.c b/keyboards/planck/keymaps/experimental/keymap.c index d9303fcae59..2c12700944c 100644 --- a/keyboards/planck/keymaps/experimental/keymap.c +++ b/keyboards/planck/keymaps/experimental/keymap.c @@ -8,6 +8,7 @@ #endif #include "eeconfig.h" +#include "version.h" extern keymap_config_t keymap_config; diff --git a/readme.md b/readme.md index c3d866f36ba..57629f8be20 100644 --- a/readme.md +++ b/readme.md @@ -122,17 +122,16 @@ Below are some definitions that will be useful: Below is a list of the useful `make` commands in QMK: -* `make` - cleans automatically and builds your keyboard and keymap depending on which folder you're in. This defaults to the "default" layout (unless in a keymap folder), and Planck keyboard in the root folder +* `make` - builds your keyboard and keymap depending on which folder you're in. This defaults to the "default" layout (unless in a keymap folder), and Planck keyboard in the root folder * `make keyboard=` - specifies the keyboard (only to be used in root) * `make keymap=` - specifies the keymap (only to be used in root and keyboard folder - not needed when in keymap folder) -* `make quick` - skips the clean step (cannot be used immediately after modifying config.h or Makefiles) +* `make clean` - cleans the `.build` folder, ensuring that everything is re-built * `make dfu` - (requires dfu-programmer) builds and flashes the keymap to your keyboard once placed in reset/dfu mode (button or press `KC_RESET`). This does not work for Teensy-based keyboards like the ErgoDox EZ. * `keyboard=` and `keymap=` are compatible with this * `make all-keyboards` - builds all keymaps for all keyboards and outputs status of each (use in root) * `make all-keyboards-default` - builds all default keymaps for all keyboards and outputs status of each (use in root) * `make all-keymaps [keyboard=]` - builds all of the keymaps for whatever keyboard folder you're in, or specified by `` -* `make all-keyboards-quick`, `make all-keyboards-default-quick` and `make all-keymaps-quick [keyboard=]` - like the normal "make-all-*" commands, but they skip the clean steps - +* `make all-keyboards-*`, `make all-keyboards-default-*` and `make all-keymaps-* [keyboard=]` - like the normal "make-all-*" commands, but the last string aftter the `-` (for example clean) is passed to the keyboard make command. Other, less useful functionality: * `make COLOR=false` - turns off color output diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index c81fa685415..d2350f27c12 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),) @@ -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. @@ -268,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 @@ -373,35 +377,62 @@ 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. -$1/%.o : %.c | $(BEGIN) +$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) $$< -o $$@) + $$(eval CMD=$$(CC) -c $$(ALL_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP)) @$$(BUILD_CMD) # Compile: create object files from C++ source files. -$1/%.o : %.cpp | $(BEGIN) +$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) $$< -o $$@) + $$(eval CMD=$$(CC) -c $$(ALL_CPPFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP)) @$(BUILD_CMD) # Assemble: create object files from assembler source files. -$1/%.o : %.S | $(BEGIN) +$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))) @@ -424,7 +455,10 @@ $(eval $(call GEN_OBJRULE,$(KBOBJDIR))) $(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) @@ -444,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 @@ -461,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: @@ -484,19 +515,6 @@ 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) @@ -505,11 +523,11 @@ $(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 \