mcu_base/Makefile

204 lines
5.3 KiB
Makefile

# 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