diff options
Diffstat (limited to 'Makefile')
| -rw-r--r-- | Makefile | 713 |
1 files changed, 445 insertions, 268 deletions
| @@ -2,284 +2,461 @@ ifndef VERBOSE | |||
| 2 | .SILENT: | 2 | .SILENT: |
| 3 | endif | 3 | endif |
| 4 | 4 | ||
| 5 | .DEFAULT_GOAL := all | 5 | # Allow the silent with lower caps to work the same way as upper caps |
| 6 | 6 | ifdef silent | |
| 7 | space := $(subst ,, ) | 7 | SILENT = $(silent) |
| 8 | ESCAPED_ABS_PATH = $(subst $(space),_SPACE_,$(abspath $1)) | 8 | endif |
| 9 | starting_makefile := $(call ESCAPED_ABS_PATH,$(firstword $(MAKEFILE_LIST))) | 9 | |
| 10 | mkfile_path := $(call ESCAPED_ABS_PATH,$(lastword $(MAKEFILE_LIST)))) | 10 | ifdef SILENT |
| 11 | abs_tmk_root := $(patsubst %/,%,$(dir $(mkfile_path))) | 11 | SUB_IS_SILENT := $(SILENT) |
| 12 | 12 | endif | |
| 13 | ifneq (,$(findstring /keyboards/,$(starting_makefile))) | 13 | |
| 14 | possible_keyboard:=$(patsubst %/,%,$(dir $(patsubst $(abs_tmk_root)/keyboards/%,%,$(starting_makefile)))) | 14 | # We need to make sure that silent is always turned off at the top level |
| 15 | ifneq (,$(findstring /keymaps/,$(possible_keyboard))) | 15 | # Otherwise the [OK], [ERROR] and [WARN] messags won't be displayed correctly |
| 16 | KEYMAP_DIR:=$(lastword $(subst /keymaps/, ,$(possible_keyboard))) | 16 | override SILENT := false |
| 17 | KEYBOARD_DIR:=$(firstword $(subst /keymaps/, ,$(possible_keyboard))) | 17 | |
| 18 | ifneq (,$(findstring /,$(KEYBOARD_DIR))) | 18 | ON_ERROR := error_occured=1 |
| 19 | # SUBPROJECT_DIR:=$(lastword $(subst /, ,$(KEYBOARD_DIR))) | 19 | |
| 20 | # KEYBOARD_DIR:=$(firstword $(subst /, ,$(KEYBOARD_DIR))) | 20 | STARTING_MAKEFILE := $(firstword $(MAKEFILE_LIST)) |
| 21 | tmk_root = ../../.. | 21 | ROOT_MAKEFILE := $(lastword $(MAKEFILE_LIST)) |
| 22 | else | 22 | ROOT_DIR := $(dir $(ROOT_MAKEFILE)) |
| 23 | tmk_root = ../../../.. | 23 | ifeq ($(ROOT_DIR),) |
| 24 | endif | 24 | ROOT_DIR := . |
| 25 | else | 25 | endif |
| 26 | KEYMAP_DIR:=default | 26 | ABS_STARTING_MAKEFILE := $(abspath $(STARTING_MAKEFILE)) |
| 27 | KEYBOARD_DIR:=$(possible_keyboard) | 27 | ABS_ROOT_MAKEFILE := $(abspath $(ROOT_MAKEFILE)) |
| 28 | ifneq (,$(findstring /,$(KEYBOARD_DIR))) | 28 | ABS_STARTING_DIR := $(dir $(ABS_STARTING_MAKEFILE)) |
| 29 | # SUBPROJECT_DIR:=$(lastword $(subst /, ,$(KEYBOARD_DIR))) | 29 | ABS_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE)) |
| 30 | # KEYBOARD_DIR:=$(firstword $(subst /, ,$(KEYBOARD_DIR))) | 30 | STARTING_DIR := $(subst $(ABS_ROOT_DIR),,$(ABS_STARTING_DIR)) |
| 31 | tmk_root = ../../.. | 31 | |
| 32 | else | 32 | MAKEFILE_INCLUDED=yes |
| 33 | tmk_root = ../.. | 33 | |
| 34 | endif | 34 | # Helper function to process the newt element of a space separated path |
| 35 | endif | 35 | # It works a bit like the traditional functional head tail |
| 36 | else | 36 | # so the CURRENT_PATH_ELEMENT will beome the new head |
| 37 | tmk_root = . | 37 | # and the PATH_ELEMENTS are the rest that are still unprocessed |
| 38 | endif | 38 | define NEXT_PATH_ELEMENT |
| 39 | # $(info $(KEYBOARD_DIR)) | 39 | $$(eval CURRENT_PATH_ELEMENT := $$(firstword $$(PATH_ELEMENTS))) |
| 40 | # $(info $(KEYMAP_DIR)) | 40 | $$(eval PATH_ELEMENTS := $$(wordlist 2,9999,$$(PATH_ELEMENTS))) |
| 41 | # $(info $(SUBPROJECT_DIR)) | 41 | endef |
| 42 | 42 | ||
| 43 | # Directory common source filess exist | 43 | # We change the / to spaces so that we more easily can work with the elements |
| 44 | TOP_DIR = $(tmk_root) | 44 | # separately |
| 45 | TMK_DIR = tmk_core | 45 | PATH_ELEMENTS := $(subst /, ,$(STARTING_DIR)) |
| 46 | TMK_PATH = $(TOP_DIR)/$(TMK_DIR) | 46 | # Initialize the path elements list for further processing |
| 47 | LIB_PATH = $(TOP_DIR)/lib | 47 | $(eval $(call NEXT_PATH_ELEMENT)) |
| 48 | 48 | ||
| 49 | QUANTUM_DIR = quantum | 49 | # This function sets the KEYBOARD; KEYMAP and SUBPROJECT to the correct |
| 50 | QUANTUM_PATH = $(TOP_DIR)/$(QUANTUM_DIR) | 50 | # variables depending on which directory you stand in. |
| 51 | 51 | # It's really a very simple if else chain, if you squint enough, | |
| 52 | 52 | # but the makefile syntax makes it very verbose. | |
| 53 | # If we are in a subfolder of keyboards | ||
| 54 | ifeq ($(CURRENT_PATH_ELEMENT),keyboards) | ||
| 55 | $(eval $(call NEXT_PATH_ELEMENT)) | ||
| 56 | KEYBOARD := $(CURRENT_PATH_ELEMENT) | ||
| 57 | $(eval $(call NEXT_PATH_ELEMENT)) | ||
| 58 | # If we are in a subfolder of keymaps, or in other words in a keymap | ||
| 59 | # folder | ||
| 60 | ifeq ($(CURRENT_PATH_ELEMENT),keymaps) | ||
| 61 | $(eval $(call NEXT_PATH_ELEMENT)) | ||
| 62 | KEYMAP := $(CURRENT_PATH_ELEMENT) | ||
| 63 | # else if we are not in the keyboard folder itself | ||
| 64 | else ifneq ($(CURRENT_PATH_ELEMENT),) | ||
| 65 | # the we can assume it's a subproject, as no other folders | ||
| 66 | # should have make files in them | ||
| 67 | SUBPROJECT := $(CURRENT_PATH_ELEMENT) | ||
| 68 | $(eval $(call NEXT_PATH_ELEMENT)) | ||
| 69 | # if we are inside a keymap folder of a subproject | ||
| 70 | ifeq ($(CURRENT_PATH_ELEMENT),keymaps) | ||
| 71 | $(eval $(call NEXT_PATH_ELEMENT)) | ||
| 72 | KEYMAP := $(CURRENT_PATH_ELEMENT) | ||
| 73 | endif | ||
| 74 | endif | ||
| 75 | endif | ||
| 76 | |||
| 77 | # Only consider folders with makefiles, to prevent errors in case there are extra folders | ||
| 78 | KEYBOARDS := $(notdir $(patsubst %/Makefile,%,$(wildcard $(ROOT_DIR)/keyboards/*/Makefile))) | ||
| 79 | |||
| 80 | #Compability with the old make variables, anything you specify directly on the command line | ||
| 81 | # always overrides the detected folders | ||
| 53 | ifdef keyboard | 82 | ifdef keyboard |
| 54 | KEYBOARD ?= $(keyboard) | 83 | KEYBOARD := $(keyboard) |
| 55 | endif | ||
| 56 | ifdef KEYBOARD_DIR | ||
| 57 | KEYBOARD ?= $(KEYBOARD_DIR) | ||
| 58 | endif | ||
| 59 | ifndef KEYBOARD | ||
| 60 | KEYBOARD=planck | ||
| 61 | endif | 84 | endif |
| 62 | |||
| 63 | MASTER ?= left | ||
| 64 | ifdef master | ||
| 65 | MASTER = $(master) | ||
| 66 | endif | ||
| 67 | |||
| 68 | |||
| 69 | # converts things to keyboards/subproject | ||
| 70 | ifneq (,$(findstring /,$(KEYBOARD))) | ||
| 71 | TEMP:=$(KEYBOARD) | ||
| 72 | KEYBOARD:=$(firstword $(subst /, ,$(TEMP))) | ||
| 73 | SUBPROJECT:=$(lastword $(subst /, ,$(TEMP))) | ||
| 74 | endif | ||
| 75 | |||
| 76 | KEYBOARD_PATH = $(TOP_DIR)/keyboards/$(KEYBOARD) | ||
| 77 | |||
| 78 | ifdef sub | 85 | ifdef sub |
| 79 | SUBPROJECT=$(sub) | 86 | SUBPROJECT := $(sub) |
| 80 | endif | 87 | endif |
| 81 | ifdef subproject | 88 | ifdef subproject |
| 82 | SUBPROJECT=$(subproject) | 89 | SUBPROJECT := $(subproject) |
| 83 | endif | ||
| 84 | |||
| 85 | ifneq ("$(wildcard $(KEYBOARD_PATH)/$(KEYBOARD).c)","") | ||
| 86 | KEYBOARD_FILE = keyboards/$(KEYBOARD)/$(KEYBOARD).c | ||
| 87 | ifneq ($(call ESCAPED_ABS_PATH,$(KEYBOARD_PATH)/Makefile),$(starting_makefile)) | ||
| 88 | -include $(KEYBOARD_PATH)/Makefile | ||
| 89 | endif | ||
| 90 | else | ||
| 91 | $(error "$(KEYBOARD_PATH)/$(KEYBOARD).c" does not exist) | ||
| 92 | endif | ||
| 93 | |||
| 94 | ifdef SUBPROJECT_DEFAULT | ||
| 95 | SUBPROJECT?=$(SUBPROJECT_DEFAULT) | ||
| 96 | endif | ||
| 97 | |||
| 98 | ifdef SUBPROJECT | ||
| 99 | SUBPROJECT_PATH = $(TOP_DIR)/keyboards/$(KEYBOARD)/$(SUBPROJECT) | ||
| 100 | ifneq ("$(wildcard $(SUBPROJECT_PATH)/$(SUBPROJECT).c)","") | ||
| 101 | OPT_DEFS += -DSUBPROJECT_$(SUBPROJECT) | ||
| 102 | SUBPROJECT_FILE = keyboards/$(KEYBOARD)/$(SUBPROJECT)/$(SUBPROJECT).c | ||
| 103 | ifneq ($(call ESCAPED_ABS_PATH,$(SUBPROJECT_PATH)/Makefile),$(starting_makefile)) | ||
| 104 | -include $(SUBPROJECT_PATH)/Makefile | ||
| 105 | endif | ||
| 106 | else | ||
| 107 | $(error "$(SUBPROJECT_PATH)/$(SUBPROJECT).c" does not exist) | ||
| 108 | endif | ||
| 109 | endif | 90 | endif |
| 110 | |||
| 111 | ifdef keymap | 91 | ifdef keymap |
| 112 | KEYMAP ?= $(keymap) | 92 | KEYMAP := $(keymap) |
| 113 | endif | ||
| 114 | ifdef KEYMAP_DIR | ||
| 115 | KEYMAP ?= $(KEYMAP_DIR) | ||
| 116 | endif | ||
| 117 | ifndef KEYMAP | ||
| 118 | KEYMAP = default | ||
| 119 | endif | ||
| 120 | KEYMAP_PATH = $(KEYBOARD_PATH)/keymaps/$(KEYMAP) | ||
| 121 | ifneq ("$(wildcard $(KEYMAP_PATH)/keymap.c)","") | ||
| 122 | KEYMAP_FILE = keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/keymap.c | ||
| 123 | ifneq ($(call ESCAPED_ABS_PATH,$(KEYMAP_PATH)/Makefile),$(starting_makefile)) | ||
| 124 | -include $(KEYMAP_PATH)/Makefile | ||
| 125 | endif | ||
| 126 | else | ||
| 127 | ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/keymap.c)","") | ||
| 128 | $(error "$(KEYMAP_PATH)/keymap.c" does not exist) | ||
| 129 | else | ||
| 130 | KEYMAP_PATH = $(SUBPROJECT_PATH)/keymaps/$(KEYMAP) | ||
| 131 | KEYMAP_FILE = keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/keymap.c | ||
| 132 | ifneq ($(call ESCAPED_ABS_PATH,$(KEYMAP_PATH)/Makefile),$(starting_makefile)) | ||
| 133 | -include $(KEYMAP_PATH)/Makefile | ||
| 134 | endif | ||
| 135 | endif | ||
| 136 | endif | ||
| 137 | |||
| 138 | ifdef SUBPROJECT | ||
| 139 | TARGET ?= $(KEYBOARD)_$(SUBPROJECT)_$(KEYMAP) | ||
| 140 | else | ||
| 141 | TARGET ?= $(KEYBOARD)_$(KEYMAP) | ||
| 142 | endif | ||
| 143 | |||
| 144 | BUILD_DIR = $(TOP_DIR)/.build | ||
| 145 | |||
| 146 | # Object files directory | ||
| 147 | # To put object files in current directory, use a dot (.), do NOT make | ||
| 148 | # this an empty or blank macro! | ||
| 149 | OBJDIR = $(BUILD_DIR)/obj_$(TARGET) | ||
| 150 | |||
| 151 | |||
| 152 | |||
| 153 | ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","") | ||
| 154 | CONFIG_H = $(KEYMAP_PATH)/config.h | ||
| 155 | else | ||
| 156 | CONFIG_H = $(KEYBOARD_PATH)/config.h | ||
| 157 | ifdef SUBPROJECT | ||
| 158 | ifneq ("$(wildcard $(SUBPROJECT_PATH)/$(SUBPROJECT).c)","") | ||
| 159 | CONFIG_H = $(SUBPROJECT_PATH)/config.h | ||
| 160 | endif | ||
| 161 | endif | ||
| 162 | endif | 93 | endif |
| 163 | 94 | ||
| 164 | # # project specific files | 95 | # Uncomment these for debugging |
| 165 | SRC += $(KEYBOARD_FILE) \ | 96 | #$(info Keyboard: $(KEYBOARD)) |
| 166 | $(KEYMAP_FILE) \ | 97 | #$(info Keymap: $(KEYMAP)) |
| 167 | $(QUANTUM_DIR)/quantum.c \ | 98 | #$(info Subproject: $(SUBPROJECT)) |
| 168 | $(QUANTUM_DIR)/keymap_common.c \ | 99 | #$(info Keyboards: $(KEYBOARDS)) |
| 169 | $(QUANTUM_DIR)/keycode_config.c \ | ||
| 170 | $(QUANTUM_DIR)/process_keycode/process_leader.c | ||
| 171 | 100 | ||
| 172 | ifdef SUBPROJECT | ||
| 173 | SRC += $(SUBPROJECT_FILE) | ||
| 174 | endif | ||
| 175 | |||
| 176 | ifdef SUBPROJECT | ||
| 177 | SRC += $(SUBPROJECT_FILE) | ||
| 178 | endif | ||
| 179 | |||
| 180 | ifdef SUBPROJECT | ||
| 181 | SRC += $(SUBPROJECT_FILE) | ||
| 182 | endif | ||
| 183 | |||
| 184 | ifndef CUSTOM_MATRIX | ||
| 185 | SRC += $(QUANTUM_DIR)/matrix.c | ||
| 186 | endif | ||
| 187 | |||
| 188 | ifeq ($(strip $(MIDI_ENABLE)), yes) | ||
| 189 | OPT_DEFS += -DMIDI_ENABLE | ||
| 190 | SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c | ||
| 191 | endif | ||
| 192 | |||
| 193 | ifeq ($(strip $(VIRTSER_ENABLE)), yes) | ||
| 194 | OPT_DEFS += -DVIRTSER_ENABLE | ||
| 195 | endif | ||
| 196 | |||
| 197 | ifeq ($(strip $(AUDIO_ENABLE)), yes) | ||
| 198 | OPT_DEFS += -DAUDIO_ENABLE | ||
| 199 | SRC += $(QUANTUM_DIR)/process_keycode/process_music.c | ||
| 200 | SRC += $(QUANTUM_DIR)/audio/audio.c | ||
| 201 | SRC += $(QUANTUM_DIR)/audio/voices.c | ||
| 202 | SRC += $(QUANTUM_DIR)/audio/luts.c | ||
| 203 | endif | ||
| 204 | |||
| 205 | ifeq ($(strip $(UCIS_ENABLE)), yes) | ||
| 206 | OPT_DEFS += -DUCIS_ENABLE | ||
| 207 | UNICODE_ENABLE = yes | ||
| 208 | endif | ||
| 209 | |||
| 210 | ifeq ($(strip $(UNICODE_ENABLE)), yes) | ||
| 211 | OPT_DEFS += -DUNICODE_ENABLE | ||
| 212 | SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c | ||
| 213 | endif | ||
| 214 | |||
| 215 | ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) | ||
| 216 | OPT_DEFS += -DRGBLIGHT_ENABLE | ||
| 217 | SRC += $(QUANTUM_DIR)/light_ws2812.c | ||
| 218 | SRC += $(QUANTUM_DIR)/rgblight.c | ||
| 219 | endif | ||
| 220 | |||
| 221 | ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) | ||
| 222 | OPT_DEFS += -DTAP_DANCE_ENABLE | ||
| 223 | SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c | ||
| 224 | endif | ||
| 225 | |||
| 226 | ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes) | ||
| 227 | SERIAL_DIR = $(QUANTUM_DIR)/serial_link | ||
| 228 | SERIAL_PATH = $(QUANTUM_PATH)/serial_link | ||
| 229 | SERIAL_SRC = $(wildcard $(SERIAL_PATH)/protocol/*.c) | ||
| 230 | SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c) | ||
| 231 | SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) | ||
| 232 | OPT_DEFS += -DSERIAL_LINK_ENABLE | ||
| 233 | VAPTH += $(SERIAL_PATH) | ||
| 234 | endif | ||
| 235 | |||
| 236 | # Optimize size but this may cause error "relocation truncated to fit" | ||
| 237 | #EXTRALDFLAGS = -Wl,--relax | ||
| 238 | |||
| 239 | # Search Path | ||
| 240 | VPATH += $(KEYMAP_PATH) | ||
| 241 | ifdef SUBPROJECT | ||
| 242 | VPATH += $(SUBPROJECT_PATH) | ||
| 243 | endif | ||
| 244 | VPATH += $(KEYBOARD_PATH) | ||
| 245 | VPATH += $(TOP_DIR) | ||
| 246 | VPATH += $(TMK_PATH) | ||
| 247 | VPATH += $(QUANTUM_PATH) | ||
| 248 | VPATH += $(QUANTUM_PATH)/keymap_extras | ||
| 249 | VPATH += $(QUANTUM_PATH)/audio | ||
| 250 | VPATH += $(QUANTUM_PATH)/process_keycode | ||
| 251 | |||
| 252 | |||
| 253 | # We can assume a ChibiOS target When MCU_FAMILY is defined, since it's not used for LUFA | ||
| 254 | ifdef MCU_FAMILY | ||
| 255 | PLATFORM=CHIBIOS | ||
| 256 | else | ||
| 257 | PLATFORM=AVR | ||
| 258 | endif | ||
| 259 | |||
| 260 | include $(TMK_PATH)/common.mk | ||
| 261 | ifeq ($(PLATFORM),AVR) | ||
| 262 | include $(TMK_PATH)/protocol/lufa.mk | ||
| 263 | include $(TMK_PATH)/avr.mk | ||
| 264 | else ifeq ($(PLATFORM),CHIBIOS) | ||
| 265 | include $(TMK_PATH)/protocol/chibios.mk | ||
| 266 | include $(TMK_PATH)/chibios.mk | ||
| 267 | OPT_OS = chibios | ||
| 268 | else | ||
| 269 | $(error Unknown platform) | ||
| 270 | endif | ||
| 271 | |||
| 272 | ifeq ($(strip $(VISUALIZER_ENABLE)), yes) | ||
| 273 | VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer | ||
| 274 | VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer | ||
| 275 | include $(VISUALIZER_PATH)/visualizer.mk | ||
| 276 | endif | ||
| 277 | |||
| 278 | include $(TMK_PATH)/rules.mk | ||
| 279 | 101 | ||
| 102 | # Set the default goal depening on where we are running make from | ||
| 103 | # this handles the case where you run make without any arguments | ||
| 104 | .DEFAULT_GOAL := all | ||
| 105 | ifneq ($(KEYMAP),) | ||
| 106 | ifeq ($(SUBPROJECT),) | ||
| 107 | # Inside a keymap folder, just build the keymap, with the | ||
| 108 | # default subproject | ||
| 109 | .DEFAULT_GOAL := $(KEYBOARD)-$(KEYMAP) | ||
| 110 | else | ||
| 111 | # Inside a subproject keyamp folder, build the keymap | ||
| 112 | # for that subproject | ||
| 113 | .DEFAULT_GOAL := $(KEYBOARD)-$(SUBPROJECT)-$(KEYMAP) | ||
| 114 | endif | ||
| 115 | else ifneq ($(SUBPROJECT),) | ||
| 116 | # Inside a subproject folder, build all keymaps for that subproject | ||
| 117 | .DEFAULT_GOAL := $(KEYBOARD)-$(SUBPROJECT)-allkm | ||
| 118 | else ifneq ($(KEYBOARD),) | ||
| 119 | # Inside a keyboard folder, build all keymaps for all subprojects | ||
| 120 | # Note that this is different from the old behaviour, which would | ||
| 121 | # build only the default keymap of the default keyboard | ||
| 122 | .DEFAULT_GOAL := $(KEYBOARD)-allsp-allkm | ||
| 123 | endif | ||
| 124 | |||
| 125 | |||
| 126 | # Compare the start of the RULE variable with the first argument($1) | ||
| 127 | # If the rules equals $1 or starts with $1-, RULE_FOUND is set to true | ||
| 128 | # and $1 is removed from the RULE variable | ||
| 129 | # Otherwise the RULE_FOUND variable is set to false, and RULE left as it was | ||
| 130 | # The function is a bit tricky, since there's no built in $(startswith) function | ||
| 131 | define COMPARE_AND_REMOVE_FROM_RULE_HELPER | ||
| 132 | ifeq ($1,$$(RULE)) | ||
| 133 | RULE:= | ||
| 134 | RULE_FOUND := true | ||
| 135 | else | ||
| 136 | STARTDASH_REMOVED=$$(subst START$1-,,START$$(RULE)) | ||
| 137 | ifneq ($$(STARTDASH_REMOVED),START$$(RULE)) | ||
| 138 | RULE_FOUND := true | ||
| 139 | RULE := $$(STARTDASH_REMOVED) | ||
| 140 | else | ||
| 141 | RULE_FOUND := false | ||
| 142 | endif | ||
| 143 | endif | ||
| 144 | endef | ||
| 145 | |||
| 146 | # This makes it easier to call COMPARE_AND_REMOVE_FROM_RULE, since it makes it behave like | ||
| 147 | # a function that returns the value | ||
| 148 | COMPARE_AND_REMOVE_FROM_RULE = $(eval $(call COMPARE_AND_REMOVE_FROM_RULE_HELPER,$1))$(RULE_FOUND) | ||
| 149 | |||
| 150 | |||
| 151 | # Recursively try to find a match for the start of the rule to be checked | ||
| 152 | # $1 The list to be checked | ||
| 153 | # If a match is found, then RULE_FOUND is set to true | ||
| 154 | # and MATCHED_ITEM to the item that was matched | ||
| 155 | define TRY_TO_MATCH_RULE_FROM_LIST_HELPER3 | ||
| 156 | ifneq ($1,) | ||
| 157 | ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,$$(firstword $1)),true) | ||
| 158 | MATCHED_ITEM := $$(firstword $1) | ||
| 159 | else | ||
| 160 | $$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$$(wordlist 2,9999,$1))) | ||
| 161 | endif | ||
| 162 | endif | ||
| 163 | endef | ||
| 164 | |||
| 165 | # A recursive helper function for finding the longest match | ||
| 166 | # $1 The list to be checed | ||
| 167 | # It works by always removing the currently matched item from the list | ||
| 168 | # and call itself recursively, until a match is found | ||
| 169 | define TRY_TO_MATCH_RULE_FROM_LIST_HELPER2 | ||
| 170 | # Stop the recursion when the list is empty | ||
| 171 | ifneq ($1,) | ||
| 172 | RULE_BEFORE := $$(RULE) | ||
| 173 | $$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$1)) | ||
| 174 | # If a match is found in the current list, otherwise just return what we had before | ||
| 175 | ifeq ($$(RULE_FOUND),true) | ||
| 176 | # Save the best match so far and call itself recursivel | ||
| 177 | BEST_MATCH := $$(MATCHED_ITEM) | ||
| 178 | BEST_MATCH_RULE := $$(RULE) | ||
| 179 | RULE_FOUND := false | ||
| 180 | RULE := $$(RULE_BEFORE) | ||
| 181 | $$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER2,$$(filter-out $$(MATCHED_ITEM),$1))) | ||
| 182 | endif | ||
| 183 | endif | ||
| 184 | endef | ||
| 185 | |||
| 186 | |||
| 187 | # Recursively try to find the longest match for the start of the rule to be checked | ||
| 188 | # $1 The list to be checked | ||
| 189 | # If a match is found, then RULE_FOUND is set to true | ||
| 190 | # and MATCHED_ITEM to the item that was matched | ||
| 191 | define TRY_TO_MATCH_RULE_FROM_LIST_HELPER | ||
| 192 | BEST_MATCH := | ||
| 193 | $$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER2,$1)) | ||
| 194 | ifneq ($$(BEST_MATCH),) | ||
| 195 | RULE_FOUND := true | ||
| 196 | RULE := $$(BEST_MATCH_RULE) | ||
| 197 | MATCHED_ITEM := $$(BEST_MATCH) | ||
| 198 | else | ||
| 199 | RULE_FOUND := false | ||
| 200 | MATCHED_ITEM := | ||
| 201 | endif | ||
| 202 | endef | ||
| 203 | |||
| 204 | # Make it easier to call TRY_TO_MATCH_RULE_FROM_LIST | ||
| 205 | TRY_TO_MATCH_RULE_FROM_LIST = $(eval $(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER,$1))$(RULE_FOUND) | ||
| 206 | |||
| 207 | define ALL_IN_LIST_LOOP | ||
| 208 | OLD_RULE$1 := $$(RULE) | ||
| 209 | $$(eval $$(call $1,$$(ITEM$1))) | ||
| 210 | RULE := $$(OLD_RULE$1) | ||
| 211 | endef | ||
| 212 | |||
| 213 | define PARSE_ALL_IN_LIST | ||
| 214 | $$(foreach ITEM$1,$2,$$(eval $$(call ALL_IN_LIST_LOOP,$1))) | ||
| 215 | endef | ||
| 216 | |||
| 217 | # The entry point for rule parsing | ||
| 218 | # parses a rule in the format <keyboard>-<subproject>-<keymap>-<target> | ||
| 219 | # but this particular function only deals with the first <keyboard> part | ||
| 220 | define PARSE_RULE | ||
| 221 | RULE := $1 | ||
| 222 | COMMANDS := | ||
| 223 | # If the rule starts with allkb, then continue the parsing from | ||
| 224 | # PARSE_ALL_KEYBOARDS | ||
| 225 | ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,allkb),true) | ||
| 226 | $$(eval $$(call PARSE_ALL_KEYBOARDS)) | ||
| 227 | # If the rule starts with the name of a known keyboard, then continue | ||
| 228 | # the parsing from PARSE_KEYBOARD | ||
| 229 | else ifeq ($$(call TRY_TO_MATCH_RULE_FROM_LIST,$$(KEYBOARDS)),true) | ||
| 230 | $$(eval $$(call PARSE_KEYBOARD,$$(MATCHED_ITEM))) | ||
| 231 | # Otherwise use the KEYBOARD variable, which is determined either by | ||
| 232 | # the current directory you run make from, or passed in as an argument | ||
| 233 | else ifneq ($$(KEYBOARD),) | ||
| 234 | $$(eval $$(call PARSE_KEYBOARD,$$(KEYBOARD))) | ||
| 235 | else | ||
| 236 | $$(info make: *** No rule to make target '$1'. Stop.) | ||
| 237 | # Notice the tab instead of spaces below! | ||
| 238 | exit 1 | ||
| 239 | endif | ||
| 240 | endef | ||
| 241 | |||
| 242 | # $1 = Keyboard | ||
| 243 | # Parses a rule in the format <subproject>-<keymap>-<target> | ||
| 244 | # the keyboard is already known when entering this function | ||
| 245 | define PARSE_KEYBOARD | ||
| 246 | CURRENT_KB := $1 | ||
| 247 | # A subproject is any keyboard subfolder with a makefile | ||
| 248 | SUBPROJECTS := $$(notdir $$(patsubst %/Makefile,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(CURRENT_KB)/*/Makefile))) | ||
| 249 | # if the rule starts with allsp, then continue with looping over all subprojects | ||
| 250 | ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,allsp),true) | ||
| 251 | $$(eval $$(call PARSE_ALL_SUBPROJECTS)) | ||
| 252 | # A special case for matching the defaultsp (default subproject) | ||
| 253 | else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,defaultsp),true) | ||
| 254 | $$(eval $$(call PARSE_SUBPROJECT,defaultsp)) | ||
| 255 | # If the rule starts with the name of a known subproject | ||
| 256 | else ifeq ($$(call TRY_TO_MATCH_RULE_FROM_LIST,$$(SUBPROJECTS)),true) | ||
| 257 | $$(eval $$(call PARSE_SUBPROJECT,$$(MATCHED_ITEM))) | ||
| 258 | # Try to use the SUBPROJECT variable, which is either determined by the | ||
| 259 | # directory which invoked make, or passed as an argument to make | ||
| 260 | else ifneq ($$(SUBPROJECT),) | ||
| 261 | $$(eval $$(call PARSE_SUBPROJECT,$$(SUBPROJECT))) | ||
| 262 | # If there's no matching subproject, we assume it's the default | ||
| 263 | # This will allow you to leave the subproject part of the target out | ||
| 264 | else | ||
| 265 | $$(eval $$(call PARSE_SUBPROJECT,)) | ||
| 266 | endif | ||
| 267 | endef | ||
| 268 | |||
| 269 | # if we are going to compile all keyboards, match the rest of the rule | ||
| 270 | # for each of them | ||
| 271 | define PARSE_ALL_KEYBOARDS | ||
| 272 | $$(eval $$(call PARSE_ALL_IN_LIST,PARSE_KEYBOARD,$(KEYBOARDS))) | ||
| 273 | endef | ||
| 274 | |||
| 275 | # $1 Subproject | ||
| 276 | # When entering this, the keyboard and subproject are known, so now we need | ||
| 277 | # to determine which keymaps are going to get compiled | ||
| 278 | define PARSE_SUBPROJECT | ||
| 279 | # If we want to compile the default subproject, then we need to | ||
| 280 | # include the correct makefile to determine the actual name of it | ||
| 281 | CURRENT_SP := $1 | ||
| 282 | ifeq ($$(CURRENT_SP),) | ||
| 283 | CURRENT_SP := defaultsp | ||
| 284 | endif | ||
| 285 | ifeq ($$(CURRENT_SP),defaultsp) | ||
| 286 | SUBPROJECT_DEFAULT= | ||
| 287 | $$(eval include $(ROOT_DIR)/keyboards/$$(CURRENT_KB)/Makefile) | ||
| 288 | CURRENT_SP := $$(SUBPROJECT_DEFAULT) | ||
| 289 | endif | ||
| 290 | # If current subproject is empty (the default was not defined), and we have a list of subproject | ||
| 291 | # then make all of them | ||
| 292 | ifeq ($$(CURRENT_SP),) | ||
| 293 | ifneq ($$(SUBPROJECTS),) | ||
| 294 | CURRENT_SP := allsp | ||
| 295 | endif | ||
| 296 | endif | ||
| 297 | # The special allsp is handled later | ||
| 298 | ifneq ($$(CURRENT_SP),allsp) | ||
| 299 | # get a list of all keymaps | ||
| 300 | KEYMAPS := $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(CURRENT_KB)/keymaps/*/.))) | ||
| 301 | ifneq ($$(CURRENT_SP),) | ||
| 302 | # if the subproject is defined, then also look for keymaps inside the subproject folder | ||
| 303 | SP_KEYMAPS := $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(CURRENT_KB)/$$(CURRENT_SP)/keymaps/*/.))) | ||
| 304 | KEYMAPS := $$(sort $$(KEYMAPS) $$(SP_KEYMAPS)) | ||
| 305 | endif | ||
| 306 | # if the rule after removing the start of it is empty (we haven't specified a kemap or target) | ||
| 307 | # compile all the keymaps | ||
| 308 | ifeq ($$(RULE),) | ||
| 309 | $$(eval $$(call PARSE_ALL_KEYMAPS)) | ||
| 310 | # The same if allkm was specified | ||
| 311 | else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,allkm),true) | ||
| 312 | $$(eval $$(call PARSE_ALL_KEYMAPS)) | ||
| 313 | # Try to match the specified keyamp with the list of known keymaps | ||
| 314 | else ifeq ($$(call TRY_TO_MATCH_RULE_FROM_LIST,$$(KEYMAPS)),true) | ||
| 315 | $$(eval $$(call PARSE_KEYMAP,$$(MATCHED_ITEM))) | ||
| 316 | # Otherwise try to match the keymap from the current folder, or arguments to the make command | ||
| 317 | else ifneq ($$(KEYMAP),) | ||
| 318 | $$(eval $$(call PARSE_KEYMAP,$$(KEYMAP))) | ||
| 319 | # No matching keymap found, so we assume that the rest of the rule is the target | ||
| 320 | # If we haven't been able to parse out a subproject, then make all of them | ||
| 321 | # This is consistent with running make without any arguments from the keyboard | ||
| 322 | # folder | ||
| 323 | else ifeq ($1,) | ||
| 324 | $$(eval $$(call PARSE_ALL_SUBPROJECTS)) | ||
| 325 | # Otherwise, make all keymaps, again this is consistent with how it works without | ||
| 326 | # any arguments | ||
| 327 | else | ||
| 328 | $$(eval $$(call PARSE_ALL_KEYMAPS)) | ||
| 329 | endif | ||
| 330 | else | ||
| 331 | # As earlier mentione,d when allsb is specified, we call our self recursively | ||
| 332 | # for all of the subprojects | ||
| 333 | $$(eval $$(call PARSE_ALL_IN_LIST,PARSE_SUBPROJECT,$(SUBPROJECTS))) | ||
| 334 | endif | ||
| 335 | endef | ||
| 336 | |||
| 337 | # If we want to parse all subprojects, but the keyboard doesn't have any, | ||
| 338 | # then use defaultsp instead | ||
| 339 | define PARSE_ALL_SUBPROJECTS | ||
| 340 | ifeq ($$(SUBPROJECTS),) | ||
| 341 | $$(eval $$(call PARSE_SUBPROJECT,defaultsp)) | ||
| 342 | else | ||
| 343 | $$(eval $$(call PARSE_ALL_IN_LIST,PARSE_SUBPROJECT,$$(SUBPROJECTS))) | ||
| 344 | endif | ||
| 345 | endef | ||
| 346 | |||
| 347 | # $1 Keymap | ||
| 348 | # This is the meat of compiling a keyboard, when entering this, everything is known | ||
| 349 | # keyboard, subproject, and keymap | ||
| 350 | # Note that we are not directly calling the command here, but instead building a list, | ||
| 351 | # which will later be processed | ||
| 352 | define PARSE_KEYMAP | ||
| 353 | CURRENT_KM = $1 | ||
| 354 | # The rest of the rule is the target | ||
| 355 | # Remove the leading "-" from the target, as it acts as a separator | ||
| 356 | MAKE_TARGET := $$(patsubst -%,%,$$(RULE)) | ||
| 357 | # We need to generate an unique indentifer to append to the COMMANDS list | ||
| 358 | COMMAND := COMMAND_KEYBOARD_$$(CURRENT_KB)_SUBPROJECT_$(CURRENT_SP)_KEYMAP_$$(CURRENT_KM) | ||
| 359 | COMMANDS += $$(COMMAND) | ||
| 360 | # If we are compiling a keyboard without a subproject, we want to display just the name | ||
| 361 | # of the keyboard, otherwise keyboard/subproject | ||
| 362 | ifeq ($$(CURRENT_SP),) | ||
| 363 | KB_SP := $(CURRENT_KB) | ||
| 364 | else | ||
| 365 | KB_SP := $(CURRENT_KB)/$$(CURRENT_SP) | ||
| 366 | endif | ||
| 367 | # Format it in bold | ||
| 368 | KB_SP := $(BOLD)$$(KB_SP)$(NO_COLOR) | ||
| 369 | # Specify the variables that we are passing forward to submake | ||
| 370 | MAKE_VARS := KEYBOARD=$$(CURRENT_KB) SUBPROJECT=$$(CURRENT_SP) KEYMAP=$$(CURRENT_KM) | ||
| 371 | MAKE_VARS += VERBOSE=$(VERBOSE) COLOR=$(COLOR) | ||
| 372 | # And the first part of the make command | ||
| 373 | MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_keyboard.mk $$(MAKE_TARGET) | ||
| 374 | # The message to display | ||
| 375 | MAKE_MSG := $$(MSG_MAKE_KB) | ||
| 376 | # We run the command differently, depending on if we want more output or not | ||
| 377 | # The true version for silent output and the false version otherwise | ||
| 378 | COMMAND_true_$$(COMMAND) := \ | ||
| 379 | printf "$$(MAKE_MSG)" | \ | ||
| 380 | $$(MAKE_MSG_FORMAT); \ | ||
| 381 | LOG=$$$$($$(MAKE_CMD) $$(MAKE_VARS) SILENT=true 2>&1) ; \ | ||
| 382 | if [ $$$$? -gt 0 ]; \ | ||
| 383 | then $$(PRINT_ERROR_PLAIN); \ | ||
| 384 | elif [ "$$$$LOG" != "" ] ; \ | ||
| 385 | then $$(PRINT_WARNING_PLAIN); \ | ||
| 386 | else \ | ||
| 387 | $$(PRINT_OK); \ | ||
| 388 | fi; | ||
| 389 | COMMAND_false_$$(COMMAND) := \ | ||
| 390 | printf "$$(MAKE_MSG)\n\n"; \ | ||
| 391 | $$(MAKE_CMD) $$(MAKE_VARS) SILENT=false; | ||
| 392 | endef | ||
| 393 | |||
| 394 | # Just parse all the keymaps for a specifc keyboard | ||
| 395 | define PARSE_ALL_KEYMAPS | ||
| 396 | $$(eval $$(call PARSE_ALL_IN_LIST,PARSE_KEYMAP,$$(KEYMAPS))) | ||
| 397 | endef | ||
| 398 | |||
| 399 | # Set the silent mode depending on if we are trying to compile multiple keyboards or not | ||
| 400 | # By default it's on in that case, but it can be overriden by specifying silent=false | ||
| 401 | # from the command line | ||
| 402 | define SET_SILENT_MODE | ||
| 403 | ifdef SUB_IS_SILENT | ||
| 404 | SILENT_MODE := $(SUB_IS_SILENT) | ||
| 405 | else ifeq ($$(words $$(COMMANDS)),1) | ||
| 406 | SILENT_MODE := false | ||
| 407 | else | ||
| 408 | SILENT_MODE := true | ||
| 409 | endif | ||
| 410 | endef | ||
| 411 | |||
| 412 | include $(ROOT_DIR)/message.mk | ||
| 413 | |||
| 414 | RUN_COMMAND = \ | ||
| 415 | $(COMMAND_$(SILENT_MODE)_$(COMMAND)) | ||
| 416 | |||
| 417 | # Allow specifying just the subproject, in the keyboard directory, which will compile all keymaps | ||
| 418 | SUBPROJECTS := $(notdir $(patsubst %/Makefile,%,$(wildcard ./*/Makefile))) | ||
| 419 | .PHONY: $(SUBPROJECTS) | ||
| 420 | $(SUBPROJECTS): %: %-allkm | ||
| 421 | |||
| 422 | # Let's match everything, we handle all the rule parsing ourselves | ||
| 423 | .PHONY: % | ||
| 424 | %: | ||
| 425 | # Check if we have the CMP tool installed | ||
| 426 | cmp --version >/dev/null 2>&1; if [ $$? -gt 0 ]; then printf "$(MSG_NO_CMP)"; exit 1; fi; | ||
| 427 | # Check if the submodules are dirty, and display a warning if they are | ||
| 428 | git submodule status --recursive 2>/dev/null | \ | ||
| 429 | while IFS= read -r x; do \ | ||
| 430 | case "$$x" in \ | ||
| 431 | \ *) ;; \ | ||
| 432 | *) printf "$(MSG_SUBMODULE_DIRTY)";break;; \ | ||
| 433 | esac \ | ||
| 434 | done | ||
| 435 | $(eval $(call PARSE_RULE,$@)) | ||
| 436 | $(eval $(call SET_SILENT_MODE)) | ||
| 437 | # Run all the commands in the same shell, notice the + at the first line | ||
| 438 | # it has to be there to allow parallel execution of the submake | ||
| 439 | # This always tries to compile everything, even if error occurs in the middle | ||
| 440 | # But we return the error code at the end, to trigger travis failures | ||
| 441 | +error_occured=0; \ | ||
| 442 | $(foreach COMMAND,$(COMMANDS),$(RUN_COMMAND)) \ | ||
| 443 | if [ $$error_occured -gt 0 ]; then printf "$(MSG_ERRORS)" & exit $$error_occured; fi | ||
| 444 | |||
| 445 | |||
| 446 | # All should compile everything | ||
| 447 | .PHONY: all | ||
| 448 | all: all-keyboards | ||
| 449 | |||
| 450 | # Define some shortcuts, mostly for compability with the old syntax | ||
| 451 | .PHONY: all-keyboards | ||
| 452 | all-keyboards: allkb-allsp-allkm | ||
| 453 | |||
| 454 | .PHONY: all-keyboards-defaults | ||
| 455 | all-keyboards-defaults: allkb-allsp-default | ||
| 456 | |||
| 457 | |||
| 458 | # Generate the version.h file | ||
| 280 | GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S") | 459 | GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S") |
| 281 | BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S") | 460 | BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S") |
| 282 | OPT_DEFS += -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\" | 461 | $(shell echo '#define QMK_VERSION "$(GIT_VERSION)"' > $(ROOT_DIR)/quantum/version.h) |
| 283 | 462 | $(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(ROOT_DIR)/quantum/version.h) \ No newline at end of file | |
| 284 | $(shell echo '#define QMK_VERSION "$(GIT_VERSION)"' > $(QUANTUM_PATH)/version.h) | ||
| 285 | $(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(QUANTUM_PATH)/version.h) | ||
