204 lines
5.3 KiB
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
|