3 # Copyright (C) Dean Camera, 2014.
5 # dean [at] fourwalledcubicle [dot] com
9 LUFA_BUILD_MODULES
+= BUILD
10 LUFA_BUILD_TARGETS
+= size symbol-sizes
all lib elf bin hex lss
clean mostlyclean
11 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 OBJECT_FILES DEBUG_TYPE DEBUG_LEVEL LINKER_RELAXATIONS COMPILER_PATH
13 LUFA_BUILD_PROVIDED_VARS
+=
14 LUFA_BUILD_PROVIDED_MACROS
+=
16 # -----------------------------------------------------------------------------
17 # LUFA GCC Compiler Buildsystem Makefile Module.
18 # -----------------------------------------------------------------------------
20 # Provides a set of targets to build a C, C++ and/or Assembly application
21 # via the AVR-GCC compiler.
22 # -----------------------------------------------------------------------------
25 # size - List built application size
26 # symbol-sizes - Print application symbols from the binary ELF
27 # file as a list sorted by size in bytes
28 # all - Build application and list size
29 # lib - Build and archive source files into a library
30 # elf - Build application ELF debug object file
31 # bin - Build application BIN binary object file
32 # hex - Build application HEX object file
33 # lss - Build application LSS assembly listing file
34 # clean - Remove all project intermediary and binary
36 # mostlyclean - Remove intermediary output files, but
38 # <filename>.s - Compile C/C++ source file into an assembly file
39 # for manual code inspection
41 # MANDATORY PARAMETERS:
43 # TARGET - Application name
44 # ARCH - Device architecture name
45 # MCU - Microcontroller device model name
46 # SRC - List of input source files (*.c, *.cpp, *.S)
47 # F_USB - Speed of the input clock of the USB controller
49 # LUFA_PATH - Path to the LUFA library core
51 # OPTIONAL PARAMETERS:
53 # BOARD - LUFA board hardware
54 # OPTIMIZATION - Optimization level
55 # C_STANDARD - C Language Standard to use
56 # CPP_STANDARD - C++ Language Standard to use
57 # F_CPU - Speed of the CPU, in Hz
58 # C_FLAGS - Flags to pass to the C compiler only
59 # CPP_FLAGS - Flags to pass to the C++ compiler only
60 # ASM_FLAGS - Flags to pass to the assembler only
61 # CC_FLAGS - Common flags to pass to the C/C++ compiler and
63 # LD_FLAGS - Flags to pass to the linker
64 # LINKER_RELAXATIONS - Enable or disable linker relaxations to
65 # decrease binary size (note: can cause link
66 # failures on systems with an unpatched binutils)
67 # OBJDIR - Directory for the output object and dependency
68 # files; if equal to ".", the output files will
69 # be generated in the same folder as the sources
70 # OBJECT_FILES - Extra object files to link in to the binaries
71 # DEBUG_FORMAT - Format of the debugging information to
72 # generate in the compiled object files
73 # DEBUG_LEVEL - Level the debugging information to generate in
74 # the compiled object files
75 # COMPILER_PATH - Location of the GCC toolchain to use
85 # -----------------------------------------------------------------------------
89 ERROR_IF_UNSET ?
= $(if
$(filter undefined
, $(origin $(strip $(1)))), $(error Makefile
$(strip $(1)) value not set
))
90 ERROR_IF_EMPTY ?
= $(if
$(strip $($(strip $(1)))), , $(error Makefile
$(strip $(1)) option cannot be blank
))
91 ERROR_IF_NONBOOL ?
= $(if
$(filter Y N
, $($(strip $(1)))), , $(error Makefile
$(strip $(1)) option must be Y or N
))
93 # Default values of optionally user-supplied variables
99 CPP_STANDARD ?
= gnu
++98
106 DEBUG_FORMAT ?
= dwarf-2
108 LINKER_RELAXATIONS ?
= Y
110 # Sanity check user supplied values
111 $(foreach MANDATORY_VAR
, $(LUFA_BUILD_MANDATORY_VARS
), $(call ERROR_IF_UNSET
, $(MANDATORY_VAR
)))
112 $(call ERROR_IF_EMPTY
, MCU
)
113 $(call ERROR_IF_EMPTY
, TARGET
)
114 $(call ERROR_IF_EMPTY
, ARCH
)
115 $(call ERROR_IF_EMPTY
, F_USB
)
116 $(call ERROR_IF_EMPTY
, LUFA_PATH
)
117 $(call ERROR_IF_EMPTY
, BOARD
)
118 $(call ERROR_IF_EMPTY
, OPTIMIZATION
)
119 $(call ERROR_IF_EMPTY
, C_STANDARD
)
120 $(call ERROR_IF_EMPTY
, CPP_STANDARD
)
121 $(call ERROR_IF_EMPTY
, OBJDIR
)
122 $(call ERROR_IF_EMPTY
, DEBUG_FORMAT
)
123 $(call ERROR_IF_EMPTY
, DEBUG_LEVEL
)
124 $(call ERROR_IF_NONBOOL
, LINKER_RELAXATIONS
)
126 # Determine the utility prefix to use for the selected architecture
128 CROSS
:= $(COMPILER_PATH
)avr
129 else ifeq ($(ARCH
), XMEGA
)
130 CROSS
:= $(COMPILER_PATH
)avr
131 $(warning The XMEGA device support is currently EXPERIMENTAL
(incomplete and
/or non-functional
), and is included for preview purposes only.
)
132 else ifeq ($(ARCH
), UC3
)
133 CROSS
:= $(COMPILER_PATH
)avr32
134 $(warning The UC3 device support is currently EXPERIMENTAL
(incomplete and
/or non-functional
), and is included for preview purposes only.
)
136 $(error Unsupported architecture
"$(ARCH)")
140 MSG_INFO_MESSAGE
:= ' [INFO] :'
141 MSG_COMPILE_CMD
:= ' [GCC] :'
142 MSG_ASSEMBLE_CMD
:= ' [GAS] :'
143 MSG_NM_CMD
:= ' [NM] :'
144 MSG_REMOVE_CMD
:= ' [RM] :'
145 MSG_LINK_CMD
:= ' [LNK] :'
146 MSG_ARCHIVE_CMD
:= ' [AR] :'
147 MSG_SIZE_CMD
:= ' [SIZE] :'
148 MSG_OBJCPY_CMD
:= ' [OBJCPY] :'
149 MSG_OBJDMP_CMD
:= ' [OBJDMP] :'
151 # Convert input source file list to differentiate them by type
152 C_SOURCE
:= $(filter %.c
, $(SRC
))
153 CPP_SOURCE
:= $(filter %.
cpp, $(SRC
))
154 ASM_SOURCE
:= $(filter %.S
, $(SRC
))
156 # Create a list of unknown source file types, if any are found throw an error
157 UNKNOWN_SOURCE
:= $(filter-out $(C_SOURCE
) $(CPP_SOURCE
) $(ASM_SOURCE
), $(SRC
))
158 ifneq ($(UNKNOWN_SOURCE
),)
159 $(error Unknown input source file formats
: $(UNKNOWN_SOURCE
))
162 # Convert input source filenames into a list of required output object files
163 OBJECT_FILES
+= $(addsuffix .o
, $(basename $(SRC
)))
165 # Check if an output object file directory was specified instead of the input file location
167 # Prefix all the object filenames with the output object file directory path
168 OBJECT_FILES
:= $(addprefix $(patsubst %/,%,$(OBJDIR
))/, $(notdir $(OBJECT_FILES
)))
170 # Check if any object file (without path) appears more than once in the object file list
171 ifneq ($(words $(sort $(OBJECT_FILES
))), $(words $(OBJECT_FILES
)))
172 $(error Cannot build with OBJDIR parameter set
- one or more object file name is not unique
)
175 # Create the output object file directory if it does not exist and add it to the virtual path list
176 $(shell mkdir
$(OBJDIR
) 2> /dev
/null
)
177 VPATH
+= $(dir $(SRC
))
180 # Create a list of dependency files from the list of object files
181 DEPENDENCY_FILES
:= $(OBJECT_FILES
:%.o
=%.d
)
183 # Create a list of common flags to pass to the compiler/linker/assembler
184 BASE_CC_FLAGS
:= -pipe
-g
$(DEBUG_FORMAT
) -g
$(DEBUG_LEVEL
)
186 BASE_CC_FLAGS
+= -mmcu
=$(MCU
) -fshort-enums
-fno-inline-small-functions
-fpack-struct
187 else ifeq ($(ARCH
), XMEGA
)
188 BASE_CC_FLAGS
+= -mmcu
=$(MCU
) -fshort-enums
-fno-inline-small-functions
-fpack-struct
189 else ifeq ($(ARCH
), UC3
)
190 BASE_CC_FLAGS
+= -mpart
=$(MCU
:at32
%=%) -masm-addr-pseudos
192 BASE_CC_FLAGS
+= -Wall
-fno-strict-aliasing
-funsigned-char
-funsigned-bitfields
-ffunction-sections
193 BASE_CC_FLAGS
+= -I.
-I
$(patsubst %/,%,$(LUFA_PATH
))/..
194 BASE_CC_FLAGS
+= -DARCH
=ARCH_
$(ARCH
) -DBOARD
=BOARD_
$(BOARD
) -DF_USB
=$(F_USB
)UL
196 BASE_CC_FLAGS
+= -DF_CPU
=$(F_CPU
)UL
198 ifeq ($(LINKER_RELAXATIONS
), Y
)
199 BASE_CC_FLAGS
+= -mrelax
202 # Additional language specific compiler flags
203 BASE_C_FLAGS
:= -x c
-O
$(OPTIMIZATION
) -std
=$(C_STANDARD
) -Wstrict-prototypes
204 BASE_CPP_FLAGS
:= -x c
++ -O
$(OPTIMIZATION
) -std
=$(CPP_STANDARD
)
205 BASE_ASM_FLAGS
:= -x assembler-with-cpp
207 # Create a list of flags to pass to the linker
208 BASE_LD_FLAGS
:= -lm
-Wl
,-Map
=$(TARGET
).map
,--cref
-Wl
,--gc-sections
209 ifeq ($(LINKER_RELAXATIONS
), Y
)
210 BASE_LD_FLAGS
+= -Wl
,--relax
213 BASE_LD_FLAGS
+= -mmcu
=$(MCU
)
214 else ifeq ($(ARCH
), XMEGA
)
215 BASE_LD_FLAGS
+= -mmcu
=$(MCU
)
216 else ifeq ($(ARCH
), UC3
)
217 BASE_LD_FLAGS
+= -mpart
=$(MCU
:at32
%=%) --rodata-writable
--direct-data
220 # Determine flags to pass to the size utility based on its reported features (only invoke if size target required)
221 # and on an architecture where this non-standard patch is available
223 size
: SIZE_MCU_FLAG
:= $(shell $(CROSS
)-size
--help | grep
-- --mcu
> /dev
/null
&& echo
--mcu
=$(MCU
) )
224 size
: SIZE_FORMAT_FLAG
:= $(shell $(CROSS
)-size
--help | grep
-- --format
=.
*avr
> /dev
/null
&& echo
--format
=avr
)
227 # Pre-build informational target, to give compiler and project name information when building
229 @echo
$(MSG_INFO_MESSAGE
) Begin compilation of project
\"$(TARGET
)\"...
231 @
$(CROSS
)-gcc
--version
233 # Post-build informational target, to project name information when building has completed
235 @echo
$(MSG_INFO_MESSAGE
) Finished building project
\"$(TARGET
)\".
237 # Prints size information of a compiled application (FLASH, RAM and EEPROM usages)
239 @echo
$(MSG_SIZE_CMD
) Determining size of
\"$<\"
241 $(CROSS
)-size
$(SIZE_MCU_FLAG
) $(SIZE_FORMAT_FLAG
) $<
243 # Prints size information on the symbols within a compiled application in decimal bytes
244 symbol-sizes
: $(TARGET
).elf
245 @echo
$(MSG_NM_CMD
) Extracting
\"$<\" symbols with decimal byte sizes
246 $(CROSS
)-nm
--size-sort
--demangle
--radix
=d
$<
248 # Cleans intermediary build files, leaving only the compiled application files
250 @echo
$(MSG_REMOVE_CMD
) Removing object files of
\"$(TARGET
)\"
251 rm -f
$(OBJECT_FILES
)
252 @echo
$(MSG_REMOVE_CMD
) Removing dependency files of
\"$(TARGET
)\"
253 rm -f
$(DEPENDENCY_FILES
)
255 # Cleans all build files, leaving only the original source code
257 @echo
$(MSG_REMOVE_CMD
) Removing output files of
\"$(TARGET
)\"
258 rm -f
$(TARGET
).elf
$(TARGET
).hex
$(TARGET
).bin
$(TARGET
).eep
$(TARGET
).map
$(TARGET
).lss
$(TARGET
).sym
$(TARGET
).a
260 # Performs a complete build of the user application and prints size information afterwards
261 all: build_begin elf hex bin lss sym size build_end
263 # Helper targets, to build a specific type of output file without having to know the project target name
266 hex
: $(TARGET
).hex
$(TARGET
).eep
271 # Default target to *create* the user application's specified source files; if this rule is executed by
272 # make, the input source file doesn't exist and an error needs to be presented to the user
274 $(error Source file does not exist
: $@
)
276 # Compiles an input C source file and generates an assembly listing for it
277 %.s
: %.c
$(MAKEFILE_LIST
)
278 @echo
$(MSG_COMPILE_CMD
) Generating assembly from C file
\"$(notdir $<)\"
279 $(CROSS
)-gcc
-S
$(BASE_CC_FLAGS
) $(BASE_C_FLAGS
) $(CC_FLAGS
) $(C_FLAGS
) $< -o
$@
281 # Compiles an input C++ source file and generates an assembly listing for it
282 %.s
: %.
cpp $(MAKEFILE_LIST
)
283 @echo
$(MSG_COMPILE_CMD
) Generating assembly from C
++ file
\"$(notdir $<)\"
284 $(CROSS
)-gcc
-S
$(BASE_CC_FLAGS
) $(BASE_CPP_FLAGS
) $(CC_FLAGS
) $(CPP_FLAGS
) $< -o
$@
286 # Compiles an input C source file and generates a linkable object file for it
287 $(OBJDIR
)/%.o
: %.c
$(MAKEFILE_LIST
)
288 @echo
$(MSG_COMPILE_CMD
) Compiling C file
\"$(notdir $<)\"
289 $(CROSS
)-gcc
-c
$(BASE_CC_FLAGS
) $(BASE_C_FLAGS
) $(CC_FLAGS
) $(C_FLAGS
) -MMD
-MP
-MF
$(@
:%.o
=%.d
) $< -o
$@
291 # Compiles an input C++ source file and generates a linkable object file for it
292 $(OBJDIR
)/%.o
: %.
cpp $(MAKEFILE_LIST
)
293 @echo
$(MSG_COMPILE_CMD
) Compiling C
++ file
\"$(notdir $<)\"
294 $(CROSS
)-gcc
-c
$(BASE_CC_FLAGS
) $(BASE_CPP_FLAGS
) $(CC_FLAGS
) $(CPP_FLAGS
) -MMD
-MP
-MF
$(@
:%.o
=%.d
) $< -o
$@
296 # Assembles an input ASM source file and generates a linkable object file for it
297 $(OBJDIR
)/%.o
: %.S
$(MAKEFILE_LIST
)
298 @echo
$(MSG_ASSEMBLE_CMD
) Assembling
\"$(notdir $<)\"
299 $(CROSS
)-gcc
-c
$(BASE_CC_FLAGS
) $(BASE_ASM_FLAGS
) $(CC_FLAGS
) $(ASM_FLAGS
) -MMD
-MP
-MF
$(@
:%.o
=%.d
) $< -o
$@
301 # Generates a library archive file from the user application, which can be linked into other applications
302 .PRECIOUS
: $(OBJECT_FILES
)
305 @echo
$(MSG_ARCHIVE_CMD
) Archiving object files into
\"$@
\"
306 $(CROSS
)-ar rcs
$@
$(OBJECT_FILES
)
308 # Generates an ELF debug file from the user application, which can be further processed for FLASH and EEPROM data
309 # files, or used for programming and debugging directly
310 .PRECIOUS
: $(OBJECT_FILES
)
312 %.elf
: $(OBJECT_FILES
)
313 @echo
$(MSG_LINK_CMD
) Linking object files into
\"$@
\"
314 $(CROSS
)-gcc
$^
-o
$@
$(BASE_LD_FLAGS
) $(LD_FLAGS
)
316 # Extracts out the loadable FLASH memory data from the project ELF file, and creates an Intel HEX format file of it
318 @echo
$(MSG_OBJCPY_CMD
) Extracting HEX file data from
\"$<\"
319 $(CROSS
)-objcopy
-O ihex
-R .eeprom
-R .fuse
-R .lock
-R .signature
$< $@
321 # Extracts out the loadable FLASH memory data from the project ELF file, and creates an Binary format file of it
323 @echo
$(MSG_OBJCPY_CMD
) Extracting BIN file data from
\"$<\"
324 $(CROSS
)-objcopy
-O binary
-R .eeprom
-R .fuse
-R .lock
-R .signature
$< $@
326 # Extracts out the loadable EEPROM memory data from the project ELF file, and creates an Intel HEX format file of it
328 @echo
$(MSG_OBJCPY_CMD
) Extracting EEP file data from
\"$<\"
329 $(CROSS
)-objcopy
-O ihex
-j .eeprom
--set-section-flags
=.eeprom
="alloc,load" --change-section-lma .eeprom
=0 --no-change-warnings
$< $@ || exit
0
331 # Creates an assembly listing file from an input project ELF file, containing interleaved assembly and source data
333 @echo
$(MSG_OBJDMP_CMD
) Extracting LSS file data from
\"$<\"
334 $(CROSS
)-objdump
-h
-d
-S
-z
$< > $@
336 # Creates a symbol file listing the loadable and discarded symbols from an input project ELF file
338 @echo
$(MSG_NM_CMD
) Extracting SYM file data from
\"$<\"
339 $(CROSS
)-nm
-n
$< > $@
341 # Include build dependency files
342 -include $(DEPENDENCY_FILES
)
344 # Phony build targets for this module
345 .PHONY
: build_begin build_end size symbol-sizes lib elf hex lss
clean mostlyclean