-
Notifications
You must be signed in to change notification settings - Fork 90
/
AppMakefile.mk
413 lines (335 loc) · 19.3 KB
/
AppMakefile.mk
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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
################################################################################
##
## libtock-c main build system Makefile.
##
## Individual applications use this Makefile to invoke the compiler and create
## Tock apps.
##
## This Makefile works by generating at runtime the rules necessary to build the
## libtock-c app for all desired architectures, then running each of those rules
## to create the compiled output. Each architecture-specific compiled binary is
## then combined into a single Tock TAB file.
##
################################################################################
# The first target Make finds is its default. So this line needs to be first to
# specify `all` as our default rule
all:
# Directory for built output.
BUILDDIR ?= build
# Build settings.
include $(TOCK_USERLAND_BASE_DIR)/Configuration.mk
# Helper functions.
include $(TOCK_USERLAND_BASE_DIR)/Helpers.mk
# Targets for fetching pre-compiled libraries.
include $(TOCK_USERLAND_BASE_DIR)/Precompiled.mk
# Include the libtock makefile. Adds rules that will rebuild the core libtock
# library when needed.
include $(TOCK_USERLAND_BASE_DIR)/libtock/Makefile
# Include the libtock-sync Makefile. Adds rules that will rebuild the core
# libtock-sync library when needed.
include $(TOCK_USERLAND_BASE_DIR)/libtock-sync/Makefile
# Include the makefile that has the programming functions for each board.
include $(TOCK_USERLAND_BASE_DIR)/Program.mk
# Rules to call library makefiles to build required libraries.
#
# We support an optional Makefile.setup which is responsible for retrieving the
# source used to build the library.
#
# Secret sauce: For this rule to work, make must treat the targets as a group.
# For make to do that, the targets must use the `%` wildcard, and that wildcard
# MUST expand to the same value for every target. To ensure this, we use the
# build directory for the library as the `%` expansion.
#
# Arguments:
# - $(1): Pattern matching all arch-specific library files.
# - $(2): The path to the library.
define EXTERN_LIB_BUILD_RULE
ifneq "$$(wildcard $(2)/Makefile.setup)" ""
# Since a Makefile.setup exists, do any setup steps needed to fetch the library.
$(1):
$$(MAKE) -C $(2) -f Makefile.setup all
$$(MAKE) -C $(2) -f Makefile all
else
$(1):
$$(MAKE) -C $(2) -f Makefile all
endif
endef
# Rules to incorporate external libraries
define EXTERN_LIB_RULES
EXTERN_LIB_NAME_$(notdir $(1)) := $(notdir $(1))
# If this library has any additional rules, add them
-include $(1)/Makefile.app
# If this library has an include directory, add it to search path
ifneq "$$(wildcard $(1)/include)" ""
override CPPFLAGS += -I$(1)/include
endif
# Add arch-specific dependencies for the library to ensure the library is built.
# Use the $(LIBNAME)_BUILDDIR as build directory, if set.
$$(notdir $(1))_BUILDDIR ?= $(1)/build
$$(foreach arch, $$(TOCK_ARCHS), $$(eval LIBS_$$(arch) += $$($(notdir $(1))_BUILDDIR)/$$(arch)/$(notdir $(1)).a))
# Generate rule for building the library.
# $$(info $$(call EXTERN_LIB_BUILD_RULE,$$(foreach arch,$$(TOCK_ARCHS),%/$$(arch)/$(notdir $(1)).a),$(1)))
$$(eval $$(call EXTERN_LIB_BUILD_RULE,$$(foreach arch,$$(TOCK_ARCHS),%/$$(arch)/$(notdir $(1)).a),$(1)))
endef
# To see the generated rules, run:
# $(info $(foreach lib, $(EXTERN_LIBS), $(call EXTERN_LIB_RULES,$(lib))))
$(foreach lib, $(EXTERN_LIBS), $(eval $(call EXTERN_LIB_RULES,$(lib))))
# Some sanity checks for variables before they are used
# Warn users about LDFLAGS currently being ignored. We currently use the WLFLAGS
# and WLFLAGS_$(arch) variables to pass linker options through the compiler, by
# encoding them as `-Wl,...` options.
ifdef LDFLAGS
$(warning *******************************************************)
$(warning LDFLAGS are currently ignored!!)
$(warning )
$(warning This is because we need to invoke the gcc frontend not the)
$(warning ld frontend for the final link step, which means that we would)
$(warning need to parse the LDFLAGS into things like -Wl,-<flag> for each)
$(warning entry, but that proved a little fragile on first attempt so)
$(warning it is not currently done. Sorry.)
$(warning Please use WLFLAGS if you need to pass linker flags.)
$(warning *******************************************************)
endif
# Warn users about improperly defined `HEAP_SIZE`.
ifdef HEAP_SIZE
$(warning The variable HEAP_SIZE is set but will not be used.)
$(warning Tock has two heaps, the application heap which is memory your)
$(warning program uses and the kernel heap or grant regions, which is memory)
$(warning dynamically allocated by drivers on behalf of your program.)
$(warning )
$(warning These regions are controlled by the APP_HEAP_SIZE and)
$(warning KERNEL_HEAP_SIZE variables respectively.)
endif
# Rules to create object files for a specific architecture.
#
# - Argument $(1) is the architecture (e.g. cortex-m0) to compile for.
define BUILD_RULES_PER_ARCH
# BUILDDIR holds architecture dependent, but board-independent outputs
$$(BUILDDIR)/$(1):
$$(TRACE_DIR)
$$(Q)mkdir -p $$@
# First step doesn't actually compile, just generate header dependency information
# More info on our approach here: http://stackoverflow.com/questions/97338
$$(BUILDDIR)/$(1)/%.o: %.c | $$(BUILDDIR)/$(1) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1))
$$(TRACE_CC)
$$(Q)$$(TOOLCHAIN_$(1))$$(CC_$(1)) $$(CFLAGS) $$(CFLAGS_$(1)) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -MF"$$(@:.o=.d)" -MG -MM -MP -MT"$$(@:.o=.d)@" -MT"$$@" "$$<"
$$(Q)$$(TOOLCHAIN_$(1))$$(CC_$(1)) $$(CFLAGS) $$(CFLAGS_$(1)) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -c -o $$@ $$<
$$(BUILDDIR)/$(1)/%.o: %.cc | $$(BUILDDIR)/$(1) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1)) $$(SYSTEM_LIBS_CXX_$(1))
$$(TRACE_CXX)
$$(Q)$$(TOOLCHAIN_$(1))$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -MF"$$(@:.o=.d)" -MG -MM -MP -MT"$$(@:.o=.d)@" -MT"$$@" "$$<"
$$(Q)$$(TOOLCHAIN_$(1))$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -c -o $$@ $$<
$$(BUILDDIR)/$(1)/%.o: %.cpp | $$(BUILDDIR)/$(1) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1)) $$(SYSTEM_LIBS_CXX_$(1))
$$(TRACE_CXX)
$$(Q)$$(TOOLCHAIN_$(1))$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -MF"$$(@:.o=.d)" -MG -MM -MP -MT"$$(@:.o=.d)@" -MT"$$@" "$$<"
$$(Q)$$(TOOLCHAIN_$(1))$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -c -o $$@ $$<
$$(BUILDDIR)/$(1)/%.o: %.cxx | $$(BUILDDIR)/$(1) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1)) $$(SYSTEM_LIBS_CXX_$(1))
$$(TRACE_CXX)
$$(Q)$$(TOOLCHAIN_$(1))$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -MF"$$(@:.o=.d)" -MG -MM -MP -MT"$$(@:.o=.d)@" -MT"$$@" "$$<"
$$(Q)$$(TOOLCHAIN_$(1))$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) -c -o $$@ $$<
OBJS_$(1) += $$(patsubst %.c,$$(BUILDDIR)/$(1)/%.o,$$(C_SRCS))
OBJS_$(1) += $$(patsubst %.cc,$$(BUILDDIR)/$(1)/%.o,$$(filter %.cc, $$(CXX_SRCS)))
OBJS_$(1) += $$(patsubst %.cpp,$$(BUILDDIR)/$(1)/%.o,$$(filter %.cpp, $$(CXX_SRCS)))
OBJS_$(1) += $$(patsubst %.cxx,$$(BUILDDIR)/$(1)/%.o,$$(filter %.cxx, $$(CXX_SRCS)))
endef
# Rules to generate an app for a given architecture and target. These actually
# create the ELF which can be linked for a specific address as needed.
#
# - Argument $(1) is the architecture (e.g. cortex-m0) to build for.
# - Argument $(2) is the output name to use for the .elf and other files.
# - Argument $(3) is the flash address to use for linking.
# - Argument $(4) is the RAM address to use for linking.
#
# Note: all variables, other than $(1), used within this block must be double
# dollar-signed so that their values will be evaluated when run, not when
# generated
define BUILD_RULES
$$(BUILDDIR)/$(1)/$(2).custom.ld: $$(LAYOUT) | $$(BUILDDIR)/$(1)
@# Start with a copy of the template / generic ld script
$$(Q)cp $$< $$@
@# #616 #635: sed is not cross-platform
@# https://stackoverflow.com/a/22247781/358675 <-- Use perl in place of sed
$$(Q)\
perl -pi -e "s/(FLASH.*ORIGIN[ =]*)([x0-9]*)(,.*LENGTH)/\$$$${1}$(3)\$$$$3/" $$@ &&\
perl -pi -e "s/(SRAM.*ORIGIN[ =]*)([x0-9]*)(,.*LENGTH)/\$$$${1}$(4)\$$$$3/" $$@
# Collect all desired built output.
$$(BUILDDIR)/$(1)/$(2).elf: $$(OBJS_$(1)) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1)) $$(SYSTEM_LIBS_CXX_$(1)) $$(BUILDDIR)/$(1)/$(2).custom.ld | $$(BUILDDIR)/$(1)
$$(TRACE_LD)
$$(Q)$$(TOOLCHAIN_$(1))$$(CC_$(1)) $$(CFLAGS) $$(CFLAGS_$(1)) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) $$(WLFLAGS) $$(WLFLAGS_$(1))\
-Xlinker --defsym=STACK_SIZE=$$(STACK_SIZE)\
-Xlinker --defsym=APP_HEAP_SIZE=$$(APP_HEAP_SIZE)\
-Xlinker --defsym=KERNEL_HEAP_SIZE=$$(KERNEL_HEAP_SIZE)\
-T $$(BUILDDIR)/$(1)/$(2).custom.ld\
-nostdlib\
-Wl,--start-group $$(OBJS_$(1)) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1)) $$(SYSTEM_LIBS_CXX_$(1)) -Wl,--end-group\
-Wl,-Map=$$(BUILDDIR)/$(1)/$(2).Map\
-o $$@
# NOTE: This rule creates an lst file for the elf as flashed on the board
# (i.e. at address 0x80000000). This is not likely what you want.
$$(BUILDDIR)/$(1)/$(2).lst: $$(BUILDDIR)/$(1)/$(2).elf
$$(TRACE_LST)
$$(Q)$$(TOOLCHAIN_$(1))$$(OBJDUMP) $$(OBJDUMP_FLAGS) $$(OBJDUMP_FLAGS_$(1)) $$< > $$@
@echo $$$$(tput bold)Listings generated at $$@$$$$(tput sgr0)
# checks compiled ELF files to ensure that all libraries and applications were
# built with the correct flags in order to work on a Tock board
.PHONY: validate_gcc_flags
validate_gcc_flags:: $$(BUILDDIR)/$(1)/$(2).elf
ifndef TOCK_NO_CHECK_SWITCHES
$$(Q)$$(TOOLCHAIN_$(1))$$(READELF) -p .GCC.command.line $$< 2>&1 | grep -q "does not exist" && { echo "Error: Missing section .GCC.command.line"; echo ""; echo "Tock requires that applications are built with"; echo " -frecord-gcc-switches"; echo "to validate that all required flags were used"; echo ""; echo "You can skip this check by defining the make variable TOCK_NO_CHECK_SWITCHES"; exit 1; } || exit 0
$$(Q)$$(TOOLCHAIN_$(1))$$(READELF) -p .GCC.command.line $$< | grep -q -- -msingle-pic-base && $$(READELF) -p .GCC.command.line $$< | grep -q -- -mpic-register=r9 && $$(READELF) -p .GCC.command.line $$< | grep -q -- -mno-pic-data-is-text-relative || { echo "Error: Missing required build flags."; echo ""; echo "Tock requires applications are built with"; echo " -msingle-pic-base"; echo " -mpic-register=r9"; echo " -mno-pic-data-is-text-relative"; echo "But one or more of these flags are missing"; echo ""; echo "To see the flags your application was built with, run"; echo "$$(READELF) -p .GCC.command.line $$<"; echo ""; exit 1; }
endif
# rules to print the size of the built binaries
.PHONY: size-$(1)-$(2)
size-$(1)-$(2): $$(BUILDDIR)/$(1)/$(2).elf
@echo Application size report for target $(2):
$$(Q)$$(TOOLCHAIN_$(1))$$(SIZE) $$^
size:: size-$(1)-$(2)
############################################################################################
# DEBUGGING STUFF
#
# The approach here is that we're going create a new elf file that is compiled
# at the actual flash and ram offset of the loaded program
#
# We want to build a rule that fails if these needed env variables aren't set
# only when actually trying to use them to build the lst file. We also want to
# force this to rerun every time it's invoked so that it picks up new env
# variable settings
# Step 0: Force this to be built every time
.PHONY: _FORCE_USERLAND_DEBUG_LD
# Step 1: Create a new linker script. Note this depends on original (non-shifted) elf
# (supposedly this could be one-lined, but I couldn't make that work, so here goes)
ifdef RAM_START
ifdef FLASH_INIT
_USERLAND_DEBUG_ALL_NEEDED_VARS := 1
endif
endif
$$(BUILDDIR)/$(1)/$(2).userland_debug.ld: $$(TOCK_USERLAND_BASE_DIR)/userland_generic.ld $$(BUILDDIR)/$(1)/$(2).elf _FORCE_USERLAND_DEBUG_LD | $$(BUILDDIR)/$(1)
ifndef _USERLAND_DEBUG_ALL_NEEDED_VARS
@echo "ERROR: Required variables RAM_START and FLASH_INIT are not set."
@echo " These are needed to compute the offset your program was loaded at."
@echo " See the kernel panic message for these values."
@exit 1
else
@# Start with a copy of the template / generic ld script
$$(Q)cp $$< $$@
@# And with apologies to future readers, this is easier as one shell command/script so
@# we can set intervening variables, away we go
@#
@# Get the offset between the init function and the start of text (0x80000000).
@# We then use that offset to calculate where the start of text was on the actual MCU.
@# Create a new LD file at the correct flash and ram locations.
@#
@# #616 #635: sed is not cross-platform
@# https://stackoverflow.com/a/22247781/358675 <-- Use perl in place of sed
$$(Q)set -e ;\
ORIGINAL_ENTRY=`$$(TOOLCHAIN_$(1))$$(READELF) -h $$(BUILDDIR)/$(1)/$(2).elf | grep Entry | awk '{print $$$$4}'` ;\
INIT_OFFSET=$$$$(($$$$ORIGINAL_ENTRY - 0x80000000)) ;\
FLASH_START=$$$$(($$$$FLASH_INIT-$$$$INIT_OFFSET)) ;\
perl -pi -e "s/(FLASH.*ORIGIN[ =]*)([x0-9]*)(,.*LENGTH)/\$$$${1}$$$$FLASH_START\$$$$3/" $$@ ;\
perl -pi -e "s/(SRAM.*ORIGIN[ =]*)([x0-9]*)(,.*LENGTH)/\$$$${1}$$$$RAM_START\$$$$3/" $$@
endif
# Step 2: Create a new ELF with the layout that matches what's loaded
$$(BUILDDIR)/$(1)/$(2).userland_debug.elf: $$(OBJS_$(1)) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1)) $$(SYSTEM_LIBS_CXX_$(1)) $$(BUILDDIR)/$(1)/$(2).userland_debug.ld | $$(BUILDDIR)/$(1)
$$(TRACE_LD)
$$(Q)$$(TOOLCHAIN_$(1))$$(CC_$(1)) $$(CFLAGS) $$(CFLAGS_$(1)) $$(CPPFLAGS) $$(CPPFLAGS_$(1)) $$(WLFLAGS) $$(WLFLAGS_$(1))\
-Xlinker --defsym=STACK_SIZE=$$(STACK_SIZE)\
-Xlinker --defsym=APP_HEAP_SIZE=$$(APP_HEAP_SIZE)\
-Xlinker --defsym=KERNEL_HEAP_SIZE=$$(KERNEL_HEAP_SIZE)\
-T $$(BUILDDIR)/$(1)/$(2).userland_debug.ld\
-nostdlib\
-Wl,--start-group $$(OBJS_$(1)) $$(LIBS_$(1)) $$(SYSTEM_LIBS_$(1)) $$(SYSTEM_LIBS_CXX_$(1)) -Wl,--end-group\
-Wl,-Map=$$(BUILDDIR)/$(1)/$(2).Map\
-o $$@
# Step 3: Now we can finally generate an LST
$$(BUILDDIR)/$(1)/$(2).userland_debug.lst: $$(BUILDDIR)/$(1)/$(2).userland_debug.elf
$$(TRACE_LST)
$$(Q)$$(TOOLCHAIN_$(1))$$(OBJDUMP) $$(OBJDUMP_FLAGS) $$(OBJDUMP_FLAGS_$(1)) $$< > $$@
@echo $$$$(tput bold)Listings generated at $$@$$$$(tput sgr0)
# END DEBUGGING STUFF
############################################################################################
endef
# Rules that apply to an entire architecture family (e.g. cortex-m).
#
# - Argument $(1) is the architecture family (e.g. cortex-m).
# - Argument $(2) is the list of architectures in that family.
# - Argument $(3) is the list of output names for the .elf of each arch.
#
# Note: all variables, other than $(1), used within this block must be double
# dollar-signed so that their values will be evaluated when run, not when
# generated.
define ARCH_FAMILY_RULES
$(1)_DIRECTORY_NAMES := $$(addsuffix /,$(2))
$(1)_DIRECTORY_FILES := $$(join $$($(1)_DIRECTORY_NAMES),$(3))
$(1)_DIRECTORY_FILES_EXT := $$(addsuffix .elf,$$($(1)_DIRECTORY_FILES))
$(1)_ELF_FILES := $$(addprefix $$(BUILDDIR)/,$$($(1)_DIRECTORY_FILES_EXT))
# Rule to print the size of the built binaries from an architecture family.
.PHONY: size-$(1)
size-$(1): $$($(1)_ELF_FILES)
@echo Application size report for arch family $(1):
$$(Q)$$(TOOLCHAIN_$(1))$$(SIZE) -t $$^
endef
# Functions to parse the `TOCK_TARGETS` array. Entries 3 and 4 default to the
# PIC addresses if they are not specified.
ARCH_FN = $(firstword $(subst |, ,$1))
OUTPUT_NAME_FN = $(if $(word 2,$(subst |, ,$1)),$(word 2,$(subst |, ,$1)),$(firstword $(subst |, ,$1)))
FLASH_ADDRESS_FN = $(if $(word 3,$(subst |, ,$1)),$(word 3,$(subst |, ,$1)),0x80000000)
RAM_ADDRESS_FN = $(if $(word 4,$(subst |, ,$1)),$(word 4,$(subst |, ,$1)),0x00000000)
# To see the generated rules, run:
#$(info $(foreach platform, $(TOCK_ARCHS), $(call BUILD_RULES_PER_ARCH,$(platform))))
#$(info $(foreach platform, $(TOCK_TARGETS), $(call BUILD_RULES,$(call ARCH_FN,$(platform)),$(call OUTPUT_NAME_FN,$(platform)),$(call FLASH_ADDRESS_FN,$(platform)),$(call RAM_ADDRESS_FN,$(platform)))))
# Actually generate the rules for each architecture
$(foreach platform, $(TOCK_ARCHS), $(eval $(call BUILD_RULES_PER_ARCH,$(platform))))
$(foreach platform, $(TOCK_TARGETS), $(eval $(call BUILD_RULES,$(call ARCH_FN,$(platform)),$(call OUTPUT_NAME_FN,$(platform)),$(call FLASH_ADDRESS_FN,$(platform)),$(call RAM_ADDRESS_FN,$(platform)))))
$(foreach family, $(TOCK_ARCH_FAMILIES), $(eval $(call ARCH_FAMILY_RULES,$(family),$(foreach target, $(filter $(family)%,$(TOCK_TARGETS)), $(call ARCH_FN, $(target))),$(foreach target, $(filter $(family)%,$(TOCK_TARGETS)), $(call OUTPUT_NAME_FN, $(target))))))
# TAB file generation. Used for Tockloader
$(BUILDDIR)/$(PACKAGE_NAME).tab: $(foreach platform, $(TOCK_TARGETS), $(BUILDDIR)/$(call ARCH_FN,$(platform))/$(call OUTPUT_NAME_FN,$(platform)).elf)
$(TRACE_E2T)
$(Q)$(ELF2TAB) $(ELF2TAB_ARGS) -o $@ $^
# Rules for building apps
SIZE_RULES = $(addprefix size-,$(TOCK_ARCH_FAMILIES))
.PHONY: all
all: $(BUILDDIR)/$(PACKAGE_NAME).tab $(SIZE_RULES)
# The size target accumulates dependencies in the platform build rule creation
.PHONY: size
# Generate helpful output for debugging userland applications.
.PHONY: debug
debug: $(foreach platform, $(TOCK_TARGETS), $(BUILDDIR)/$(call ARCH_FN,$(platform))/$(call OUTPUT_NAME_FN,$(platform)).userland_debug.lst)
# Generate a .lst file for each architecture using the RAM and flash addresses
# specified in the linker file. This will create a valid assembly file, but the
# addresses of the instructions will be wrong unless the application was
# compiled for specific addresses. Notably, on cortex-m platforms, which use
# position-independent code, the addresses will be wrong, and you should use
# `make debug` instead. For architectures without PIC support (like RISC-V),
# `make lst` will work since the linker files uses the correct addresses.
.PHONY: lst
lst: $(foreach platform, $(TOCK_TARGETS), $(BUILDDIR)/$(call ARCH_FN,$(platform))/$(call OUTPUT_NAME_FN,$(platform)).lst)
.PHONY:
clean::
rm -Rf $(BUILDDIR)
# Rules for running the C linter
FORMATTED_FILES := $(patsubst %.c,$(BUILDDIR)/format/%.uncrustify,$(C_SRCS))
FORMATTED_FILES += $(patsubst %.cc,$(BUILDDIR)/format/%.uncrustify,$(filter %.cc, $(CXX_SRCS)))
FORMATTED_FILES += $(patsubst %.cpp,$(BUILDDIR)/format/%.uncrustify,$(filter %.cpp, $(CXX_SRCS)))
FORMATTED_FILES += $(patsubst %.cxx,$(BUILDDIR)/format/%.uncrustify,$(filter %.cxx, $(CXX_SRCS)))
$(BUILDDIR)/format:
@mkdir -p $@
.PHONY: fmt format
fmt format:: $(FORMATTED_FILES)
$(BUILDDIR)/format/%.uncrustify: %.c $(TOCK_USERLAND_BASE_DIR)/tools/uncrustify/uncrustify.cfg | _format_check_unstaged
$(Q)$(UNCRUSTIFY) -f $< -o $@
$(Q)cmp -s $< $@ || (if [ "$$CI" = "true" ]; then diff -y $< $@; rm $@; exit 1; else cp $@ $<; fi)
$(BUILDDIR)/format/%.uncrustify: %.cc $(TOCK_USERLAND_BASE_DIR)/tools/uncrustify/uncrustify.cfg | _format_check_unstaged
$(Q)$(UNCRUSTIFY) -f $< -o $@
$(Q)cmp -s $< $@ || (if [ "$$CI" = "true" ]; then diff -y $< $@; rm $@; exit 1; else cp $@ $<; fi)
$(BUILDDIR)/format/%.uncrustify: %.cpp $(TOCK_USERLAND_BASE_DIR)/tools/uncrustify/uncrustify.cfg | _format_check_unstaged
$(Q)$(UNCRUSTIFY) -f $< -o $@
$(Q)cmp -s $< $@ || (if [ "$$CI" = "true" ]; then diff -y $< $@; rm $@; exit 1; else cp $@ $<; fi)
$(BUILDDIR)/format/%.uncrustify: %.cxx $(TOCK_USERLAND_BASE_DIR)/tools/uncrustify/uncrustify.cfg | _format_check_unstaged
$(Q)$(UNCRUSTIFY) -f $< -o $@
$(Q)cmp -s $< $@ || (if [ "$$CI" = "true" ]; then diff -y $< $@; rm $@; exit 1; else cp $@ $<; fi)
# Rules to help validate build configuration
fmt format::
$(Q)$(TOCK_USERLAND_BASE_DIR)/tools/check_override.sh
#########################################################################################
# Include dependency rules for picking up header changes (by convention at bottom of makefile)
OBJS_NO_ARCHIVES += $(filter %.o,$(foreach platform, $(TOCK_ARCHS), $(OBJS_$(platform))))
-include $(OBJS_NO_ARCHIVES:.o=.d)