+DFU_UTIL ?= dfu-util
+ST_LINK_CLI ?= st-link_cli
+
+# Generate a .qmk for the QMK-FF
+qmk: $(BUILD_DIR)/$(TARGET).bin
+ zip $(TARGET).qmk -FSrj $(KEYMAP_PATH)/*
+ zip $(TARGET).qmk -u $<
+ printf "@ $<\n@=firmware.bin\n" | zipnote -w $(TARGET).qmk
+ printf "{\n \"generated\": \"%s\"\n}" "$$(date)" > $(BUILD_DIR)/$(TARGET).json
+ if [ -f $(KEYBOARD_PATH_5)/info.json ]; then \
+ jq -s '.[0] * .[1]' $(BUILD_DIR)/$(TARGET).json $(KEYBOARD_PATH_5)/info.json | ex -sc 'wq!$(BUILD_DIR)/$(TARGET).json' /dev/stdin; \
+ fi
+ if [ -f $(KEYBOARD_PATH_4)/info.json ]; then \
+ jq -s '.[0] * .[1]' $(BUILD_DIR)/$(TARGET).json $(KEYBOARD_PATH_4)/info.json | ex -sc 'wq!$(BUILD_DIR)/$(TARGET).json' /dev/stdin; \
+ fi
+ if [ -f $(KEYBOARD_PATH_3)/info.json ]; then \
+ jq -s '.[0] * .[1]' $(BUILD_DIR)/$(TARGET).json $(KEYBOARD_PATH_3)/info.json | ex -sc 'wq!$(BUILD_DIR)/$(TARGET).json' /dev/stdin; \
+ fi
+ if [ -f $(KEYBOARD_PATH_2)/info.json ]; then \
+ jq -s '.[0] * .[1]' $(BUILD_DIR)/$(TARGET).json $(KEYBOARD_PATH_2)/info.json | ex -sc 'wq!$(BUILD_DIR)/$(TARGET).json' /dev/stdin; \
+ fi
+ if [ -f $(KEYBOARD_PATH_1)/info.json ]; then \
+ jq -s '.[0] * .[1]' $(BUILD_DIR)/$(TARGET).json $(KEYBOARD_PATH_1)/info.json | ex -sc 'wq!$(BUILD_DIR)/$(TARGET).json' /dev/stdin; \
+ fi
+ zip $(TARGET).qmk -urj $(BUILD_DIR)/$(TARGET).json
+ printf "@ $(TARGET).json\n@=info.json\n" | zipnote -w $(TARGET).qmk
+
+define EXEC_DFU_UTIL
+ until $(DFU_UTIL) -l | grep -q "Found DFU"; do\
+ echo "Error: Bootloader not found. Trying again in 5s." ;\
+ sleep 5 ;\
+ done
+ $(DFU_UTIL) $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin
+endef
+
+dfu-util: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter
+ $(call EXEC_DFU_UTIL)
+
+# Legacy alias
+dfu-util-wait: dfu-util
+
+st-link-cli: $(BUILD_DIR)/$(TARGET).hex sizeafter
+ $(ST_LINK_CLI) $(ST_LINK_ARGS) -q -c SWD -p $(BUILD_DIR)/$(TARGET).hex -Rst
+
+
+# Autodetect teensy loader
+ifndef TEENSY_LOADER_CLI
+ ifneq (, $(shell which teensy-loader-cli 2>/dev/null))
+ TEENSY_LOADER_CLI ?= teensy-loader-cli
+ else
+ TEENSY_LOADER_CLI ?= teensy_loader_cli
+ endif
+endif
+
+define EXEC_TEENSY
+ $(TEENSY_LOADER_CLI) -mmcu=$(MCU_LDSCRIPT) -w -v $(BUILD_DIR)/$(TARGET).hex
+endef
+
+teensy: $(BUILD_DIR)/$(TARGET).hex cpfirmware sizeafter
+ $(call EXEC_TEENSY)
+
+bin: $(BUILD_DIR)/$(TARGET).bin sizeafter
+ $(COPY) $(BUILD_DIR)/$(TARGET).bin $(TARGET).bin;
+
+
+flash: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter
+ifeq ($(strip $(BOOTLOADER)),dfu)
+ $(call EXEC_DFU_UTIL)
+else ifeq ($(strip $(MCU_FAMILY)),KINETIS)
+ $(call EXEC_TEENSY)
+else ifeq ($(strip $(MCU_FAMILY)),STM32)
+ $(call EXEC_DFU_UTIL)
+else
+ $(PRINT_OK); $(SILENT) || printf "$(MSG_FLASH_BOOTLOADER)"
+endif