-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
313 lines (257 loc) · 10.9 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
################################################################################
# Arduino SAMD21 Makefile
#
# Copyright (C) 2018-2019 Allen Wild <allenwild93@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
################################################################################
# If a sketch subdir makefile set SKETCH, use it as an override.
# This lets config.mk define a default sketch, but running make from
# a sketch subdir will take precedence over that.
ifeq ($(SKETCH_FROM_SUBDIR),1)
override SKETCH := $(SKETCH)
endif
# allow for persistent config
-include config.mk
# Logic to figure out sketch name. (unless running make clean)
# S=<something> on the command line overrides everything else
ifneq ($(findstring clean,$(MAKECMDGOALS)),clean)
ifneq ($(S),)
ifeq ($(origin S),command line)
override SKETCH := $(S)
endif
endif
# here we allow SKETCH to be set externally via other means (environment, config.mk)
# if still empty, fall back to S
ifeq ($(SKETCH),)
ifneq ($(S),)
SKETCH := $(S)
endif
endif
# confirm that SKETCH is set
ifeq ($(SKETCH),)
$(error S or SKETCH must be defined to use this Makefile)
endif
endif # clean
# TARGET is typically the sketch name, but could be overridden I guess
TARGET := $(SKETCH)
# Directory Configuration
OBJDIR = obj
CORE = core
# all these directories will be used as CPP include paths, and
# all c/cpp/S sources will be compiled into libcore. However, we don't use -Ilib/core/api, all the API
# header files are expected to be included as "api/Foo.h".
LIBRARIES = variant $(CORE) $(CORE)/api $(CORE)/USB
LIBRARIES += Adafruit_BusIO Adafruit_FreeTouch Adafruit_GFX Adafruit_SH110X Adafruit_ZeroDMA
LIBRARIES += DigitalIO HID Keyboard MPR121 Neostrip PWM RotaryEncoder SPI Timeout Timer Wire
CORESRCDIRS = $(addprefix lib/,$(LIBRARIES))
COREINCS = $(addprefix -I,$(filter-out lib/$(CORE)/api,$(CORESRCDIRS)))
VARIANT_DIR = lib/variant
CMSIS_DIR = lib/CMSIS
SAM_DIR = lib/CMSIS-Atmel
COMPORT ?= /dev/ttyACM0
BOSSAC ?= bossac
BOSSAC_FLAGS = --erase --write --verify --reset --usb-port --port=$(COMPORT)
OS := $(shell uname -s)
ifeq ($(OS),Linux)
RESET_SCRIPT = scripts/reset-arduino-linux.sh -q $(COMPORT)
else
RESET_SCRIPT = scripts/ard-reset-arduino --zero $(COMPORT)
endif
# my bossa-git AUR package sets the version to the Arch pkgver, which is 1.8.rXX.gYYYYYYY since
# there hasn't been a v1.9 tag yet, so figure out the version by checking for the availability
# of the --arduino-erase option
BOSSA_19 := $(shell $(BOSSAC) --help 2>/dev/null | grep -q -e '--arduino-erase' && echo y || echo n)
ifeq ($(BOSSA_19),y)
# we have auto-erase available
BOSSAC_FLAGS := $(filter-out --erase,$(BOSSAC_FLAGS))
# BOSSA v1.8 hard-coded the flash starting address as 0x2000, so the command-line offset
# must be zero (the default) or else the program would get written to 0x4000.
# BOSSA v1.9 doesn't do that, so we must set the offset to 0x2000 or else the bootloader
# will get overwritten, bricking the board.
BOSSAC_FLAGS += --offset=0x2000
endif
# Tools Configuration
TOOLCHAIN_BIN ?=
export CC = $(TOOLCHAIN_BIN)arm-none-eabi-gcc
export CXX = $(TOOLCHAIN_BIN)arm-none-eabi-g++
export AS = $(TOOLCHAIN_BIN)arm-none-eabi-gcc -x assembler-with-cpp
export CCLD = $(TOOLCHAIN_BIN)arm-none-eabi-gcc
export CXXLD = $(TOOLCHAIN_BIN)arm-none-eabi-g++
export AR = $(TOOLCHAIN_BIN)arm-none-eabi-gcc-ar
export OBJCOPY = $(TOOLCHAIN_BIN)arm-none-eabi-objcopy
export OBJDUMP = $(TOOLCHAIN_BIN)arm-none-eabi-objdump
export SIZE = $(TOOLCHAIN_BIN)arm-none-eabi-size
export GDB = $(TOOLCHAIN_BIN)arm-none-eabi-gdb
ifeq ($(NO_SOURCE_VERSION),)
SOURCE_VERSION := $(SKETCH)-$(shell scripts/get_version.sh)
SOURCE_VERSION_FLAG = -DSOURCE_VERSION='"$(SOURCE_VERSION)"'
else
SOURCE_VERSION_FLAG =
endif
# Sketches can set PRINTF_FLOAT=1 to build with this option (adds 12kB)
PRINTF_FLOAT_FLAG = -Wl,--require-defined=_printf_float
LCPPFLAGS = -D__SAMD21G18A__ -DUSBCON $(SOURCE_VERSION_FLAG)
LCPPFLAGS += -I$(SKETCH) $(COREINCS) -I$(CMSIS_DIR)/Include -I$(SAM_DIR)
LCPPFLAGS += -MMD -MP
# used everywhere
CPUFLAGS = -mcpu=cortex-m0plus -mthumb -ggdb3 -Os -pipe
ifneq ($(LTO),0)
CPUFLAGS += -flto
else
$(info >>> LTO is disabled!)
endif
# used in CFLAGS/CXXFLAGS/ASFLAGS, but not LDFLAGS
CCXXFLAGS = $(CPUFLAGS) -Wall -Wextra -Werror
ifeq ($(shell test "$(shell $(CC) -dumpversion | cut -d. -f1)" -ge 7 && echo 1),1)
CCXXFLAGS += -Wno-expansion-to-defined
endif
CCXXFLAGS += -fno-exceptions -ffunction-sections -fdata-sections
LCFLAGS = $(CCXXFLAGS) -std=gnu11
LCXXFLAGS = $(CCXXFLAGS) -std=gnu++14 -fno-rtti -fno-threadsafe-statics
LASFLAGS = $(CCXXFLAGS)
LDSCRIPT ?= $(VARIANT_DIR)/linker_scripts/gcc/flash_with_bootloader.ld
LLDFLAGS = $(CPUFLAGS) -fuse-linker-plugin --specs=nano.specs --specs=nosys.specs
LLDFLAGS += $(if $(filter $(PRINTF_FLOAT),1), $(PRINTF_FLOAT_FLAG))
LLDFLAGS += -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all
LLDFLAGS += -Wl,--warn-common -Wl,--warn-section-align
LLDFLAGS += -Wl,-Map=$(OBJDIR)/$(TARGET).map
LLDFLAGS += -L$(OBJDIR) -L$(CMSIS_DIR)
CORELIB = $(OBJDIR)/libcore.a
LLIBS = -lcore -lm
ifeq ($(CLANG),1)
$(info >>> Building with clang!)
SYSROOT = /usr/arm-none-eabi
CC = clang -target arm-none-eabi --sysroot=$(SYSROOT)
CXX = clang++ -target arm-none-eabi --sysroot=$(SYSROOT)
AR = llvm-ar
CXX_INCDIR := $(shell find $(SYSROOT)/include/c++ -mindepth 1 -maxdepth 1 -type d | tail -n1)
CPUFLAGS := $(filter-out -flto,$(CPUFLAGS))
# turn on -Weverything, then disable a ton of warnings I won't fix
#CCXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-undef
#CCXXFLAGS += -Wno-non-virtual-dtor -Wno-old-style-cast -Wno-zero-as-null-pointer-constant -Wno-padded
#CCXXFLAGS += -Wno-documentation -Wno-gnu-anonymous-struct -Wno-nested-anon-types -Wno-unused-function
#CCXXFLAGS += -Wno-shadow -Wno-shadow-field-in-constructor -Wno-c++14-binary-literal
#CCXXFLAGS += -Wno-c99-extensions -Wno-global-constructors -Wno-weak-vtables -Wno-sign-conversion -Wno-conversion
#CCXXFLAGS += -Wno-error
# GNU linker expects short enums, but clang uses 32 bits by default
# clang wrongly thinks some symbol-aliased functions are unused
CCXXFLAGS += -fshort-enums -Wno-unused-function
LCXXFLAGS += -I$(CXX_INCDIR) -I$(CXX_INCDIR)/arm-none-eabi
endif # clang
# include sketch-specific config after setting all the compile flags
# and such. Here sketches can override/append all the stuff set above
-include $(SKETCH)/config.mk
define override_flags
override $(1) := $$(strip $$(L$(1)) $$($(1)))
endef
$(foreach f,CPPFLAGS CFLAGS CXXFLAGS ASFLAGS LDFLAGS LIBS,$(eval $(call override_flags,$(f))))
# don't look for a sketch when running make clean
ifneq ($(findstring clean,$(MAKECMDGOALS)),clean)
ifneq ($(findstring newsketch,$(MAKECMDGOALS)),newsketch)
TARGET_CC_SRC = $(notdir $(wildcard $(SKETCH)/*.c))
TARGET_CXX_SRC = $(notdir $(wildcard $(SKETCH)/*.cpp))
TARGET_AS_SRC = $(notdir $(wildcard $(SKETCH)/*.S))
TARGET_OBJ = $(patsubst %.cpp,$(OBJDIR)/%.o,$(TARGET_CXX_SRC)) \
$(patsubst %.c,$(OBJDIR)/%.o,$(TARGET_CC_SRC)) \
$(patsubst %.S,$(OBJDIR)/%.o,$(TARGET_AS_SRC))
ifeq ($(strip $(TARGET_OBJ)),)
$(error No source files found for sketch $(SKETCH))
endif
endif
endif
CORE_CC_SRC = $(foreach dir,$(CORESRCDIRS),$(notdir $(wildcard $(dir)/*.c)))
CORE_CXX_SRC = $(foreach dir,$(CORESRCDIRS),$(notdir $(wildcard $(dir)/*.cpp)))
CORE_AS_SRC = $(foreach dir,$(CORESRCDIRS),$(notdir $(wildcard $(dir)/*.S)))
CORE_OBJ = $(patsubst %.cpp,$(OBJDIR)/%.o,$(CORE_CXX_SRC)) \
$(patsubst %.c,$(OBJDIR)/%.o,$(CORE_CC_SRC)) \
$(patsubst %.S,$(OBJDIR)/%.o,$(CORE_AS_SRC))
# "system" objects to link explicitly rather than via libcore.h
SYS_OBJ = $(addprefix $(OBJDIR)/,cortex_handlers.o main.o startup.o variant.o)
CORE_OBJ := $(filter-out $(SYS_OBJ),$(CORE_OBJ))
TARGET_ELF = $(OBJDIR)/$(TARGET).elf
TARGET_BIN = $(OBJDIR)/$(TARGET).bin
TARGET_HEX = $(OBJDIR)/$(TARGET).hex
V ?= 0
_V_CC_0 = @echo " CC " $<;
_V_CXX_0 = @echo " CXX " $<;
_V_AS_0 = @echo " AS " $<;
_V_LD_0 = @echo " LD " $@;
_V_AR_0 = @echo " AR " $@;
_V_BIN_0 = @echo " BIN " $@;
_V_HEX_0 = @echo " HEX " $@;
_V_SIZE_0 = @echo "Program Size:";
_V_RESET_0 = @echo " RESET " $(COMPORT);
_V_UPLOAD_0 = @echo " UPLOAD " $<;
_V_CLEAN_0 = @echo " CLEAN";
_V_DISTCLEAN_0 = @echo " DISTCLEAN";
vpath %.c $(SKETCH) $(CORESRCDIRS)
vpath %.cpp $(SKETCH) $(CORESRCDIRS)
vpath %.S $(SKETCH) $(CORESRCDIRS)
.PHONY: all
all: $(TARGET_BIN) .size_done
SIZE_CMD = $(_V_SIZE_$(V))scripts/print-size.py -q $(TARGET_ELF)
.PHONY: size
size: $(TARGET_ELF) | $(TARGET_BIN)
$(SIZE_CMD)
.size_done: $(TARGET_ELF) | $(TARGET_BIN)
$(SIZE_CMD)
@touch $@
.PHONY: upload
upload: $(TARGET_BIN) all
$(_V_RESET_$(V))$(RESET_SCRIPT)
$(_V_UPLOAD_$(V))$(BOSSAC) $(BOSSAC_FLAGS) $<
.PHONY: clean
clean:
$(_V_CLEAN_$(V))rm -rf $(OBJDIR) .size_done
.PHONY: distclean
distclean: clean
$(_V_DISTCLEAN_$(V))rm -f config.mk
.PHONY: config
config:
if [ -f config.mk ]; then sed -i '/^SKETCH\b/d' config.mk; fi
echo 'SKETCH = $(SKETCH)' >>config.mk
.PHONY: gdb
gdb: $(TARGET_ELF)
$(GDB) -q $(TARGET_ELF) -ex "target extended-remote :2331" -ex "load" -ex "mon reset"
.PHONY: newsketch
newsketch:
mkdir $(SKETCH)
cp lib/sketch-template.cpp $(SKETCH)/$(SKETCH).cpp
ln -s ../lib/Makefile.sketch $(SKETCH)/Makefile
.PHONY: dis
dis: $(TARGET_ELF)
@$(OBJDUMP) -dC $(TARGET_ELF)
.PHONY: disvim
disvim: $(TARGET_ELF)
$(OBJDUMP) -dC $(TARGET_ELF) | vim -R -c ':set ft=asm' -
.PHONY: hex
hex: $(TARGET_HEX)
$(TARGET_ELF): $(TARGET_OBJ) $(SYS_OBJ) $(CORELIB) $(LDSCRIPT)
+$(_V_LD_$(V))$(CXXLD) $(LDFLAGS) -T$(LDSCRIPT) -o $@ $(TARGET_OBJ) $(SYS_OBJ) -Wl,--as-needed $(LIBS)
$(TARGET_BIN): $(TARGET_ELF)
$(_V_BIN_$(V))$(OBJCOPY) -O binary $< $@
$(TARGET_HEX): $(TARGET_ELF)
$(_V_HEX_$(V))$(OBJCOPY) -O ihex $< $@
$(OBJDIR):
@mkdir -p $@
$(OBJDIR)/%.o: %.c | $(OBJDIR)
$(_V_CC_$(V))$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.cpp | $(OBJDIR)
$(_V_CXX_$(V))$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.S | $(OBJDIR)
$(_V_AS_$(V))$(AS) $(CPPFLAGS) $(ASFLAGS) -c -o $@ $<
$(CORELIB): $(CORE_OBJ)
$(_V_AR_$(V))$(AR) rcs $@ $^
-include $(wildcard $(OBJDIR)/*.d)