lufa.build.in 9.87 KB
Newer Older
1
2
3
4
5
6
7
8
#
#             LUFA Library
#     Copyright (C) Dean Camera, 2012.
#
#  dean [at] fourwalledcubicle [dot] com
#           www.lufa-lib.org
#

9
10
11
LUFA_BUILD_MODULES         += BUILD
LUFA_BUILD_TARGETS         += size symbol-sizes all elf hex lss clean
LUFA_BUILD_MANDATORY_VARS  += TARGET ARCH MCU SRC F_USB LUFA_PATH
12
LUFA_BUILD_OPTIONAL_VARS   += BOARD OPTIMIZATION C_STANDARD CPP_STANDARD F_CPU C_FLAGS CPP_FLAGS ASM_FLAGS CC_FLAGS LD_FLAGS OBJDIR
13
14
LUFA_BUILD_PROVIDED_VARS   += 
LUFA_BUILD_PROVIDED_MACROS += 
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

# -----------------------------------------------------------------------------
#               LUFA GCC Compiler Buildsystem Makefile Module.
# -----------------------------------------------------------------------------
# DESCRIPTION:
#   Provides a set of targets to build a C, C++ and/or Assembly application
#   via the AVR-GCC compiler.
# -----------------------------------------------------------------------------
# TARGETS:
#
#    size                      - List built application size
#    symbol-sizes              - Print application symbols from the binary ELF
#                                file as a list sorted by size in bytes
#    all                       - Build application and list size
#    elf                       - Build application ELF debug object file
#    hex                       - Build application HEX object files
#    lss                       - Build application LSS assembly listing file
#    clean                     - Remove output files
#
# MANDATORY PARAMETERS:
#
#    TARGET                    - Application name
#    ARCH                      - Device architecture name
#    MCU                       - Microcontroller device model name
#    SRC                       - List of input source files (*.c, *.cpp, *.S)
#    F_USB                     - Speed of the input clock of the USB controller
#                                in Hz
#    LUFA_PATH                 - Path to the LUFA library core
#
# OPTIONAL PARAMETERS:
#
#    BOARD                     - LUFA board hardware
#    OPTIMIZATION              - Optimization level
#    C_STANDARD                - C Language Standard to use
#    CPP_STANDARD              - C++ Language Standard to use
#    F_CPU                     - Speed of the CPU, in Hz
#    C_FLAGS                   - Flags to pass to the C compiler only
#    CPP_FLAGS                 - Flags to pass to the C++ compiler only
#    ASM_FLAGS                 - Flags to pass to the assembler only
#    CC_FLAGS                  - Common flags to pass to the C/C++ compiler and
#                                assembler
#    LD_FLAGS                  - Flags to pass to the linker
57
58
59
#    OBJDIR                    - Directory for the output object and dependency
#                                files; if equal to ".", the output files will
#                                be generated in the same folder as the sources
60
#
61
62
63
64
65
66
67
68
# PROVIDED VARIABLES:
#
#    (None)
#
# PROVIDED MACROS:
#
#    (None)
#
69
70
# -----------------------------------------------------------------------------

71
72
73
ERROR_IF_UNSET   = $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set))
ERROR_IF_EMPTY   = $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank))
ERROR_IF_NONBOOL = $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N))
74
75
76
77
78
79
80
81
82
83
84

# Default values of optionally user-supplied variables
BOARD           ?= NONE
OPTIMIZATION    ?= s
F_CPU           ?=
C_STANDARD      ?= gnu99
CPP_STANDARD    ?= gnu++98
C_FLAGS         ?=
CPP_FLAGS       ?=
ASM_FLAGS       ?=
CC_FLAGS        ?=
85
OBJDIR          ?= .
86

87
88
89
90
91
92
93
94
95
96
97
# Sanity check user supplied values
$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR)))
$(call ERROR_IF_EMPTY, MCU)
$(call ERROR_IF_EMPTY, TARGET)
$(call ERROR_IF_EMPTY, ARCH)
$(call ERROR_IF_EMPTY, F_USB)
$(call ERROR_IF_EMPTY, LUFA_PATH)
$(call ERROR_IF_EMPTY, BOARD)
$(call ERROR_IF_EMPTY, OPTIMIZATION)
$(call ERROR_IF_EMPTY, C_STANDARD)
$(call ERROR_IF_EMPTY, CPP_STANDARD)
98
$(call ERROR_IF_EMPTY, OBJDIR)
99

100
101
102
103
104
# Determine the utility prefix to use for the selected architecture
ifeq ($(ARCH), AVR8)
   CROSS        := avr-
else ifeq ($(ARCH), XMEGA)
   CROSS        := avr-
105
   $(warning The XMEGA device support is currently EXPERIMENTAL (incomplete and/or non-functional), and is included for preview purposes only.)
106
107
else ifeq ($(ARCH), UC3)
   CROSS        := avr32-
108
   $(warning The UC3 device support is currently EXPERIMENTAL (incomplete and/or non-functional), and is included for preview purposes only.)
109
else
110
   $(error Unsupported architecture "$(ARCH)")
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
endif

# Output Messages
MSG_BUILD_BEGIN  := Begin compilation of project \"$(TARGET)\"...
MSG_BUILD_END    := Finished building project \"$(TARGET)\".
MSG_COMPILE_CMD  := ' [CC]      :'
MSG_ASSEMBLE_CMD := ' [AS]      :'
MSG_NM_CMD       := ' [NM]      :'
MSG_REMOVE_CMD   := ' [RM]      :'
MSG_LINKER_CMD   := ' [LNK]     :'
MSG_SIZE_CMD     := ' [SIZE]    :'
MSG_OBJCPY_CMD   := ' [OBJCPY]  :'
MSG_OBJDMP_CMD   := ' [OBJDMP]  :'

# Convert input source file list to differentiate them by type
C_SOURCE   = $(filter %.c, $(SRC))
CPP_SOURCE = $(filter %.cpp, $(SRC))
ASM_SOURCE = $(filter %.S, $(SRC))

# Create a list of unknown source file types, if any are found throw an error
UNKNOWN_SOURCE = $(filter-out $(C_SOURCE) $(CPP_SOURCE) $(ASM_SOURCE), $(SRC))
ifneq ($(UNKNOWN_SOURCE),)
   $(error Unknown input source formats: $(UNKNOWN_SOURCE))
endif

# Convert input source filenames into a list of required output object files
137
138
139
140
141
142
143
144
OBJECT_FILES = $(filter %.o, $(C_SOURCE:%.c=%.o) $(CPP_SOURCE:%.cpp=%.o) $(ASM_SOURCE:%.S=%.o))
ifneq ($(OBJDIR),.)
   $(shell mkdir $(OBJDIR) 2>&1 | /dev/null)   
   VPATH           += $(dir $(SRC))
   
   OBJECT_FILES    := $(addprefix $(patsubst %/,%,$(OBJDIR))/, $(notdir $(OBJECT_FILES)))
endif

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
DEPENDENCY_FILES = $(OBJECT_FILES:%.o=%.d)

# Create a list of common flags to pass to the compiler/linker/assembler
BASE_CC_FLAGS    := 
ifeq ($(ARCH), AVR8)
   BASE_CC_FLAGS += -mmcu=$(MCU) -gdwarf-2 -fshort-enums -fno-inline-small-functions -fpack-struct
else ifeq ($(ARCH), XMEGA)
   BASE_CC_FLAGS += -mmcu=$(MCU) -gdwarf-2 -fshort-enums -fno-inline-small-functions -fpack-struct
else ifeq ($(ARCH), UC3)
   BASE_CC_FLAGS += -mpart=$(MCU:at32%=%) -g3 -masm-addr-pseudos
endif
BASE_CC_FLAGS += -Wall -fno-strict-aliasing -funsigned-char -funsigned-bitfields -ffunction-sections
BASE_CC_FLAGS += -I. -I$(patsubst %/,%,$(LUFA_PATH))/..
BASE_CC_FLAGS += -DARCH=ARCH_$(ARCH) -DBOARD=BOARD_$(BOARD) -DF_USB=$(F_USB)UL
ifneq ($(F_CPU),)
   BASE_CC_FLAGS += -DF_CPU=$(F_CPU)UL
endif

# Additional language specific compiler flags
BASE_C_FLAGS   := -x c -O$(OPTIMIZATION) -std=$(C_STANDARD) -Wstrict-prototypes
BASE_CPP_FLAGS := -x c++ -O$(OPTIMIZATION) -std=$(CPP_STANDARD)
BASE_ASM_FLAGS := -x assembler-with-cpp

# Create a list of flags to pass to the linker
BASE_LD_FLAGS := -lm -Wl,-Map=$(TARGET).map,--cref -Wl,--gc-sections 
ifeq ($(ARCH), UC3)
   BASE_LD_FLAGS += --rodata-writable --direct-data   
else
   BASE_LD_FLAGS += -Wl,--relax
endif

# Determine flags to pass to the size utility based on its reported features
SIZE_MCU_FLAG    := $(shell $(CROSS)size --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
SIZE_FORMAT_FLAG := $(shell $(CROSS)size --help | grep -- --format=.*avr > /dev/null && echo --format=avr )


181
build_begin:
182
183
184
185
	@echo ""
	@echo $(MSG_BUILD_BEGIN)
	@echo ""
	
186
build_end:
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	@echo $(MSG_BUILD_END)
	@echo ""

gcc_version:
	@$(CROSS)gcc --version

check_source:
	@for f in $(SRC); do \
		if [ ! -f $$f ]; then \
			echo "Error: Source file not found: $$f"; \
			exit 1; \
		fi; \
	 done

size: $(TARGET).elf
	@echo $(MSG_SIZE_CMD) Determining size of \"$<\"
203
204
	@echo ""
	$(CROSS)size $(SIZE_MCU_FLAG) $(SIZE_FORMAT_FLAG) $< ; 2>/dev/null;
205
206
207
208
209
210
211
212
213
214
215

symbol-sizes: $(TARGET).elf
	@echo $(MSG_NM_CMD) Extracting \"$<\" symbols with decimal byte sizes
	avr-nm --size-sort --demangle --radix=d $<

clean:
	@echo $(MSG_REMOVE_CMD) Removing object files of \"$(TARGET)\"
	rm -f $(OBJECT_FILES)
	@echo $(MSG_REMOVE_CMD) Removing dependency files of \"$(TARGET)\"
	rm -f $(DEPENDENCY_FILES)
	@echo $(MSG_REMOVE_CMD) Removing output files of \"$(TARGET)\"
216
	rm -f $(TARGET).elf $(TARGET).hex $(TARGET).eep $(TARGET).map $(TARGET).lss $(TARGET).sym
217

218
all: build_begin check_source gcc_version elf hex lss sym size build_end
219
220
221
222

elf: $(TARGET).elf
hex: $(TARGET).hex $(TARGET).eep
lss: $(TARGET).lss
223
sym: $(TARGET).sym
224

225
$(OBJDIR)/%.o: %.c $(MAKEFILE_LIST)
226
	@echo $(MSG_COMPILE_CMD) Compiling C file \"$(notdir $<)\"
227
228
	$(CROSS)gcc -c $(BASE_CC_FLAGS) $(BASE_C_FLAGS) $(CC_FLAGS) $(C_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@

229
$(OBJDIR)/%.o: %.cpp $(MAKEFILE_LIST)
230
	@echo $(MSG_COMPILE_CMD) Compiling C++ file \"$(notdir $<)\"
231
232
	$(CROSS)gcc -c $(BASE_CC_FLAGS) $(BASE_CPP_FLAGS) $(CC_FLAGS) $(CPP_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@
	
233
$(OBJDIR)/%.o: %.S $(MAKEFILE_LIST)
234
	@echo $(MSG_ASSEMBLE_CMD) Assembling \"$(notdir $<)\"
235
236
	$(CROSS)gcc -c $(BASE_CC_FLAGS) $(BASE_ASM_FLAGS) $(CC_FLAGS) $(ASM_FLAGS) $< -o $@

237
238
.PRECIOUS  : $(OBJECT_FILES)
.SECONDARY : %.elf
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
%.elf: $(OBJECT_FILES)
	@echo $(MSG_LINKER_CMD) Linking object files into \"$@\"
	$(CROSS)gcc $(BASE_CC_FLAGS) $(BASE_LD_FLAGS) $(CC_FLAGS) $(LD_FLAGS) $^ -o $@

%.hex: %.elf
	@echo $(MSG_OBJCPY_CMD) Extracting HEX file data from \"$<\"
	$(CROSS)objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@

%.eep: %.elf
	@echo $(MSG_OBJCPY_CMD) Extracting EEP file data from \"$<\"
	$(CROSS)objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex $< $@ || exit 0

%.lss: %.elf
	@echo $(MSG_OBJDMP_CMD) Extracting LSS file data from \"$<\"
	$(CROSS)objdump -h -S -z $< > $@

255
256
257
258
%.sym: %.elf
	@echo $(MSG_NM_CMD) Extracting SYM file data from \"$<\"
	$(CROSS)nm -n $< > $@

259
260
261
262
# Include build dependency files
-include $(DEPENDENCY_FILES)

# Phony build targets for this module
263
.PHONY: build_begin build_end gcc_version check_source size symbol-sizes elf hex lss clean