/
common.mk
240 lines (186 loc) · 8.36 KB
/
common.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
# $Id$
#
# following variables should be set before including this file:
# - PROCESSOR e.g.: STM32F103RE
# - FAMILY e.g.: STM32F10x
# - BOARD e.g.: MBHP_CORE_STM32
# - LCD e.g.: clcd
# - LD_FILE e.g.: $(MIOS32_PATH)/etc/ld/$(FAMILY)/$(PROCESSOR).ld
# - PROJECT e.g.: project # (.lst, .hex, .map, etc... will be added automatically)
# - THUMB_SOURCE e.g.: main.c (.c only)
# - THUMB_CPP_SOURCE e.g.: main.cp (.cpp only)
# - THUMB_AS_SOURCE e.g.: assembly.s (.s only)
# - ARM_SOURCE e.g.: my_startup.c (.c only)
# - ARM_CPP_SOURCE e.g.: my_startup.cpp (.cpp only)
# - ARM_AS_SOURCE e.g.: assembly.s (.s only)
# - C_INCLUDE e.g.: -I./ui # (more include pathes will be added by .mk files)
# - A_INCLUDE same for assembly code
# - DIST e.g.: ./
#
# Modules can be added by including .mk files from $MIOS32_PATH/modules/*/*.mk
#
# if MIOS32_SHELL environment variable hasn't been set by the user, set it here
# Ubuntu users should set it to /bin/bash from external (-> "export MIOS32_SHELL /bin/bash")
MIOS32_SHELL ?= sh
export MIOS32_SHELL
# select GCC tools
# can be optionally overruled via environment variable
# e.g. for Cortex M3 support provided by CodeSourcery, use MIOS32_GCC_PREFIX=arm-none-eabi
# The usage of arm-elf isn't recommented due to compatibility issues!!!
MIOS32_GCC_PREFIX ?= arm-none-eabi
CC = $(MIOS32_GCC_PREFIX)-gcc
CPP = $(MIOS32_GCC_PREFIX)-g++
OBJCOPY = $(MIOS32_GCC_PREFIX)-objcopy
OBJDUMP = $(MIOS32_GCC_PREFIX)-objdump
NM = $(MIOS32_GCC_PREFIX)-nm
SIZE = $(MIOS32_GCC_PREFIX)-size
# where should the output files be located
PROJECT_OUT ?= $(PROJECT)_build
# default linker flags
LDFLAGS += -T $(LD_FILE) -mthumb -u _start -Wl,--gc-section -Xlinker -M -Xlinker -Map=$(PROJECT_OUT)/$(PROJECT).map -nostartfiles -lstdc++
# for https://launchpad.net/gcc-arm-embedded: enable newlib-nano for better performance
# not compatible with other toolchains (users have to switch to new version, or disable the line below)
LDFLAGS += --specs=nano.specs
# default assembler flags
AFLAGS += $(A_DEFINES) $(A_INCLUDE) -Wa,-adhlns=$(<:.s=.lst)
# define C flags
CFLAGS += $(C_DEFINES) $(C_INCLUDE) -Wall -Wno-format -Wno-switch -Wno-strict-aliasing
# add family specific arguments
ifeq ($(FAMILY),STM32F10x)
CFLAGS += -mcpu=cortex-m3 -mlittle-endian -ffunction-sections -fdata-sections -fomit-frame-pointer
endif
ifeq ($(FAMILY),STM32F4xx)
# leads to a crash - reason not analysed yet
#CFLAGS += -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mthumb -mfloat-abi=hard -mlittle-endian -ffunction-sections -fdata-sections -fomit-frame-pointer
# works (but FPU not enabled)
CFLAGS += -mcpu=cortex-m4 -mlittle-endian -ffunction-sections -fdata-sections -fomit-frame-pointer
endif
ifeq ($(FAMILY),LPC17xx)
CFLAGS += -mcpu=cortex-m3 -mlittle-endian -ffunction-sections -fdata-sections -fomit-frame-pointer
endif
ifeq ($(FAMILY),STR9x)
CFLAGS += -mcpu=arm7tdmi -D PACK_STRUCT_END=__attribute\(\(packed\)\) -D ALIGN_STRUCT_END=__attribute\(\(aligned\(4\)\)\) -fomit-frame-pointer -ffunction-sections -mthumb-interwork
endif
# define CPP flags
CPPFLAGS += $(CFLAGS) -fno-rtti -fno-exceptions -Wno-write-strings
# to monitor stack usage via $MIOS32_BIN_PATH/avstack.pl
# see also
# - http://dlbeer.co.nz/oss/avstack.html and
# - https://mcuoneclipse.com/2015/08/21/gnu-static-stack-usage-analysis/
CFLAGS += -fstack-usage
# convert .c/.s -> .o
THUMB_OBJS = $(THUMB_SOURCE:.c=.o)
THUMB_CPP_OBJS = $(THUMB_CPP_SOURCE:.cpp=.o)
THUMB_AS_OBJS = $(THUMB_AS_SOURCE:.s=.o)
ARM_OBJS = $(ARM_SOURCE:.c=.o)
ARM_CPP_OBJS = $(ARM_CPP_SOURCE:.cpp=.o)
ARM_AS_OBJS = $(ARM_AS_SOURCE:.s=.o)
# convert .s -> .lst
THUMB_AS_LST = $(THUMB_AS_SOURCE:.s=.lst)
ARM_AS_LST = $(ARM_AS_SOURCE:.s=.lst)
# list of all objects
ALL_OBJS = $(addprefix $(PROJECT_OUT)/, $(THUMB_OBJS) $(THUMB_CPP_OBJS) $(THUMB_AS_OBJS) $(ARM_OBJS) $(ARM_CPP_OBJS) $(ARM_AS_OBJS))
# list of all dependency files
ALL_DFILES = $(ALL_OBJS:.o=.d)
# which directories contain source files?
DIRS = $(dir $(THUMB_OBJS) $(THUMB_CPP_OBJS) $(THUMB_AS_OBJS) $(ARM_OBJS) $(ARM_CPP_OBJS) $(ARM_AS_OBJS))
# add files for distribution
DIST += $(MIOS32_PATH)/include/makefile/common.mk $(MIOS32_PATH)/include/c
DIST += $(LD_FILE)
# default rule
all: dirs cleanhex $(PROJECT).hex $(PROJECT_OUT)/$(PROJECT).bin $(PROJECT_OUT)/$(PROJECT).lss $(PROJECT_OUT)/$(PROJECT).sym projectinfo
# define debug/release target for easier use in codeblocks
debug: all
Debug: all
release: all
Release: all
# create the output directories
dirs:
@-if [ ! -e $(PROJECT_OUT) ]; then mkdir $(PROJECT_OUT); fi;
@-$(foreach DIR,$(DIRS), if [ ! -e $(PROJECT_OUT)/$(DIR) ]; \
then mkdir -p $(PROJECT_OUT)/$(DIR); fi; )
# rule to create a .hex and .bin file
%.bin : $(PROJECT_OUT)/$(PROJECT).elf
@$(OBJCOPY) $< -O binary $@
%.hex : $(PROJECT_OUT)/$(PROJECT).elf
@$(OBJCOPY) $< -O ihex $@
# rule to create a listing file from .elf
%.lss: $(PROJECT_OUT)/$(PROJECT).elf
@$(OBJDUMP) -w -h -S -C $< > $@
# rule to create a symbol table from .elf
%.sym: $(PROJECT_OUT)/$(PROJECT).elf
@$(NM) -n $< > $@
# rule to create .elf file
$(PROJECT_OUT)/$(PROJECT).elf: $(ALL_OBJS)
@$(CC) $(CFLAGS) $(ALL_OBJS) $(LIBS) $(LDFLAGS) -o$@
# rule to output project informations
projectinfo:
@echo "-------------------------------------------------------------------------------"
@echo "Application successfully built for:"
@echo "Processor: $(PROCESSOR)"
@echo "Family: $(FAMILY)"
@echo "Board: $(BOARD)"
@echo "LCD: $(LCD)"
@echo "-------------------------------------------------------------------------------"
$(SIZE) $(PROJECT_OUT)/$(PROJECT).elf
@grep -E '__ram_start|__ram_end' project_build/project.sym
# default rule for compiling .c programs
# inspired from the "super makefile" published at http://gpwiki.org/index.php/Make
# Rule for creating object file and .d file, the sed magic is to add
# the object path at the start of the file because the files gcc
# outputs assume it will be in the same dir as the source file.
$(PROJECT_OUT)/%.o: %.c
@echo Creating object file for $(notdir $<)
@$(CC) -Wp,-MMD,$(PROJECT_OUT)/$*.dd $(CFLAGS) -mthumb -c $< -o $@
@sed -e '1s/^\(.*\)$$/$(subst /,\/,$(dir $@))\1/' $(PROJECT_OUT)/$*.dd > $(PROJECT_OUT)/$*.d
@rm -f $(PROJECT_OUT)/$*.dd
$(PROJECT_OUT)/%.o: %.cpp
@echo Creating object file for $(notdir $<)
@$(CC) -Wp,-MMD,$(PROJECT_OUT)/$*.dd $(CPPFLAGS) -mthumb -c $< -o $@
@sed -e '1s/^\(.*\)$$/$(subst /,\/,$(dir $@))\1/' $(PROJECT_OUT)/$*.dd > $(PROJECT_OUT)/$*.d
@rm -f $(PROJECT_OUT)/$*.dd
$(PROJECT_OUT)/%.o: %.s
@echo Creating object file for $(notdir $<)
@$(CC) -Wp,-MMD,$(PROJECT_OUT)/$*.dd $(ASFLAGS) -mthumb -c $< -o $@
@sed -e '1s/^\(.*\)$$/$(subst /,\/,$(dir $@))\1/' $(PROJECT_OUT)/$*.dd > $(PROJECT_OUT)/$*.d
@rm -f $(PROJECT_OUT)/$*.dd
# Includes the .d files so it knows the exact dependencies for every
# source.
-include $(ALL_DFILES)
# TODO: solution to differ between THUMB and ARM objects!
# we could search in the ARM*OBJS list and prevent the usage of -mthumb in this case
#$(ARM_OBJS) : %.o : %.c
# $(CC) -c $(CFLAGS) $< -o $@
#$(ARM_CPP_OBJS) : %.o : %.cpp
# $(CPP) -c $(CPPFLAGS) $< -o $@
#$(ARM_AS_OBJS) : %.o : %.s
# $(CC) -c $(AFLAGS) $< -o $@
# clean temporary files
clean:
rm -rf $(PROJECT_OUT)
# clean project image
cleanhex:
rm -f $(PROJECT).hex
# clean temporary files + project image
cleanall: clean cleanhex
# for use with graphviz and egypt
callgraph: egyptall egypt_tidy egypt_all egypt_project
egyptall: CFLAGS += -dr
egyptall: all
egypt_tidy:
@rm -fR egypt
@echo "-------------------------------------------------------------------------------"
@echo "Generating call graphs in .dot files"
@echo "-------------------------------------------------------------------------------"
@mkdir egypt
@mv *.expand egypt/
egypt_all:
@perl $(MIOS32_PATH)/etc/egypt/egypt egypt/*.expand > egypt/$(PROJECT).dot
egypt_project: EGYPTFILES = find egypt/*.expand -maxdepth 1 ! -name "mios32_*.expand" ! -name "stm32f10x*.expand" ! -name "usb_*.expand" ! -name "printf-stdarg.c*.expand" ! -name "crt0_STM32x.c*.expand" ! -name "app_lcd.c*.expand" ! -name "heap_*.expand" ! -name "list.c*.expand" ! -name "port.c*.expand" ! -name "queue.c*.expand" ! -name "main.c*.expand"
egypt_project:
@perl $(MIOS32_PATH)/etc/egypt/egypt `$(EGYPTFILES)` > egypt/$(PROJECT)_NoMIOS.dot
callgraph_convert:
@$(MIOS32_SHELL) $(MIOS32_PATH)/etc/egypt/dot_output.sh
callgraph_all: callgraph callgraph_convert
callgraph_clean:
@rm -fR egypt