X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tmk_core%2Frules.mk;h=0edf6adf513c871c456df339bdd13fde35a5f1fe;hb=0f95c0865cec9cefde37dcb1bca32360a6741f0d;hp=21011c2808f5898e23026fd6338b32df2791d19f;hpb=d1e4f2eb0838ef400f4f76fc644610d6c8230658;p=qmk_firmware.git diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index 21011c280..0edf6adf5 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -21,18 +21,20 @@ VPATH_SRC := $(VPATH) vpath %.c $(VPATH_SRC) vpath %.h $(VPATH_SRC) vpath %.cpp $(VPATH_SRC) +vpath %.cc $(VPATH_SRC) vpath %.hpp $(VPATH_SRC) vpath %.S $(VPATH_SRC) VPATH := # Convert all SRC to OBJ define OBJ_FROM_SRC -$(patsubst %.c,$1/%.o,$(patsubst %.cpp,$1/%.o,$(patsubst %.S,$1/%.o,$($1_SRC)))) +$(patsubst %.c,$1/%.o,$(patsubst %.cpp,$1/%.o,$(patsubst %.cc,$1/%.o,$(patsubst %.S,$1/%.o,$(patsubst %.clib,$1/%.a,$($1_SRC)))))) endef $(foreach OUTPUT,$(OUTPUTS),$(eval $(OUTPUT)_OBJ +=$(call OBJ_FROM_SRC,$(OUTPUT)))) # Define a list of all objects OBJ := $(foreach OUTPUT,$(OUTPUTS),$($(OUTPUT)_OBJ)) +NO_LTO_OBJ := $(filter %.a,$(OBJ)) MASTER_OUTPUT := $(firstword $(OUTPUTS)) @@ -46,9 +48,6 @@ FORMAT = ihex # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) OPT = s -AUTOGEN ?= false - - # Compiler flag to set the C Standard level. # c89 = "ANSI" C # gnu89 = c89 plus GCC extensions @@ -80,7 +79,9 @@ CSTANDARD = -std=gnu99 # -Wall...: warning level # -Wa,...: tell GCC to pass this to the assembler. # -adhlns...: create assembler listing -CFLAGS += -g$(DEBUG) +ifndef SKIP_DEBUG_INFO + CFLAGS += -g$(DEBUG) +endif CFLAGS += $(CDEFS) CFLAGS += -O$(OPT) # add color @@ -91,6 +92,9 @@ endif endif CFLAGS += -Wall CFLAGS += -Wstrict-prototypes +ifneq ($(strip $(ALLOW_WARNINGS)), yes) + CFLAGS += -Werror +endif #CFLAGS += -mshort-calls #CFLAGS += -fno-unit-at-a-time #CFLAGS += -Wundef @@ -99,7 +103,6 @@ CFLAGS += -Wstrict-prototypes CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst) CFLAGS += $(CSTANDARD) - #---------------- Compiler Options C++ ---------------- # -g*: generate debugging information # -O*: optimization level @@ -107,13 +110,18 @@ CFLAGS += $(CSTANDARD) # -Wall...: warning level # -Wa,...: tell GCC to pass this to the assembler. # -adhlns...: create assembler listing -CPPFLAGS += -g$(DEBUG) +ifndef SKIP_DEBUG_INFO + CPPFLAGS += -g$(DEBUG) +endif CPPFLAGS += $(CPPDEFS) CPPFLAGS += -O$(OPT) # to supress "warning: only initialized variables can be placed into program memory area" CPPFLAGS += -w CPPFLAGS += -Wall CPPFLAGS += -Wundef +ifneq ($(strip $(ALLOW_WARNINGS)), yes) + CPPFLAGS += -Werror +endif #CPPFLAGS += -mshort-calls #CPPFLAGS += -fno-unit-at-a-time #CPPFLAGS += -Wstrict-prototypes @@ -131,8 +139,12 @@ CPPFLAGS += -Wa,-adhlns=$(@:%.o=%.lst) # files -- see avr-libc docs [FIXME: not yet described there] # -listing-cont-lines: Sets the maximum number of continuation lines of hex # dump that will be displayed for a given single line of source input. -ASFLAGS += $(ADEFS) -ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100 +ASFLAGS += $(ADEFS) +ifndef SKIP_DEBUG_INFO + ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100 +else + ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),--listing-cont-lines=100 +endif #---------------- Library Options ---------------- # Minimalistic printf version @@ -160,6 +172,7 @@ SCANF_LIB = MATH_LIB = -lm +CREATE_MAP ?= yes #---------------- Linker Options ---------------- @@ -170,7 +183,10 @@ MATH_LIB = -lm # Comennt out "--relax" option to avoid a error such: # (.vectors+0x30): relocation truncated to fit: R_AVR_13_PCREL against symbol `__vector_12' # -LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref + +ifeq ($(CREATE_MAP),yes) + LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref +endif #LDFLAGS += -Wl,--relax LDFLAGS += $(EXTMEMOPTS) LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) @@ -200,19 +216,23 @@ 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,$@) +define NO_LTO +$(patsubst %.a,%.o,$1): NOLTO_CFLAGS += -fno-lto +endef +$(foreach LOBJ, $(NO_LTO_OBJ), $(eval $(call NO_LTO,$(LOBJ)))) -# Default target. -all: build sizeafter +MOVE_DEP = mv -f $(patsubst %.o,%.td,$@) $(patsubst %.o,%.d,$@) -# Change the build target to build a HEX file or a library. -build: elf hex -#build: elf hex eep lss sym -#build: lib +# Add QMK specific flags +DFU_SUFFIX ?= dfu-suffix +DFU_SUFFIX_ARGS ?= elf: $(BUILD_DIR)/$(TARGET).elf hex: $(BUILD_DIR)/$(TARGET).hex +cpfirmware: $(FIRMWARE_FORMAT) + $(SILENT) || printf "Copying $(TARGET).$(FIRMWARE_FORMAT) to qmk_firmware folder" | $(AWK_CMD) + $(COPY) $(BUILD_DIR)/$(TARGET).$(FIRMWARE_FORMAT) $(TARGET).$(FIRMWARE_FORMAT) && $(PRINT_OK) eep: $(BUILD_DIR)/$(TARGET).eep lss: $(BUILD_DIR)/$(TARGET).lss sym: $(BUILD_DIR)/$(TARGET).sym @@ -220,19 +240,17 @@ LIBNAME=lib$(TARGET).a lib: $(LIBNAME) # Display size of file. -HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex #ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf ELFSIZE = $(SIZE) $(BUILD_DIR)/$(TARGET).elf sizebefore: - @if test -f $(TARGET).hex; then $(SECHO) $(MSG_SIZE_BEFORE); $(SILENT) || $(HEXSIZE); \ + @if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO) $(MSG_SIZE_BEFORE); $(SILENT) || $(HEXSIZE); \ 2>/dev/null; $(SECHO); fi sizeafter: $(BUILD_DIR)/$(TARGET).hex - @if test -f $(TARGET).hex; then $(SECHO); $(SECHO) $(MSG_SIZE_AFTER); $(SILENT) || $(HEXSIZE); \ + @if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO); $(SECHO) $(MSG_SIZE_AFTER); $(SILENT) || $(HEXSIZE); \ 2>/dev/null; $(SECHO); fi - # test file sizes eventually - # @if [[ $($(SIZE) --target=$(FORMAT) $(TARGET).hex | $(AWK) 'NR==2 {print "0x"$5}') -gt 0x200 ]]; then $(SECHO) "File is too big!"; fi # Display compiler version information. gccversion : @@ -243,12 +261,6 @@ gccversion : @$(SILENT) || printf "$(MSG_FLASH) $@" | $(AWK_CMD) $(eval CMD=$(HEX) $< $@) @$(BUILD_CMD) - @if $(AUTOGEN); then \ - $(SILENT) || printf "Copying $(TARGET).hex to keymaps/$(KEYMAP)/$(KEYBOARD)_$(KEYMAP).hex\n"; \ - $(COPY) $@ $(KEYMAP_PATH)/$(KEYBOARD)_$(KEYMAP).hex; \ - else \ - $(COPY) $@ $(TARGET).hex; \ - fi %.eep: %.elf @$(SILENT) || printf "$(MSG_EEPROM) $@" | $(AWK_CMD) @@ -271,6 +283,10 @@ gccversion : @$(SILENT) || printf "$(MSG_BIN) $@" | $(AWK_CMD) $(eval CMD=$(BIN) $< $@ || exit 0) @$(BUILD_CMD) + if [ ! -z "$(DFU_SUFFIX_ARGS)" ]; then \ + $(DFU_SUFFIX) $(DFU_SUFFIX_ARGS) -a $(BUILD_DIR)/$(TARGET).bin 1>/dev/null ;\ + fi + $(COPY) $(BUILD_DIR)/$(TARGET).bin $(TARGET).bin; BEGIN = gccversion sizebefore @@ -282,15 +298,15 @@ BEGIN = gccversion sizebefore @$(SILENT) || printf "$(MSG_LINKING) $@" | $(AWK_CMD) $(eval CMD=$(CC) $(ALL_CFLAGS) $(filter-out %.txt,$^) --output $@ $(LDFLAGS)) @$(BUILD_CMD) - + define GEN_OBJRULE $1_INCFLAGS := $$(patsubst %,-I%,$$($1_INC)) ifdef $1_CONFIG -$1_CONFIG_FLAGS += -include $$($1_CONFIG) +$1_CONFIG_FLAGS += $$(patsubst %,-include %,$$($1_CONFIG)) endif -$1_CFLAGS = $$(ALL_CFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) -$1_CPPFLAGS= $$(ALL_CPPFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) +$1_CFLAGS = $$(ALL_CFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS) +$1_CPPFLAGS= $$(ALL_CPPFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS) $1_ASFLAGS= $$(ALL_ASFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) # Compile: create object files from C source files. @@ -305,7 +321,13 @@ $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 $$($1_CPPFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP)) - @$(BUILD_CMD) + @$$(BUILD_CMD) + +$1/%.o : %.cc $1/%.d $1/cppflags.txt $1/compiler.txt | $(BEGIN) + @mkdir -p $$(@D) + @$$(SILENT) || printf "$$(MSG_COMPILING_CPP) $$<" | $$(AWK_CMD) + $$(eval CMD=$$(CC) -c $$($1_CPPFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP)) + @$$(BUILD_CMD) # Assemble: create object files from assembler source files. $1/%.o : %.S $1/asflags.txt $1/compiler.txt | $(BEGIN) @@ -314,6 +336,12 @@ $1/%.o : %.S $1/asflags.txt $1/compiler.txt | $(BEGIN) $$(eval CMD=$$(CC) -c $$($1_ASFLAGS) $$< -o $$@) @$$(BUILD_CMD) +$1/%.a : $1/%.o + @mkdir -p $$(@D) + @$(SILENT) || printf "Archiving: $$<" | $$(AWK_CMD) + $$(eval CMD=$$(AR) rcs $$@ $$<) + @$$(BUILD_CMD) + $1/force: $1/cflags.txt: $1/force @@ -329,20 +357,22 @@ $1/compiler.txt: $1/force $$(CC) --version | cmp -s - $$@ || $$(CC) --version > $$@ endef +.PRECIOUS: $(MASTER_OUTPUT)/obj.txt $(MASTER_OUTPUT)/obj.txt: $(MASTER_OUTPUT)/force - echo '$(OBJ)' | cmp -s - $$@ || echo '$(OBJ)' > $$@ + echo '$(OBJ)' | cmp -s - $@ || echo '$(OBJ)' > $@ +.PRECIOUS: $(MASTER_OUTPUT)/ldflags.txt $(MASTER_OUTPUT)/ldflags.txt: $(MASTER_OUTPUT)/force - echo '$(LDFLAGS)' | cmp -s - $$@ || echo '$(LDFLAGS)' > $$@ + echo '$(LDFLAGS)' | cmp -s - $@ || echo '$(LDFLAGS)' > $@ # We have to use static rules for the .d files for some reason -DEPS = $(patsubst %.o,%.d,$(OBJ)) +DEPS = $(patsubst %.o,%.d,$(patsubst %.a,%.o,$(OBJ))) # Keep the .d files .PRECIOUS: $(DEPS) # Empty rule to force recompilation if the .d file is missing $(DEPS): - + $(foreach OUTPUT,$(OUTPUTS),$(eval $(call GEN_OBJRULE,$(OUTPUT)))) @@ -360,18 +390,47 @@ show_path: @echo SRC=$(SRC) @echo OBJ=$(OBJ) +objs-size: + for i in $(OBJ); do echo $$i; done | sort | xargs $(SIZE) + +ifeq ($(findstring avr-gcc,$(CC)),avr-gcc) +SIZE_MARGIN = 1024 + +check-size: + $(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) $(CFLAGS) $(OPT_DEFS) tmk_core/common/avr/bootloader_size.c 2> /dev/null | sed -ne '/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0)) + $(eval CURRENT_SIZE=$(shell if [ -f $(BUILD_DIR)/$(TARGET).hex ]; then $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(AWK) 'NR==2 {print $$4}'; else printf 0; fi)) + $(eval FREE_SIZE=$(shell expr $(MAX_SIZE) - $(CURRENT_SIZE))) + $(eval OVER_SIZE=$(shell expr $(CURRENT_SIZE) - $(MAX_SIZE))) + $(eval PERCENT_SIZE=$(shell expr $(CURRENT_SIZE) \* 100 / $(MAX_SIZE))) + if [ $(MAX_SIZE) -gt 0 ] && [ $(CURRENT_SIZE) -gt 0 ]; then \ + $(SILENT) || printf "$(MSG_CHECK_FILESIZE)" | $(AWK_CMD); \ + if [ $(CURRENT_SIZE) -gt $(MAX_SIZE) ]; then \ + printf "\n * $(MSG_FILE_TOO_BIG)"; $(PRINT_ERROR_PLAIN); \ + else \ + if [ $(FREE_SIZE) -lt $(SIZE_MARGIN) ]; then \ + $(PRINT_WARNING_PLAIN); printf " * $(MSG_FILE_NEAR_LIMIT)"; \ + else \ + $(PRINT_OK); $(SILENT) || printf " * $(MSG_FILE_JUST_RIGHT)"; \ + fi \ + fi \ + fi +else +check-size: + echo "(Firmware size check does not yet support $(MCU) microprocessors; skipping.)" +endif + # Create build directory -$(shell mkdir $(BUILD_DIR) 2>/dev/null) +$(shell mkdir -p $(BUILD_DIR) 2>/dev/null) # Create object files directory -$(eval $(foreach OUTPUT,$(OUTPUTS),$(shell mkdir $(OUTPUT) 2>/dev/null))) +$(eval $(foreach OUTPUT,$(OUTPUTS),$(shell mkdir -p $(OUTPUT) 2>/dev/null))) # Include the dependency files. --include $(patsubst %.o,%.d,$(OBJ)) +-include $(patsubst %.o,%.d,$(patsubst %.a,%.o,$(OBJ))) # Listing of phony targets. -.PHONY : all finish sizebefore sizeafter gccversion \ -build elf hex eep lss sym coff extcoff \ +.PHONY : all finish sizebefore sizeafter qmkversion \ +gccversion build elf hex eep lss sym coff extcoff \ clean clean_list debug gdb-config show_path \ -program teensy dfu flip dfu-ee flip-ee dfu-start \ No newline at end of file +program teensy dfu flip dfu-ee flip-ee dfu-start