1# List of available make goals:
2#
3# all                     Default target, builds the project
4# clean                   Clean up the project
5# rebuild                 Rebuild the project
6#
7# doc                     Build the documentation
8# cleandoc                Clean up the documentation
9# rebuilddoc              Rebuild the documentation
10#
11#
12# Copyright (c) 2009 - 2013 Atmel Corporation. All rights reserved.
13#
14# \asf_license_start
15#
16# \page License
17#
18# Redistribution and use in source and binary forms, with or without
19# modification, are permitted provided that the following conditions are met:
20#
21# 1. Redistributions of source code must retain the above copyright notice,
22#    this list of conditions and the following disclaimer.
23#
24# 2. Redistributions in binary form must reproduce the above copyright notice,
25#    this list of conditions and the following disclaimer in the documentation
26#    and/or other materials provided with the distribution.
27#
28# 3. The name of Atmel may not be used to endorse or promote products derived
29#    from this software without specific prior written permission.
30#
31# 4. This software may only be redistributed and used in connection with an
32#    Atmel microcontroller product.
33#
34# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
35# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
37# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
38# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
42# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
43# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44# POSSIBILITY OF SUCH DAMAGE.
45#
46# \asf_license_stop
47#
48
49# Include the config.mk file from the current working path, e.g., where the
50# user called make.
51include config.mk
52
53# Tool to use to generate documentation from the source code
54DOCGEN          ?= doxygen
55
56# Look for source files relative to the top-level source directory
57VPATH           := $(PRJ_PATH)
58
59# Output target file
60target          := $(TARGET)
61
62# Output project name (target name minus suffix)
63project         := $(basename $(target))
64
65# Output target file (typically ELF or static library)
66ifeq ($(suffix $(target)),.a)
67target_type     := lib
68else
69ifeq ($(suffix $(target)),.elf)
70target_type     := elf
71else
72$(error "Target type $(target_type) is not supported")
73endif
74endif
75
76# Allow override of operating system detection. The user can add OS=Linux or
77# OS=Windows on the command line to explicit set the host OS.
78#
79# This allows to work around broken uname utility on certain systems.
80ifdef OS
81  ifeq ($(strip $(OS)), Linux)
82    os_type     := Linux
83  endif
84  ifeq ($(strip $(OS)), Windows)
85    os_type     := windows32_64
86  endif
87endif
88
89os_type         ?= $(strip $(shell uname))
90
91ifeq ($(os_type),windows32)
92os              := Windows
93else
94ifeq ($(os_type),windows64)
95os              := Windows
96else
97ifeq ($(os_type),windows32_64)
98os              ?= Windows
99else
100ifeq ($(os_type),)
101os              := Windows
102else
103# Default to Linux style operating system. Both Cygwin and mingw are fully
104# compatible (for this Makefile) with Linux.
105os              := Linux
106endif
107endif
108endif
109endif
110
111# Output documentation directory and configuration file.
112docdir          := ../doxygen/html
113doccfg          := ../doxygen/doxyfile.doxygen
114
115CROSS           ?= avr-
116AR              := $(CROSS)ar
117AS              := $(CROSS)as
118CC              := $(CROSS)gcc
119CPP             := $(CROSS)gcc -E
120CXX             := $(CROSS)g++
121LD              := $(CROSS)gcc
122NM              := $(CROSS)nm
123OBJCOPY         := $(CROSS)objcopy
124OBJDUMP         := $(CROSS)objdump
125SIZE            := $(CROSS)size
126
127RM              := rm
128ifeq ($(os),Windows)
129RMDIR           := rmdir /S /Q
130else
131RMDIR           := rmdir -p --ignore-fail-on-non-empty
132endif
133
134# On Windows, we need to override the shell to force the use of cmd.exe
135ifeq ($(os),Windows)
136SHELL           := cmd
137endif
138
139# Strings for beautifying output
140MSG_CLEAN_FILES         = "RM      *.o *.d"
141MSG_CLEAN_DIRS          = "RMDIR   $(strip $(clean-dirs))"
142MSG_CLEAN_DOC           = "RMDIR   $(docdir)"
143MSG_MKDIR               = "MKDIR   $(dir $@)"
144
145MSG_INFO                = "INFO    "
146MSG_PREBUILD            = "PREBUILD  $(PREBUILD_CMD)"
147MSG_POSTBUILD           = "POSTBUILD $(POSTBUILD_CMD)"
148
149MSG_ARCHIVING           = "AR      $@"
150MSG_ASSEMBLING          = "AS      $@"
151MSG_BINARY_IMAGE        = "OBJCOPY $@"
152MSG_COMPILING           = "CC      $@"
153MSG_COMPILING_CXX       = "CXX     $@"
154MSG_EEPROM_IMAGE        = "OBJCOPY $@"
155MSG_EXTENDED_LISTING    = "OBJDUMP $@"
156MSG_IHEX_IMAGE          = "OBJCOPY $@"
157MSG_LINKING             = "LN      $@"
158MSG_PREPROCESSING       = "CPP     $@"
159MSG_SIZE                = "SIZE    $@"
160MSG_SYMBOL_TABLE        = "NM      $@"
161
162MSG_GENERATING_DOC      = "DOXYGEN $(docdir)"
163
164# Don't use make's built-in rules and variables
165MAKEFLAGS       += -rR
166
167# Don't print 'Entering directory ...'
168MAKEFLAGS       += --no-print-directory
169
170# Function for reversing the order of a list
171reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
172
173# Hide command output by default, but allow the user to override this
174# by adding V=1 on the command line.
175#
176# This is inspired by the Kbuild system used by the Linux kernel.
177ifdef V
178  ifeq ("$(origin V)", "command line")
179    VERBOSE = $(V)
180  endif
181endif
182ifndef VERBOSE
183  VERBOSE = 0
184endif
185
186ifeq ($(VERBOSE), 1)
187  Q =
188else
189  Q = @
190endif
191
192arflags-gnu-y           := $(ARFLAGS)
193asflags-gnu-y           := $(ASFLAGS)
194cflags-gnu-y            := $(CFLAGS)
195cxxflags-gnu-y          := $(CXXFLAGS)
196cppflags-gnu-y          := $(CPPFLAGS)
197cpuflags-gnu-y          :=
198dbgflags-gnu-y          := $(DBGFLAGS)
199libflags-gnu-y          := $(foreach LIB,$(LIBS),-l$(LIB))
200ldflags-gnu-y           := $(LDFLAGS)
201flashflags-gnu-y        := $(FLASHFLAGS)
202eepromflags-gnu-y       := $(EEPROMFLAGS)
203clean-files             :=
204clean-dirs              :=
205
206clean-files             += $(wildcard $(target) $(project).map)
207clean-files             += $(wildcard $(project).hex $(project).eep)
208clean-files             += $(wildcard $(project).lss $(project).sym)
209clean-files             += $(wildcard $(build))
210
211# Use pipes instead of temporary files for communication between processes
212cflags-gnu-y    += -pipe
213asflags-gnu-y   += -pipe
214ldflags-gnu-y   += -pipe
215
216# Archiver flags.
217arflags-gnu-y   += rcs
218
219# Always enable warnings. And be very careful about implicit
220# declarations.
221cflags-gnu-y    += -Wall -Wstrict-prototypes -Wmissing-prototypes
222cflags-gnu-y    += -Werror-implicit-function-declaration
223cxxflags-gnu-y  += -Wall
224# IAR doesn't allow arithmetic on void pointers, so warn about that.
225cflags-gnu-y    += -Wpointer-arith
226cxxflags-gnu-y  += -Wpointer-arith
227
228# Preprocessor flags.
229cppflags-gnu-y  += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC))
230asflags-gnu-y   += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)')
231
232# CPU specific flags.
233cpuflags-gnu-y  += -mmcu=$(MCU)
234
235# Dependency file flags.
236depflags        = -MD -MP -MQ $@
237
238# Debug specific flags.
239ifdef BUILD_DEBUG_LEVEL
240dbgflags-gnu-y  += -g$(BUILD_DEBUG_LEVEL)
241else
242dbgflags-gnu-y  += -gdwarf-2
243endif
244
245# Optimization specific flags.
246ifdef BUILD_OPTIMIZATION
247optflags-gnu-y  = -O$(BUILD_OPTIMIZATION)
248else
249optflags-gnu-y  = $(OPTIMIZATION)
250endif
251
252# Relax compilation and linking.
253cflags-gnu-y    += -mrelax
254cxxflags-gnu-y  += -mrelax
255asflags-gnu-y   += -mrelax
256ldflags-gnu-y   += -Wl,--relax
257
258# Always preprocess assembler files.
259asflags-gnu-y   += -x assembler-with-cpp
260# Compile C files using the GNU99 standard.
261cflags-gnu-y    += -std=gnu99
262# Compile C++ files using the GNU++98 standard.
263cxxflags-gnu-y  += -std=gnu++98
264
265# Use unsigned character type when compiling.
266cflags-gnu-y    += -funsigned-char
267cxxflags-gnu-y  += -funsigned-char
268
269# Don't use strict aliasing (very common in embedded applications).
270cflags-gnu-y    += -fno-strict-aliasing
271cxxflags-gnu-y  += -fno-strict-aliasing
272
273# Separate each function and data into its own separate section to allow
274# garbage collection of unused sections.
275cflags-gnu-y    += -ffunction-sections -fdata-sections
276cxxflags-gnu-y  += -ffunction-sections -fdata-sections
277
278# Garbage collect unreferred sections when linking.
279ldflags-gnu-y   += -Wl,--gc-sections
280
281# Output a link map file and a cross reference table
282ldflags-gnu-y   += -Wl,-Map=$(project).map,--cref
283
284# Add library search paths relative to the top level directory.
285ldflags-gnu-y   += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH))
286
287a_flags  = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__
288c_flags  = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y)
289cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y)
290l_flags  = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y)
291ar_flags = $(arflags-gnu-y)
292
293# Intel Hex file production flags
294flashflags-gnu-y        += -R .eeprom -R .usb_descriptor_table
295
296# Eeprom file production flags
297eepromflags-gnu-y       += -j .eeprom
298eepromflags-gnu-y       += --set-section-flags=.eeprom="alloc,load"
299eepromflags-gnu-y       += --change-section-lma .eeprom=0
300
301# Source files list and part informations must already be included before
302# running this makefile
303
304# If a custom build directory is specified, use it -- force trailing / in directory name.
305ifdef BUILD_DIR
306	build-dir       := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/)
307else
308	build-dir        =
309endif
310
311# Create object files list from source files list.
312obj-y                   := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS))))
313
314# Create dependency files list from source files list.
315dep-files               := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d))
316
317clean-files             += $(wildcard $(obj-y))
318clean-files             += $(dep-files)
319
320clean-dirs              += $(call reverse,$(sort $(wildcard $(dir $(obj-y)))))
321
322# Default target.
323.PHONY: all
324ifeq ($(target_type),lib)
325all: $(target) $(project).lss $(project).sym
326else
327ifeq ($(target_type),elf)
328all: prebuild $(target) $(project).lss $(project).sym $(project).hex $(project).bin postbuild
329endif
330endif
331
332prebuild:
333ifneq ($(strip $(PREBUILD_CMD)),)
334	@echo $(MSG_PREBUILD)
335	$(Q)$(PREBUILD_CMD)
336endif
337
338postbuild:
339ifneq ($(strip $(POSTBUILD_CMD)),)
340	@echo $(MSG_POSTBUILD)
341	$(Q)$(POSTBUILD_CMD)
342endif
343
344# Clean up the project.
345.PHONY: clean
346clean:
347	@$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES))
348	$(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),)
349	@$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS))
350# Remove created directories, and make sure we only remove existing
351# directories, since recursive rmdir might help us a bit on the way.
352ifeq ($(os),Windows)
353	$(Q)$(if $(strip $(clean-dirs)),                        \
354			$(RMDIR) $(strip $(subst /,\,$(clean-dirs))))
355else
356	$(Q)$(if $(strip $(clean-dirs)),                        \
357		for directory in $(strip $(clean-dirs)); do     \
358			if [ -d "$$directory" ]; then           \
359				$(RMDIR) $$directory;           \
360			fi                                      \
361		done                                            \
362	)
363endif
364
365# Rebuild the project.
366.PHONY: rebuild
367rebuild: clean all
368
369.PHONY: objfiles
370objfiles: $(obj-y)
371
372# Create object files from C source files.
373$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk
374	$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
375ifeq ($(os),Windows)
376	$(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@))
377else
378	$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
379endif
380	@echo $(MSG_COMPILING)
381	$(Q)$(CC) $(c_flags) -c $< -o $@
382
383# Create object files from C++ source files.
384$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk
385	$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
386ifeq ($(os),Windows)
387	$(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@))
388else
389	$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
390endif
391	@echo $(MSG_COMPILING_CXX)
392	$(Q)$(CXX) $(cxx_flags) -c $< -o $@
393
394# Preprocess and assemble: create object files from assembler source files.
395$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk
396	$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
397ifeq ($(os),Windows)
398	$(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@))
399else
400	$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
401endif
402	@echo $(MSG_ASSEMBLING)
403	$(Q)$(CC) $(a_flags) -c $< -o $@
404
405# Preprocess and assemble: create object files from assembler source files.
406$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk
407	$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
408ifeq ($(os),Windows)
409	$(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@))
410else
411	$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
412endif
413	@echo $(MSG_ASSEMBLING)
414	$(Q)$(CC) $(a_flags) -c $< -o $@
415
416# Include all dependency files to add depedency to all header files in use.
417include $(dep-files)
418
419ifeq ($(target_type),lib)
420# Archive object files into an archive
421$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
422	@echo $(MSG_ARCHIVING)
423	$(Q)$(AR) $(ar_flags) $@ $(obj-y)
424	@echo $(MSG_SIZE)
425	$(Q)$(SIZE) -Bxt $@
426else
427ifeq ($(target_type),elf)
428# Link the object files into an ELF file. Also make sure the target is rebuilt
429# if the common Makefile.avr.in or project config.mk is changed.
430$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
431	@echo $(MSG_LINKING)
432	$(Q)$(LD) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@
433	@echo $(MSG_SIZE)
434	$(Q)$(SIZE) -Ax $@
435	$(Q)$(SIZE) -Bx $@
436endif
437endif
438
439# Create extended function listing from target output file.
440%.lss: $(target)
441	@echo $(MSG_EXTENDED_LISTING)
442	$(Q)$(OBJDUMP) -h -S $< > $@
443
444# Create symbol table from target output file.
445%.sym: $(target)
446	@echo $(MSG_SYMBOL_TABLE)
447	$(Q)$(NM) -n $< > $@
448
449# Create Intel HEX image from ELF output file.
450%.hex: $(target)
451	@echo $(MSG_IHEX_IMAGE)
452	$(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y)  $< $@
453
454# Create EEPROM Intel HEX image from ELF output file.
455%.eep: $(target)
456	@echo $(MSG_EEPROM_IMAGE)
457	$(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@  || exit 0
458
459# Create binary image from ELF output file.
460%.bin: $(target)
461	@echo $(MSG_BINARY_IMAGE)
462	$(Q)$(OBJCOPY) -O binary $< $@
463
464# Provide information about the detected host operating system.
465.SECONDARY: info-os
466info-os:
467	@echo $(MSG_INFO)$(os) build host detected
468
469# Build Doxygen generated documentation.
470.PHONY: doc
471doc:
472	@echo $(MSG_GENERATING_DOC)
473	$(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg))
474
475# Clean Doxygen generated documentation.
476.PHONY: cleandoc
477cleandoc:
478	@$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC))
479	$(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir))
480
481# Rebuild the Doxygen generated documentation.
482.PHONY: rebuilddoc
483rebuilddoc: cleandoc doc
484