@@ -298,17 +298,21 @@ TARGET_LST = $(OBJECT_DIR)/$(FORKNAME)_$(TARGET).lst
298298TARGET_OBJS = $(addsuffix .o,$(addprefix $(OBJECT_DIR ) /$(TARGET ) /,$(basename $(SRC ) ) ) )
299299TARGET_DEPS = $(addsuffix .d,$(addprefix $(OBJECT_DIR ) /$(TARGET ) /,$(basename $(SRC ) ) ) )
300300TARGET_MAP = $(OBJECT_DIR ) /$(FORKNAME ) _$(TARGET ) .map
301+ TARGET_DIRS := $(sort $(dir $(TARGET_OBJS ) ) )
301302
302303CLEAN_ARTIFACTS := $(TARGET_BIN )
303304CLEAN_ARTIFACTS += $(TARGET_HEX )
304305CLEAN_ARTIFACTS += $(TARGET_ELF ) $(TARGET_OBJS ) $(TARGET_MAP )
305306CLEAN_ARTIFACTS += $(TARGET_LST )
306307
307- # Make sure build date and revision is updated on every incremental build
308- $(OBJECT_DIR ) /$(TARGET ) /build/version.o : FORCE
308+ # Rebuild version.o whenever any source changes so the embedded timestamp stays current
309+ $(OBJECT_DIR ) /$(TARGET ) /build/version.o : $( SRC )
309310
310- .PHONY : FORCE clean clean_test clean_all all_clean
311- FORCE :
311+ .PHONY : clean clean_test clean_all all_clean binary_hex
312+
313+ # Build each output directory once, not once-per-file, for parallel-safe compilation
314+ $(TARGET_DIRS ) :
315+ @mkdir -p $@
312316
313317# List of buildable ELF files and their object dependencies.
314318# It would be nice to compute these lists, but that seems to be just beyond make.
@@ -329,15 +333,17 @@ $(TARGET_ELF): $(TARGET_OBJS) $(LD_SCRIPT) $(LD_SCRIPTS)
329333 $(V1 ) $(CROSS_CC ) -o $@ $(filter % .o,$^ ) $(LD_FLAGS )
330334 $(V1 ) $(SIZE ) $(TARGET_ELF )
331335
336+ # .SECONDEXPANSION allows $$(dir $$@) in prerequisites — expands to the target's
337+ # directory at rule instantiation time, wiring each .o to its pre-created dir.
338+ .SECONDEXPANSION :
339+
332340# Compile
333341ifeq ($(DEBUG ) ,GDB)
334- $(OBJECT_DIR ) /$(TARGET ) /% .o : % .c
335- $(V1 ) mkdir -p $(dir $@ )
342+ $(OBJECT_DIR ) /$(TARGET ) /% .o : % .c | $$(dir $$@ )
336343 $(V1 ) echo " %% (debug) $( notdir $< ) " " $( STDOUT) " && \
337344 $(CROSS_CC ) -c -o $@ $(CFLAGS ) $(CC_DEBUG_OPTIMISATION ) $<
338345else
339- $(OBJECT_DIR ) /$(TARGET ) /% .o : % .c
340- $(V1 ) mkdir -p $(dir $@ )
346+ $(OBJECT_DIR ) /$(TARGET ) /% .o : % .c | $$(dir $$@ )
341347 $(V1 ) $(if $(findstring $(subst ./src/main/,,$< ) ,$(SPEED_OPTIMISED_SRC ) ) , \
342348 echo " %% (speed optimised) $( notdir $< ) " " $( STDOUT) " && \
343349 $(CROSS_CC ) -c -o $@ $(CFLAGS ) $(CC_SPEED_OPTIMISATION ) $< , \
@@ -349,13 +355,11 @@ $(OBJECT_DIR)/$(TARGET)/%.o: %.c
349355endif
350356
351357# Assemble
352- $(OBJECT_DIR ) /$(TARGET ) /% .o : % .s
353- $(V1 ) mkdir -p $(dir $@ )
358+ $(OBJECT_DIR ) /$(TARGET ) /% .o : % .s | $$(dir $$@ )
354359 @echo " %% $( notdir $< ) " " $( STDOUT) "
355360 $(V1 ) $(CROSS_CC ) -c -o $@ $(ASFLAGS ) $<
356361
357- $(OBJECT_DIR ) /$(TARGET ) /% .o : % .S
358- $(V1 ) mkdir -p $(dir $@ )
362+ $(OBJECT_DIR ) /$(TARGET ) /% .o : % .S | $$(dir $$@ )
359363 @echo " %% $( notdir $< ) " " $( STDOUT) "
360364 $(V1 ) $(CROSS_CC ) -c -o $@ $(ASFLAGS ) $<
361365
@@ -410,7 +414,7 @@ targets-group-rest: $(GROUP_OTHER_TARGETS)
410414
411415$(VALID_TARGETS ) :
412416 $(V0 ) @echo " Building $@ " && \
413- $(MAKE ) binary hex TARGET=$@ && \
417+ $(MAKE ) binary_hex TARGET=$@ && \
414418 echo " Building $@ succeeded."
415419
416420$(NOBUILD_TARGETS ) :
@@ -481,6 +485,9 @@ binary:
481485hex :
482486 $(V0 ) $(MAKE ) $(TARGET_HEX )
483487
488+ # # binary_hex : build both binary and hex in one sub-make (ELF linked once; BIN+HEX via parallel objcopy)
489+ binary_hex : $(TARGET_BIN ) $(TARGET_HEX )
490+
484491unbrick_$(TARGET ) : $(TARGET_HEX )
485492 $(V0 ) stty -F $(SERIAL_DEVICE ) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
486493 $(V0 ) stm32flash -w $(TARGET_HEX ) -v -g 0x0 -b 115200 $(SERIAL_DEVICE )
0 commit comments