# Top-level Makefile # Current development directory path -include Makefile.opts ifeq ($(MCU),) $(error Must set 'MCU' in Makefile.opts; see 'BUILD' file) endif # Toolchain - Don't change this unless you are sure what you're doing! TOOLCHAIN_CONFIG=toolchain-$(MCU_CORE).config TOOLCHAIN_SRC_DIR=crosstool-ng CROSS_DIR ?= ${HOME}/x-tools/arm-$(MCU_CORE)_v3a-eabi CROSS_COMPILE ?= ${CROSS_DIR}/bin/arm-$(MCU_CORE)_v3a-eabi- CC=$(CROSS_COMPILE)gcc CXX=$(CROSS_COMPILE)g++ CPP=$(CROSS_COMPILE)cpp LD=$(CROSS_COMPILE)gcc OBJCOPY=$(CROSS_COMPILE)objcopy AR=$(CROSS_COMPILE)gcc-ar RANLIB=$(CROSS_COMPILE)gcc-ranlib AS=$(CROSS_COMPILE)as GDB=$(CROSS_COMPILE)gdb SIZE=$(CROSS_COMPILE)size NM=$(CROSS_COMPILE)nm RM=rm ECHO=echo HOSTCC ?= gcc MAKE ?= make # How many processor cores we can use for builds JLEVEL:=${shell cat /proc/cpuinfo |grep processor |wc -l} # Libraries LIBDIR=libs # Generic CMSIS include: MCU_INCLUDE += -I$(LIBDIR)/CMSIS/Include # Compiler flags CFLAGS += -pipe -Wall -Wextra -g -Os -std=c99 $(MCU_CFLAGS) $(TARGET_CFLAGS) CXXFLAGS += -pipe -Wall -Wextra -g -Os -std=c++03 $(MCU_CXXFLAGS) $(TARGET_CXXFLAGS) CPPFLAGS += $(MCU_INCLUDE) $(INCLUDE) $(MCU_CPPFLAGS) $(TARGET_CPPFLAGS) LDCPPFLAGS += -DMCU=$(MCU) -DMCU_SUBTYPE=$(MCU_SUBTYPE) $(TARGET_LDCPPFLAGS) # Linker Flags LDFLAGS += -nostartfiles -fno-exceptions -ffunction-sections -fdata-sections -specs=nosys.specs # Use LTO? ifneq ($(USE_LTO),) CFLAGS += -flto # -ffat-lto-objects CXXFLAGS += -flto # -ffat-lto-objects LDFLAGS += -fuse-linker-plugin -flto=$(JLEVEL) $(CFLAGS) else CFLAGS += -ffunction-sections CXXFLAGS += -ffunction-sections LDFLAGS += -fwhole-program endif # Try and pretty things up a bit. Q=@ E=echo ifeq ($(V), 1) Q= E=true endif # Now for the image definition IMAGE = $(MCU)-main # Initial Makefile targets all: .toolchain version $(IMAGE).bin .PHONY: clean libclean distclean version dep .PRECIOUS: %.elf %.ld %.a # Include library targets include $(LIBDIR)/$(MCU).mk include $(LIBDIR)/math.mk include $(LIBDIR)/freertos.mk # Include application targets include src/build.mk # Bookeeping VERSION_H = inc/version.h VERSION = `./git-version-gen /dev/null` # Set up the libraries we need LIBRARIES += $(LIBDIR)/lib$(MCU).a LIBS_OBJS += $(MCU_LIBS_OBJS) $(LIBDIR)/lib$(MCU).a: $(MCU_LIBS_OBJS) @$(E) " AR " $@ $(Q)$(AR) cr $@ $^ # Generic compilation rules %.ld: libs/$(MCU).ld.in inc/$(MCU)_hw.h @$(E) " GENERATE " $@ $(Q)$(CPP) $(LDCPPFLAGS) -include inc/$(MCU)_hw.h libs/$(MCU).ld.in -P -o $@ %.bin: %.elf @$(E) " OBJCOPY " $@ $(Q)$(OBJCOPY) -O binary $< --remove-section .note.gnu.build-id $@ # Dependency tracking -include $(SRC_OBJS:.o=.d) -include $(LIBS_OBJS:.o=.d) %.o: %.c Makefile.opts $(VERSION_H) # These last two are ... special @$(E) " CC " $< $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) -MM $< > $(@:.o=.dt) $(Q)sed -e 's|.*:|$*.o:|' < $*.dt > $*.d $(Q)sed -e 's/.*://' -e 's/\\$$//' < $*.dt | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d @$(RM) -f $*.dt $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ %.o: %.cpp Makefile.opts $(VERSION_H) # These last two are ... special @$(E) " CX " $< $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $< > $(@:.o=.dt) $(Q)sed -e 's|.*:|$*.o:|' < $*.dt > $*.d $(Q)sed -e 's/.*://' -e 's/\\$$//' < $*.dt | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d @$(RM) -f $*.dt $(Q)$(CC) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ %.elf: %.ld $(LIBRARIES) $(PROGRAM_LIBS) @$(E) " LINK " $@ $(Q)$(CC) -o $@ $(LDFLAGS) \ -Wl,--gc-sections \ -Wl,-T$(@:.elf=.ld) \ -Wl,--no-whole-archive \ $(PROGRAM_LIBS) $(LIBRARIES) \ -Wl,--build-id=none \ -Wl,-Map=$(@:.elf=.map) $(Q)$(SIZE) $@ cppcheck: cppcheck --std=c99 -q -v --enable=all $(CPPFLAGS) $(SRC_OBJS:.o=.c) $(LIBS_OBJS:.o=.c) # Cleanup clean: @$(E) " CLEAN " $(Q)$(RM) -f $(SRC_OBJS) src/*.a $(IMAGE).{bin,elf,ld,map} libclean: @$(E) " LIBCLEAN " $(Q)$(RM) -f $(LIBS_OBJS) $(LIBRARIES) distclean: clean libclean @$(E) " DISTCLEAN" $(Q)$(RM) -f $(DEPFILE) $(VERSION_H) $(Q)$(RM) -Rf $(TOOLCHAIN_SRC_DIR)/.build $(Q)if [ -r $(TOOLCHAIN_SRC_DIR)/Makefile ] ; then \ cd $(TOOLCHAIN_SRC_DIR) ; \ MAKELEVEL='' $(MAKE) clean ; \ MAKELEVEL='' $(MAKE) distclean ; \ fi @$(RM) -f .toolchain-$(MCU_CORE) $(Q)$(RM) -f tags TAGS # Toolchain .toolchain: .toolchain-$(MCU_CORE) .toolchain-$(MCU_CORE): $(Q)if [ ! -x $(CROSS_COMPILE)gcc ] ; then \ ( unset AS LD LDD CC CPP AR NM STRIP STRIPTOOL OBJCOPY OBJDUMP RANLIB LD_LIBRARY_PATH MAKELEVEL ; \ if [ -r $(TOOLCHAIN_SRC_DIR)/$(TOOLCHAIN_CONFIG) ] ; then \ cp $(TOOLCHAIN_SRC_DIR)/$(TOOLCHAIN_CONFIG) $(TOOLCHAIN_SRC_DIR)/.config ; \ else \ $(ECHO) "$(TOOLCHAIN_CONFIG) missing! Exiting." ; \ exit 1 ;\ fi ; \ $(RM) -Rf $(TOOLCHAIN_SRC_DIR)/.build ; \ cd $(TOOLCHAIN_SRC_DIR) ; \ ./configure --enable-local && \ $(MAKE) && \ ./ct-ng build ; \ cd - ) ; \ fi @if [ ! -x $(CROSS_COMPILE)gcc ] ; then \ $(ECHO) "Toolchain Build failed!" ; \ exit 1 ;\ fi @touch .toolchain-$(MCU_CORE) toolclean: $(Q)if [ -d $(CROSS_DIR) ] ; then \ chmod -R +w $(CROSS_DIR) ; \ $(RM) -fr $(CROSS_DIR) ; \ fi @$(RM) -f .toolchain-$(MCU_CORE) # For saner developers tags: find . -path '*crosstool*' -prune \ -o -name '*.[CHch]' -type f -print \ | etags - # Automagic version strings version: # @$(E) " VERSION " $(VERSION_H) $(Q)./git-version-gen $(VERSION_H) $(APP) > /dev/null