123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- #-------------------------------------------------------------------------------
- # Copyright (c) 2012 Freescale Semiconductor, Inc.
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without modification,
- # are permitted provided that the following conditions are met:
- #
- # o Redistributions of source code must retain the above copyright notice, this list
- # of conditions and the following disclaimer.
- #
- # o Redistributions in binary form must reproduce the above copyright notice, this
- # list of conditions and the following disclaimer in the documentation and/or
- # other materials provided with the distribution.
- #
- # o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- # contributors may be used to endorse or promote products derived from this
- # software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #-------------------------------------------------------------------------------
- #-------------------------------------------------------------------------------
- # Sources and objects
- #-------------------------------------------------------------------------------
- # Select our object root depending on whether we're building an app or lib.
- ifneq "$(APP_NAME)" ""
- OBJS_ROOT = $(APP_OBJS_ROOT)
- else
- OBJS_ROOT = $(LIB_OBJS_ROOT)
- endif
- # Strip sources.
- SOURCES := $(strip $(SOURCES))
- # Convert sources list to absolute paths and root-relative paths.
- SOURCES_ABS := $(foreach s,$(SOURCES),$(abspath $(s)))
- SOURCES_REL := $(subst $(SDK_ROOT)/,,$(SOURCES_ABS))
- # Get a list of unique directories containing the source files.
- SOURCE_DIRS_ABS := $(sort $(foreach f,$(SOURCES_ABS),$(dir $(f))))
- SOURCE_DIRS_REL := $(subst $(SDK_ROOT)/,,$(SOURCE_DIRS_ABS))
- OBJECTS_DIRS := $(addprefix $(OBJS_ROOT)/,$(SOURCE_DIRS_REL))
- # Filter source files list into separate source types.
- C_SOURCES = $(filter %.c,$(SOURCES_REL))
- CXX_SOURCES = $(filter %.cpp,$(SOURCES_REL))
- ASM_s_SOURCES = $(filter %.s,$(SOURCES_REL))
- ASM_S_SOURCES = $(filter %.S,$(SOURCES_REL))
- # Convert sources to objects.
- OBJECTS_C := $(addprefix $(OBJS_ROOT)/,$(C_SOURCES:.c=.o))
- OBJECTS_CXX := $(addprefix $(OBJS_ROOT)/,$(CXX_SOURCES:.cpp=.o))
- OBJECTS_ASM := $(addprefix $(OBJS_ROOT)/,$(ASM_s_SOURCES:.s=.o))
- OBJECTS_ASM_S := $(addprefix $(OBJS_ROOT)/,$(ASM_S_SOURCES:.S=.o))
- PREBUILT_OBJECTS = $(addprefix $(SDK_ROOT)/,$(filter %.o,$(SOURCES_REL)))
- # Complete list of all object files.
- OBJECTS_ALL := $(sort $(OBJECTS_C) $(OBJECTS_CXX) $(OBJECTS_ASM) $(OBJECTS_ASM_S) $(PREBUILT_OBJECTS))
- #-------------------------------------------------------------------------------
- # Target library
- #-------------------------------------------------------------------------------
- # Library where app objects are archived, if used.
- LIBAPP = $(APP_OUTPUT_ROOT)/lib$(APP_NAME).a
- # Build the target lib path from the lib name.
- ifneq "$(TARGET_LIB_NAME)" ""
- TARGET_LIB ?= $(LIBS_ROOT)/lib$(TARGET_LIB_NAME).a
- else ifeq "$(ARCHIVE_APP_OBJECTS)" "1"
- TARGET_LIB ?= $(LIBAPP)
- endif
- # Construct full path name to application output ELF file.
- ifneq "$(APP_NAME)" ""
- APP_ELF ?= $(APP_OUTPUT_ROOT)/$(APP_NAME).elf
- endif
- # Select the output target.
- ifneq "$(TARGET_LIB)" ""
- # Only use the target lib if there are actually objects to put into it.
- ifneq "$(strip $(OBJECTS_ALL))" ""
- archive_or_objs = $(TARGET_LIB)($(OBJECTS_ALL))
- endif
- else
- archive_or_objs = $(OBJECTS_ALL)
- endif
- #-------------------------------------------------------------------------------
- # Default target
- #-------------------------------------------------------------------------------
- # Note that prerequisite order is important here. The subdirectories must be built first, or you
- # may end up with files in the current directory not getting added to libraries. This would happen
- # if subdirs modified the library file after local files were compiled but before they were added
- # to the library.
- .PHONY: all
- all : $(SUBDIRS) $(archive_or_objs) $(APP_ELF)
- # Recipe to create the output object file directories.
- $(OBJECTS_DIRS) :
- $(at)mkdir -p $@
- # Everything depends upon the current makefile.
- $(OBJECTS_ALL) $(APP_ELF): $(this_makefile)
- # Object files depend on the directories where they will be created.
- #
- # The dirs are made order-only prerequisites (by being listed after the '|') so they won't cause
- # the objects to be rebuilt, as the modification date on a directory changes whenver its contents
- # change. This would cause the objects to always be rebuilt if the dirs were normal prerequisites.
- $(OBJECTS_ALL): | $(OBJECTS_DIRS)
- #-------------------------------------------------------------------------------
- # Pattern rules for compilation
- #-------------------------------------------------------------------------------
- # We cd into the source directory before calling the appropriate compiler. This must be done
- # on a single command line since make calls individual recipe lines in separate shells, so
- # '&&' is used to chain the commands.
- #
- # Generate make dependencies while compiling using the -MMD option, which excludes system headers.
- # If system headers are included, there are path problems on cygwin. The -MP option creates empty
- # targets for each header file so that a rebuild will be forced if the file goes missing, but
- # no error will occur.
- # Compile C sources.
- $(OBJS_ROOT)/%.o: $(SDK_ROOT)/%.c
- @$(call printmessage,c,Compiling, $(subst $(SDK_ROOT)/,,$<))
- $(at)cd $(dir $<) && $(CC) $(CFLAGS) $(SYSTEM_INC) $(INCLUDES) $(DEFINES) -MMD -MF $(basename $@).d -MP -o $@ -c $<
- # Compile C++ sources.
- $(OBJS_ROOT)/%.o: $(SDK_ROOT)/%.cpp
- @$(call printmessage,cxx,Compiling, $(subst $(SDK_ROOT)/,,$<))
- $(at)cd $(dir $<) && $(CXX) $(CXXFLAGS) $(SYSTEM_INC) $(INCLUDES) $(DEFINES) -MMD -MF $(basename $@).d -MP -o $@ -c $<
- # For .S assembly files, first run through the C preprocessor then assemble.
- $(OBJS_ROOT)/%.o: $(SDK_ROOT)/%.S
- @$(call printmessage,asm,Assembling, $(subst $(SDK_ROOT)/,,$<))
- $(at)cd $(dir $<) \
- && $(CPP) -D__LANGUAGE_ASM__ $(INCLUDES) $(DEFINES) -o $(basename $@).s $< \
- && $(AS) $(ASFLAGS) $(INCLUDES) -MD $(OBJS_ROOT)/$*.d -o $@ $(basename $@).s
- # Assembler sources.
- $(OBJS_ROOT)/%.o: $(SDK_ROOT)/%.s
- @$(call printmessage,asm,Assembling, $(subst $(SDK_ROOT)/,,$<))
- $(at)cd $(dir $<) && $(AS) $(ASFLAGS) $(INCLUDES) -MD $(basename $@).d -o $@ $<
- # Add objects to the target library.
- #
- # We use mkdir to explicitly ensure that the archive's directory exists before calling
- # the ar tool. The dir can't be made a dependancy because make will try to add it to the
- # archive.
- #
- # flock is used to protect the archive file from multiple processes trying to write to it
- # simultaneously, in case we're using parallel processes.
- #
- # The log message is disabled in order to reduce clutter in the build log, since you will get
- # one message for every file that is archived.
- $(TARGET_LIB)(%): %
- # @$(call printmessage,ar,Archiving, $(?F) in $(@F))
- $(at)mkdir -p $(dir $(@))
- $(at)flock $(@).lock $(AR) -rucs $@ $?
- #-------------------------------------------------------------------------------
- # Subdirs
- #-------------------------------------------------------------------------------
- # Recursively execute make in each of the subdirectories.
- # Subdirs are double-colon rules to allow additional recipes to be added to them.
- # This is used by the top-level makefile to print a message when starting to build
- # the sdk library.
- .PHONY: $(SUBDIRS)
- $(SUBDIRS)::
- @$(MAKE) $(silent_make) -r -C $@
- #-------------------------------------------------------------------------------
- # Linking
- #-------------------------------------------------------------------------------
- # Only link the application if LINK_APP is defined.
- ifeq "$(LINK_APP)" "1"
- # If app objects are being archived into a library, we don't need to specify the
- # actual .o files on the linker command line.
- ifeq "$(ARCHIVE_APP_OBJECTS)" "1"
- app_objs = $(TARGET_LIB)
- else
- app_objs = $(OBJECTS_ALL) $(TARGET_LIB)
- endif
- app_bin = $(basename $(APP_ELF)).bin
- app_map = $(basename $(APP_ELF)).map
- # Preprocess the linker script if it has an ".S" extension.
- ifeq "$(filter %.S,$(LD_FILE))" ""
- the_ld_file = $(LD_FILE)
- else
- rel_ld_file = $(basename $(subst $(SDK_ROOT)/,,$(abspath $(LD_FILE))))
- the_ld_file = $(addprefix $(OBJS_ROOT)/,$(rel_ld_file))
- the_ld_file_dir = $(dir $(the_ld_file))
- # Rule to preprocess the ld file. The ld file's parent directory is made an order-only
- # prerequisite so it cannot by itself cause this recipe to be invoked.
- $(the_ld_file): $(LD_FILE) | $(the_ld_file_dir)
- @$(call printmessage,cpp,Preprocessing, $(subst $(SDK_ROOT)/,,$<))
- $(at)cd $(dir $<) && $(CC) -E -P $(INCLUDES) $(DEFINES) -o $@ $<
- endif
- # Link the application.
- # Wrap the link objects in start/end group so that ld re-checks each
- # file for dependencies. Otherwise linking static libs can be a pain
- # since order matters.
- $(APP_ELF): $(SUBDIRS) $(app_objs) $(the_ld_file) $(LIBRARIES) $(APP_LIBS)
- @$(call printmessage,link,Linking, $(APP_NAME))
- $(at)$(LD) -Bstatic -nostartfiles -nostdlib $(LDFLAGS) \
- -T $(the_ld_file) \
- $(LDINC) \
- --start-group \
- $(app_objs) \
- $(LIBRARIES) \
- $(APP_LIBS) \
- $(LDADD) \
- --end-group \
- -o $@ \
- -Map $(app_map) --cref
- $(at)$(OBJCOPY) --gap-fill 0x00 -I elf32-little -O binary $@ $(app_bin)
- @echo "Output ELF:" ; echo " $(APP_ELF)"
- @echo "Output binary:" ; echo " $(app_bin)"
- else
- # Empty target to prevent an error. Needed because $(APP_ELF) is a prereq for the 'all' target.
- $(APP_ELF): ;
- endif
- # Include dependency files.
- -include $(OBJECTS_ALL:.o=.d)
|