Skip to content

Instantly share code, notes, and snippets.

@ag88
Last active December 23, 2019 05:31
Show Gist options
  • Save ag88/a6a02acbc7e681ebd682c87c0f310268 to your computer and use it in GitHub Desktop.
Save ag88/a6a02acbc7e681ebd682c87c0f310268 to your computer and use it in GitHub Desktop.
libmaple Makefile v0 alpha
# version 0 (alpha)
#
# This make file for libmaple core is possibly *dangerous*
# i.e. it compiles the sources (in src and STM32F1) directory
# and overwrite all the stuff in $(out_dir)
# $(out_dir) is the binary directory where the object files are dumped there
#
# make clean *deletes* the *$(out_dir)* (coded here as bin )
#
# this is a relative path makefile
# the directory structure needs to be
# Root
# +-- src (your sources e.g. the sketch
# | the files has to be cpp, c or h, no ino)
# |
# +-- STM32F1 (copy from the libmaple core)
# |
# +-- Makefile (this makefile)
#
# the make needs to be run from the root of this file structure
# the make is relative path from this Root
# generated object files and binaries (elf, bin) are placed into the
# $(out_dir) - bin
#
# make clean - *deletes* $(out_dir)
#
# make all - starts the build
#
# Lic: public domain
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# this folder is deleted with make clean
out_dir := bin
# this is the name of the subdirectory under STM32F1/variants
# it needs to match, this caters to a single variant
variant := maple_mini
# these are the defines passed to gcc, g++ and the assembler
# use += to add more definitions
defines := MCU_STM32F103CB
defines += __STM32F1__
defines += VECT_TAB_ADDR=0x8002000
defines += CONFIG_MAPLE_MINI_NO_DISABLE_DEBUG
defines += DEBUG_LEVEL=DEBUG_NONE
defines += F_CPU=72000000L
defines += SERIAL_USB
defines += USB_VID=0x1EAF
defines += USB_PID=0x0004
defines += USB_MANUFACTURER=\"Unknown\"
# source directories
# these are the initial directories to search for sources
# relative to this build (root) directory
# if you use libraries either put them in a sub-directory in src
srcdir := src
# or add it here
#srcdir += library1
#srcdir += library2
# points to the root folder of stm32duino libmaple core
# this should be 1 level above STM32F1 folder
# use of this is not encouraged, it is safer to copy the STM32F1
# folder into the current directory
# omit the final slash after the directory
core_root := .
# these are the source directories for the libmaple core
# and variant, normally they stay unchanged
# if you want to place the libmaple core directory somewhere else,
# define core_root above
coredir := $(core_root)/STM32F1/cores/maple
variantdir += $(core_root)/STM32F1/variants/$(variant)
coredir += $(variantdir)
#this is the ld script in STM32F1/variants/$(variant)/ld to use
ldscript := bootloader_20.ld
#the includes i.e. the -Ipath needs to be exlicitly stated
#no automatic recursive searching
#if you use libraries you may want to add it here
includedir += STM32F1/cores/maple/
includedir += STM32F1/system/libmaple/
includedir += STM32F1/system/libmaple/include/
includedir += STM32F1/system/libmaple/stm32f1/include/series/
includedir += STM32F1/system/libmaple/usb/stm32f1/
includedir += STM32F1/system/libmaple/usb/usb_lib/
includedir += STM32F1/variants/maple_mini/
#if you use core_root, you would need to add that as a prefix
#includedir := $(addprefix $(core_root)/,$(includedir))
# update this to match
# this should be the install base location of ARM_NONE_EABI_GCC toolchain
ARM_NONE_EABI_PATH := /opt5/opt/gcc-arm-none-eabi-6-2017-q1-update
# this should be the location of the arm standard libraries c & c++
# the arm-none-eabi/lib select the folder matching the arch
# compile options e.g. thumb and v7-m
LD_TOOLCHAIN_PATH := $(ARM_NONE_EABI_PATH)/arm-none-eabi/lib/thumb/v7-m
# recursive wildcard function, call with params:
# - start directory (finished with /) or empty string for current dir
# - glob pattern
# (taken from http://blog.jgc.org/2011/07/gnu-make-recursive-wildcard-function.html)
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
cfiles := $(strip $(foreach s, $(srcdir), $(call rwildcard,$(s),*.c)))
cxxfiles := $(strip $(foreach s, $(srcdir), $(call rwildcard,$(s),*.cpp)))
asfiles := $(strip $(foreach s, $(srcdir), $(call rwildcard,$(s),*.S)))
core_cfiles += $(subst $(core_root)/,,$(strip $(foreach s, $(coredir), $(call rwildcard,$(s),*.c))))
core_cxxfiles += $(subst $(core_root)/,,$(strip $(foreach s, $(coredir), $(call rwildcard,$(s),*.cpp))))
core_asfiles += $(subst $(core_root)/,,$(strip $(foreach s, $(coredir), $(call rwildcard,$(s),*.S))))
src_files := $(cfiles) $(cxxfiles) $(asfiles)
core_files := $(core_cfiles) $(core_cxxfiles) $(core_asfiles)
files := $(src_files) $(core_files)
sdirs := $(sort $(dir $(files)))
#hfiles := $(foreach s, $(includedir), $(call rwildcard,$(s),*.h))
#hfiles += $(foreach s, $(srcdir), $(call rwildcard,$(s),*.h))
#incdirs = $(sort $(dir $(hfiles)))
TOOLPREFIX := arm-none-eabi-
CC = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)gcc
CXX = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)g++
AS = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)as
OBJCOPY = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)objcopy
OBJDUMP = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)objdump
AR = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)ar
SIZE = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)size
NM = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)nm
LD = $(ARM_NONE_EABI_PATH)/bin/$(TOOLPREFIX)ld
RM = /usr/bin/rm
MKDIR = /usr/bin/mkdir -p
TEST = /usr/bin/test
DEFINES := $(addprefix -D,$(defines))
INCLUDES := $(addprefix -I,$(includedir))
#optimise
# -O0 - none
# -Os - optimise size
# -O1 - optimise
# -O2 - optimise more
# -O3 - optimise most
# -Og - optimise debug
OFLAG := -Os
#debug
# default none
# -g - debug
# -g1 - minimal
# -g3 - maximal
DFLAG = -g1
COMMON_OFLAGS := -Wl,--gc-sections $(OFLAG) $(DFLAG) \
-ffunction-sections -fdata-sections \
-fmessage-length=0 -fsigned-char \
-ffreestanding -fno-move-loop-invariants \
--specs=nano.specs -Wall -Wextra
TARGET_FLAGS += -mcpu=cortex-m3 -march=armv7-m -mthumb \
$(INCLUDES) $(DEFINES)
GLOBAL_CFLAGS := $(COMMON_OFLAGS) $(TARGET_FLAGS)
TARGET_CFLAGS :=
GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions \
-fno-use-cxa-atexit -fno-threadsafe-statics \
$(COMMON_OFLAGS) \
$(TARGET_FLAGS)
TARGET_CXXFLAGS :=
GLOBAL_ASFLAGS := $(TARGET_FLAGS)
#TARGET_ASFLAGS := -Wl,--gc-sections $(OFLAG) $(DFLAG) -Xassembler -Wall
TARGET_ASFLAGS := -Wl,--gc-sections $(OFLAG) $(DFLAG)
LD_SCRIPT_PATH := $(variantdir)/ld/$(ldscript)
# -nostdlib
# -nodefaultlibs
# -nostartfiles
# -Wl,--gc-sections
GLOBAL_LDFLAGS := --specs=nano.specs \
-Xlinker --gc-sections
TARGET_LDFLAGS := -Xlinker -T$(LD_SCRIPT_PATH) \
-mcpu=cortex-m3 -mthumb -march=armv7-m \
-L $(variantdir)/ld
CFLAGS = $(GLOBAL_CFLAGS) $(TARGET_CFLAGS)
CXXFLAGS = $(GLOBAL_CXXFLAGS) $(TARGET_CXXFLAGS)
CPPFLAGS =
ASFLAGS = $(GLOBAL_ASFLAGS) $(TARGET_ASFLAGS)
# Add toolchain directory to LD search path
TOOLCHAIN_LDFLAGS := -L $(LD_TOOLCHAIN_PATH)
LDFLAGS = $(GLOBAL_LDFLAGS) $(TARGET_LDFLAGS) $(TOOLCHAIN_LDFLAGS)
#build lists of object files relative to $(out_dir)
COBJS = $(addprefix $(out_dir)/,$(patsubst %.c,%.o,$(cfiles)))
CXXOBJS = $(addprefix $(out_dir)/,$(patsubst %.cpp,%.o,$(cxxfiles)))
ASOBJS = $(addprefix $(out_dir)/,$(patsubst %.S,%.o,$(asfiles)))
CORE_COBJS = $(addprefix $(out_dir)/,$(patsubst %.c,%.o,$(core_cfiles)))
CORE_CXXOBJS = $(addprefix $(out_dir)/,$(patsubst %.cpp,%.o,$(core_cxxfiles)))
CORE_ASOBJS = $(addprefix $(out_dir)/,$(patsubst %.S,%.o,$(core_asfiles)))
variant.ELF = $(out_dir)/$(variant).elf
variant.BIN = $(out_dir)/$(variant).bin
.PHONY: all clean mkdir
all: mkdir $(variant.BIN)
@echo
@$(SIZE) $(variant.ELF)
@echo
@ls -l $(variant.BIN)
@echo
@$(OBJDUMP) --section-headers $(variant.ELF)
@echo
@echo Source dirs
@echo $(srcdir) $(coredir) | sed 's/ /\n/g'
@echo
@echo $(sort $(dir $(src_files))) | sed 's/ /\n/g'
@echo $(addprefix $(core_root)/,$(sort $(dir $(core_files)))) | sed 's/ /\n/g'
@echo
@echo Includes
@echo $(INCLUDES) | sed 's/ /\n/g'
@echo
@echo Defines
@echo $(DEFINES) | sed 's/ /\n/g'
$(variant.BIN): $(variant.ELF)
$(OBJCOPY) -v -Obinary $(variant.ELF) $@
$(variant.ELF): $(ASOBJS) $(COBJS) $(CXXOBJS) \
$(CORE_COBJS) $(CORE_CXXOBJS) $(CORE_ASOBJS)
$(CXX) $(LDFLAGS) -o $@ -Wl,-Map,$(out_dir)/$(variant).map $+
# General directory independent build rules, generate dependency information
$(COBJS): $(out_dir)/%.o: %.c
$(CC) $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $<
$(CXXOBJS): $(out_dir)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $<
$(ASOBJS): $(out_dir)/%.o: %.S
$(CC) $(ASFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $<
$(CORE_COBJS): $(out_dir)/%.o: $(core_root)/%.c
$(CC) $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $<
$(CORE_CXXOBJS): $(out_dir)/%.o: $(core_root)/%.cpp
$(CXX) $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $<
$(CORE_ASOBJS): $(out_dir)/%.o: $(core_root)/%.S
$(CC) $(ASFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $<
# create the build directories
tgtdirs := $(addsuffix .dir,$(addprefix $(out_dir)/,$(sdirs)))
mkdir: $(tgtdirs)
# the .dir file is a marker file that the directory is created
$(tgtdirs) : $(out_dir)/.dir
$(MKDIR) $(dir $@)
@touch $@
$(out_dir)/.dir:
$(MKDIR) $(dir $@)
@touch $@
clean:
@echo clean
$(RM) -r $(out_dir)
DEPENDS := $(COBJS:%.o=%.d) $(CXXOBJS:%.o=%.d) $(ASOBJS:%.o=%.d)
DEPENDS += $(CORE_COBJS:%.o=%.d) $(CORE_CXXOBJS:%.o=%.d) $(CORE_ASOBJS:%.o=%.d)
-include $(DEPENDS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment