aboutsummaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile713
1 files changed, 445 insertions, 268 deletions
diff --git a/Makefile b/Makefile
index 331badcf8..f78cca6c6 100644
--- a/Makefile
+++ b/Makefile
@@ -2,284 +2,461 @@ ifndef VERBOSE
2.SILENT: 2.SILENT:
3endif 3endif
4 4
5.DEFAULT_GOAL := all 5# Allow the silent with lower caps to work the same way as upper caps
6 6ifdef silent
7space := $(subst ,, ) 7 SILENT = $(silent)
8ESCAPED_ABS_PATH = $(subst $(space),_SPACE_,$(abspath $1)) 8endif
9starting_makefile := $(call ESCAPED_ABS_PATH,$(firstword $(MAKEFILE_LIST))) 9
10mkfile_path := $(call ESCAPED_ABS_PATH,$(lastword $(MAKEFILE_LIST)))) 10ifdef SILENT
11abs_tmk_root := $(patsubst %/,%,$(dir $(mkfile_path))) 11 SUB_IS_SILENT := $(SILENT)
12 12endif
13ifneq (,$(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))) 16override SILENT := false
17 KEYBOARD_DIR:=$(firstword $(subst /keymaps/, ,$(possible_keyboard))) 17
18 ifneq (,$(findstring /,$(KEYBOARD_DIR))) 18ON_ERROR := error_occured=1
19 # SUBPROJECT_DIR:=$(lastword $(subst /, ,$(KEYBOARD_DIR))) 19
20 # KEYBOARD_DIR:=$(firstword $(subst /, ,$(KEYBOARD_DIR))) 20STARTING_MAKEFILE := $(firstword $(MAKEFILE_LIST))
21 tmk_root = ../../.. 21ROOT_MAKEFILE := $(lastword $(MAKEFILE_LIST))
22 else 22ROOT_DIR := $(dir $(ROOT_MAKEFILE))
23 tmk_root = ../../../.. 23ifeq ($(ROOT_DIR),)
24 endif 24 ROOT_DIR := .
25 else 25endif
26 KEYMAP_DIR:=default 26ABS_STARTING_MAKEFILE := $(abspath $(STARTING_MAKEFILE))
27 KEYBOARD_DIR:=$(possible_keyboard) 27ABS_ROOT_MAKEFILE := $(abspath $(ROOT_MAKEFILE))
28 ifneq (,$(findstring /,$(KEYBOARD_DIR))) 28ABS_STARTING_DIR := $(dir $(ABS_STARTING_MAKEFILE))
29 # SUBPROJECT_DIR:=$(lastword $(subst /, ,$(KEYBOARD_DIR))) 29ABS_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE))
30 # KEYBOARD_DIR:=$(firstword $(subst /, ,$(KEYBOARD_DIR))) 30STARTING_DIR := $(subst $(ABS_ROOT_DIR),,$(ABS_STARTING_DIR))
31 tmk_root = ../../.. 31
32 else 32MAKEFILE_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
36else 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
38endif 38define 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)) 41endef
42 42
43# Directory common source filess exist 43# We change the / to spaces so that we more easily can work with the elements
44TOP_DIR = $(tmk_root) 44# separately
45TMK_DIR = tmk_core 45PATH_ELEMENTS := $(subst /, ,$(STARTING_DIR))
46TMK_PATH = $(TOP_DIR)/$(TMK_DIR) 46# Initialize the path elements list for further processing
47LIB_PATH = $(TOP_DIR)/lib 47$(eval $(call NEXT_PATH_ELEMENT))
48 48
49QUANTUM_DIR = quantum 49# This function sets the KEYBOARD; KEYMAP and SUBPROJECT to the correct
50QUANTUM_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
54ifeq ($(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
75endif
76
77# Only consider folders with makefiles, to prevent errors in case there are extra folders
78KEYBOARDS := $(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
53ifdef keyboard 82ifdef keyboard
54 KEYBOARD ?= $(keyboard) 83 KEYBOARD := $(keyboard)
55endif
56ifdef KEYBOARD_DIR
57 KEYBOARD ?= $(KEYBOARD_DIR)
58endif
59ifndef KEYBOARD
60 KEYBOARD=planck
61endif 84endif
62
63MASTER ?= left
64ifdef master
65 MASTER = $(master)
66endif
67
68
69# converts things to keyboards/subproject
70ifneq (,$(findstring /,$(KEYBOARD)))
71 TEMP:=$(KEYBOARD)
72 KEYBOARD:=$(firstword $(subst /, ,$(TEMP)))
73 SUBPROJECT:=$(lastword $(subst /, ,$(TEMP)))
74endif
75
76KEYBOARD_PATH = $(TOP_DIR)/keyboards/$(KEYBOARD)
77
78ifdef sub 85ifdef sub
79 SUBPROJECT=$(sub) 86 SUBPROJECT := $(sub)
80endif 87endif
81ifdef subproject 88ifdef subproject
82 SUBPROJECT=$(subproject) 89 SUBPROJECT := $(subproject)
83endif
84
85ifneq ("$(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
90else
91$(error "$(KEYBOARD_PATH)/$(KEYBOARD).c" does not exist)
92endif
93
94ifdef SUBPROJECT_DEFAULT
95 SUBPROJECT?=$(SUBPROJECT_DEFAULT)
96endif
97
98ifdef 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
109endif 90endif
110
111ifdef keymap 91ifdef keymap
112 KEYMAP ?= $(keymap) 92 KEYMAP := $(keymap)
113endif
114ifdef KEYMAP_DIR
115 KEYMAP ?= $(KEYMAP_DIR)
116endif
117ifndef KEYMAP
118 KEYMAP = default
119endif
120KEYMAP_PATH = $(KEYBOARD_PATH)/keymaps/$(KEYMAP)
121ifneq ("$(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
126else
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
136endif
137
138ifdef SUBPROJECT
139 TARGET ?= $(KEYBOARD)_$(SUBPROJECT)_$(KEYMAP)
140else
141 TARGET ?= $(KEYBOARD)_$(KEYMAP)
142endif
143
144BUILD_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!
149OBJDIR = $(BUILD_DIR)/obj_$(TARGET)
150
151
152
153ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
154 CONFIG_H = $(KEYMAP_PATH)/config.h
155else
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
162endif 93endif
163 94
164# # project specific files 95# Uncomment these for debugging
165SRC += $(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
172ifdef SUBPROJECT
173 SRC += $(SUBPROJECT_FILE)
174endif
175
176ifdef SUBPROJECT
177 SRC += $(SUBPROJECT_FILE)
178endif
179
180ifdef SUBPROJECT
181 SRC += $(SUBPROJECT_FILE)
182endif
183
184ifndef CUSTOM_MATRIX
185 SRC += $(QUANTUM_DIR)/matrix.c
186endif
187
188ifeq ($(strip $(MIDI_ENABLE)), yes)
189 OPT_DEFS += -DMIDI_ENABLE
190 SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
191endif
192
193ifeq ($(strip $(VIRTSER_ENABLE)), yes)
194 OPT_DEFS += -DVIRTSER_ENABLE
195endif
196
197ifeq ($(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
203endif
204
205ifeq ($(strip $(UCIS_ENABLE)), yes)
206 OPT_DEFS += -DUCIS_ENABLE
207 UNICODE_ENABLE = yes
208endif
209
210ifeq ($(strip $(UNICODE_ENABLE)), yes)
211 OPT_DEFS += -DUNICODE_ENABLE
212 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
213endif
214
215ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
216 OPT_DEFS += -DRGBLIGHT_ENABLE
217 SRC += $(QUANTUM_DIR)/light_ws2812.c
218 SRC += $(QUANTUM_DIR)/rgblight.c
219endif
220
221ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
222 OPT_DEFS += -DTAP_DANCE_ENABLE
223 SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
224endif
225
226ifeq ($(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)
234endif
235
236# Optimize size but this may cause error "relocation truncated to fit"
237#EXTRALDFLAGS = -Wl,--relax
238
239# Search Path
240VPATH += $(KEYMAP_PATH)
241ifdef SUBPROJECT
242 VPATH += $(SUBPROJECT_PATH)
243endif
244VPATH += $(KEYBOARD_PATH)
245VPATH += $(TOP_DIR)
246VPATH += $(TMK_PATH)
247VPATH += $(QUANTUM_PATH)
248VPATH += $(QUANTUM_PATH)/keymap_extras
249VPATH += $(QUANTUM_PATH)/audio
250VPATH += $(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
254ifdef MCU_FAMILY
255 PLATFORM=CHIBIOS
256else
257 PLATFORM=AVR
258endif
259
260include $(TMK_PATH)/common.mk
261ifeq ($(PLATFORM),AVR)
262 include $(TMK_PATH)/protocol/lufa.mk
263 include $(TMK_PATH)/avr.mk
264else ifeq ($(PLATFORM),CHIBIOS)
265 include $(TMK_PATH)/protocol/chibios.mk
266 include $(TMK_PATH)/chibios.mk
267 OPT_OS = chibios
268else
269 $(error Unknown platform)
270endif
271
272ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
273 VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer
274 VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer
275 include $(VISUALIZER_PATH)/visualizer.mk
276endif
277
278include $(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
105ifneq ($(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
115else ifneq ($(SUBPROJECT),)
116 # Inside a subproject folder, build all keymaps for that subproject
117 .DEFAULT_GOAL := $(KEYBOARD)-$(SUBPROJECT)-allkm
118else 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
123endif
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
131define 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
144endef
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
148COMPARE_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
155define 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
163endef
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
169define 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
184endef
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
191define 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
202endef
203
204# Make it easier to call TRY_TO_MATCH_RULE_FROM_LIST
205TRY_TO_MATCH_RULE_FROM_LIST = $(eval $(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER,$1))$(RULE_FOUND)
206
207define ALL_IN_LIST_LOOP
208 OLD_RULE$1 := $$(RULE)
209 $$(eval $$(call $1,$$(ITEM$1)))
210 RULE := $$(OLD_RULE$1)
211endef
212
213define PARSE_ALL_IN_LIST
214 $$(foreach ITEM$1,$2,$$(eval $$(call ALL_IN_LIST_LOOP,$1)))
215endef
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
220define 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
240endef
241
242# $1 = Keyboard
243# Parses a rule in the format <subproject>-<keymap>-<target>
244# the keyboard is already known when entering this function
245define 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
267endef
268
269# if we are going to compile all keyboards, match the rest of the rule
270# for each of them
271define PARSE_ALL_KEYBOARDS
272 $$(eval $$(call PARSE_ALL_IN_LIST,PARSE_KEYBOARD,$(KEYBOARDS)))
273endef
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
278define 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
335endef
336
337# If we want to parse all subprojects, but the keyboard doesn't have any,
338# then use defaultsp instead
339define 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
345endef
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
352define 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;
392endef
393
394# Just parse all the keymaps for a specifc keyboard
395define PARSE_ALL_KEYMAPS
396 $$(eval $$(call PARSE_ALL_IN_LIST,PARSE_KEYMAP,$$(KEYMAPS)))
397endef
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
402define 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
410endef
411
412include $(ROOT_DIR)/message.mk
413
414RUN_COMMAND = \
415$(COMMAND_$(SILENT_MODE)_$(COMMAND))
416
417# Allow specifying just the subproject, in the keyboard directory, which will compile all keymaps
418SUBPROJECTS := $(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
448all: all-keyboards
449
450# Define some shortcuts, mostly for compability with the old syntax
451.PHONY: all-keyboards
452all-keyboards: allkb-allsp-allkm
453
454.PHONY: all-keyboards-defaults
455all-keyboards-defaults: allkb-allsp-default
456
457
458# Generate the version.h file
280GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S") 459GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")
281BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S") 460BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S")
282OPT_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)