# Copyright (C) 2007-2014 Apple Inc. All rights reserved. # Copyright (C) 2006 Apple Computer, Inc. All rights reserved. # # This document is the property of Apple Inc. # It is considered confidential and proprietary. # # This document may not be reproduced or transmitted in any form, # in whole or in part, without the express written permission of # Apple Inc. # ############################################################################### # Makefile to build/install a specific executable from the iBoot source tree # # The following must be set by the caller: # # CONFIG # PRODUCT # BUILD # XBS_BUILD_TAG # OBJROOT # SYMROOT # # The following may be set by the caller: # # APPLICATION_OPTIONS # List of options from application to be added to OPTIONS # # IMAGE_TYPE # Installation will generate an image component of the # specified type. # # IMAGE_FORMAT # Installation will generate images of the format(s) listed. # Valid formats are 2 and 3 (Image2, Image3 respectively). # # DFU_IMAGE # The generated image will also be installed into the DFU # install location. # # ROM_IMAGE # Installation will generate a raw binary. # # INTEL_HEX # Installation will generate an Intel Hex format version # of the binary. ROM_IMAGE_SIZE must be set to a value # of the form XXk where XX is your average power of 2 # and larger than the binary image (this causes the # image to be padded correspondingly). # # Environment: # TOOLCHAIN_PREFIX # Locate tools somewhere other than on the path. # # XXX need something to cause the mach-o to be installed include makefiles/macros.mk include makefiles/config.mk #$(warning Building $(SUB_TARGET)-$(PRODUCT) $(CONFIG) $(BUILD) config) # Directories BUILDDIR := $(OBJROOT)/build/$(SUB_TARGET)$(CONFIG)-$(PRODUCT)-$(BUILD) HDRDIR := $(OBJROOT)/build/include SYMDIR := $(SYMROOT)/build/$(SUB_TARGET)$(CONFIG)-$(PRODUCT)-$(BUILD) APPDIR := apps/$(APPLICATION) LIBDIR := /BAD # Built products PRODUCT_BUILD := $(call TOSYMDIR,$(PRODUCT)) PRODUCT_MACHO := $(PRODUCT_BUILD).sys PRODUCT_DSYM := $(PRODUCT_MACHO).dSYM PRODUCT_BIN := $(PRODUCT_BUILD).bin PRODUCT_LIBLIST := $(call TOBUILDDIR,$(PRODUCT)).library_list PRODUCT_HDRLIST := $(call TOBUILDDIR,$(PRODUCT)).header_list # Local tools BHC := $(call TOTOOLSDIR,bhc) MACHO2BIN := $(call TOTOOLSDIR,Macho2Bin) # All sources depend on these GLOBAL_SRCDEPS := PRODUCT_SRCDEPS := # Global headers live here: GLOBAL_INCLUDES += $(HDRDIR) # Product-related compilation flags PRODUCT_ALLFLAGS := # Object files to build, added to by included rules.mk files. ALL_OBJS := # Deps for object files, computed locally (except for libraries, XXX probably a bug) ALL_DEPS := # Static libraries we build locally. LOCALLIBS := # Static libraries built for us by libraries.mk. COMMONLIBS := # Static libraries someone else already built. PREBUILT_STATICLIBS := # Static libraries imported externally. EXTERNAL_STATICLIBS := # All static libraries. ALL_STATICLIBS := # Additional dependencies for the product. EXTRA_PRODUCTDEPS := # Dependencies for cleaning CLEAN := # Source modules list, added to by included rules.mk files. MODULES := # Module opt-out list, added to by included rules.mk files. MODULES_ELIDE := # Common library module dependency list, added to by included rules.mk files. LIBRARY_MODULES := # Options to be passed to all compiled sources in the form =. -D will be added # automatically. OPTIONS := # Tag that identifies libraries used/generated by this build # This is appended by other rules to uniquely identify library builds. LIBRARY_TAG := # Options passed to the library build LIBRARY_OPTIONS := BUILD=$(BUILD) # Compiler options for the library build LIBRARY_ALLFLAGS := # Default is no synch AES AES_SYNCH_FIXUP := false # Expose what we are building to the compiler # APPLICATION_$(APPLICATION) # PRODUCT_$(PRODUCT) # SUB_TARGET_$(SUB_TARGET) # SUB_TARGET_$(SUB_TARGET)_CONFIG_$(CONFIG) # CONFIG_$(CONFIG) APPLICATION_UPPER := $(call UPCASE, $(APPLICATION)) PRODUCT_UPPER := $(call UPCASE, $(PRODUCT)) SUB_TARGET_UPPER := $(call UPCASE, $(SUB_TARGET)) CONFIG_UPPER := $(call UPCASE, $(CONFIG)) OPTIONS += APPLICATION_$(APPLICATION_UPPER)=1 # 8208311 OPTIONS += $(APPLICATION_OPTIONS) OPTIONS += PRODUCT_$(PRODUCT_UPPER)=1 OPTIONS += SUB_TARGET_$(SUB_TARGET_UPPER)=1 OPTIONS += SUB_TARGET_STRING=\"$(SUB_TARGET)\" OPTIONS += SUB_TARGET_UPPER_STRING=\"$(SUB_TARGET_UPPER)\" ifneq ($(CONFIG),) OPTIONS += SUB_TARGET_$(SUB_TARGET_UPPER)_CONFIG_$(CONFIG_UPPER)=1 OPTIONS += CONFIG_$(CONFIG_UPPER)=1 endif OPTIONS += $(BUILD)_BUILD=1 ifneq ($(CRYPTO_HASH),sha1) CRYPTO_HASH_UPPER := $(call UPCASE, $(subst -,_,$(CRYPTO_HASH))) OPTIONS += WITH_$(CRYPTO_HASH_UPPER)=1 endif # Also define RELEASE_BUILD for the ROMRELEASE build flavor so that everything # uses BUILD_RELEASE doesn't have to be touched to use ROMRELEASE also. ifeq ($(BUILD),ROMRELEASE) OPTIONS += RELEASE_BUILD=1 endif # export hacks as options OPTIONS += $(addprefix HACK_,$(HACKS)) # Identifying strings OPTIONS += BUILD_STYLE=\"$(BUILD)\" OPTIONS += CONFIG_PROGNAME_STRING=\"$(PRODUCT)\" OPTIONS += CONFIG_BOARD_STRING=\"$(SUB_TARGET)$(CONFIG)\" # can't OPTIONS this as it changes for every non-XBS build GLOBAL_CFLAGS += -DXBS_BUILD_TAG=\"$(XBS_BUILD_TAG)\" GLOBAL_ASFLAGS += -DXBS_BUILD_TAG=\"$(XBS_BUILD_TAG)\" # deal with the options.h file which is dynamically built from the OPTIONS make variable OPTIONS_HEADER_FILE := $(call TOSYMDIR,options.h) OPTIONS_HEADER_FILE_TEMP := $(call TOSYMDIR,options.h.temp) PRODUCT_ALLFLAGS += -include $(OPTIONS_HEADER_FILE) PRODUCT_SRCDEPS += $(OPTIONS_HEADER_FILE) # Read the application makefile, which may add modules include $(APPDIR)/application.mk # Application may adjust TARGET TARGET := $(SUB_TARGET) # Read the target configuration, which may add modules # Allow the config file path to be overridden to support # configs outside of the application's regular location. CONFIG_FILE ?= $(APPDIR)/config/$(SUB_TARGET)-config.mk include $(CONFIG_FILE) # The target configuration may elect to abort the build of this product ifeq ($(ABORT),true) $(warning Build of $(SUB_TARGET)-$(PRODUCT) $(CONFIG) $(BUILD) aborted by configuration) build: install: clean: library_list: else # Ensure TARGET exists TARGET_UPPER := $(call UPCASE, $(TARGET)) OPTIONS += TARGET_$(TARGET_UPPER)=1 ifneq ($(CONFIG),) OPTIONS += TARGET_$(TARGET_UPPER)_CONFIG_$(CONFIG_UPPER)=1 endif # Ensure SUB_PLATFORM exists SUB_PLATFORM ?= $(PLATFORM) SUB_PLATFORM_UPPER := $(call UPCASE, $(SUB_PLATFORM)) OPTIONS += SUB_PLATFORM_$(SUB_PLATFORM_UPPER)=1 # Create PLATFORM_NAME_STRING, PLATFORM_NAME_UNQUOTED OPTIONS += PLATFORM_NAME_STRING=\"$(SUB_PLATFORM)\" OPTIONS += PLATFORM_NAME_UNQUOTED=$(SUB_PLATFORM) # Read module configurations MODULES_ALREADY_INCLUDED:= MODULES_VAR := MODULES MODULE_MAKEFILE := rules.mk include makefiles/main-nested-module.mk # Now that we have processed modules, we know where common library objects will be located. LIBRARY_UNIQUE := $(subst ${empty} ${empty},-,$(sort ${LIBRARY_TAG})) LIBDIR := $(OBJROOT)/build/lib-$(LIBRARY_UNIQUE)-$(BUILD) # Do library modules MODULES_ALREADY_INCLUDED:= MODULES_VAR := LIBRARY_MODULES MODULE_MAKEFILE := library.mk include makefiles/main-nested-module.mk LIBRARY_MODULE_LIST := $(sort $(MODULES_ALREADY_INCLUDED)) # Compute the static library set based on the build target list. # We have two sets of static libraries; common libraries are built by libraries.mk, # whilst local libraries are built here. # Note local libraries before common libraries to permit local->common depdendencies. # (We could list both sets twice...) COMMONLIB_TARGETVARS := $(addsuffix _BUILD,$(COMMONLIBS)) COMMONLIB_LIBS := $(foreach i,$(COMMONLIB_TARGETVARS),$(value $i)) LOCALLIB_TARGETVARS := $(addsuffix _BUILD,$(LOCALLIBS)) LOCALLIB_LIBS := $(foreach i,$(LOCALLIB_TARGETVARS),$(value $i)) ALL_STATICLIBS += $(LOCALLIB_LIBS) $(COMMONLIB_LIBS) $(EXTERNAL_STATICLIBS) # At the very least, installing requires the product be built INSTALL_PREREQS = $(PRODUCT) # If an image type is specified, enable the image format targets ifneq ($(IMAGE_TYPE),) ifeq ($(IMAGE_FORMAT),img3) INSTALL_PREREQS += install-image3 else INSTALL_PREREQS += install-image4 endif endif # If a DFU image is being handled, enable the image format targets # In Image4, this collides with the DSTROOT products of EmbeddedFirmware # due to not having a unique extension. It is already installed under # /image4, which EmbeddedFirmware searches, so we can skip this duplicate. ifeq ($(DFU_IMAGE),true) ifeq ($(IMAGE_FORMAT),img3) INSTALL_PREREQS += install-dfuimage3 endif endif # If we are generating a plain binary, enable the target ifeq ($(BINARY_IMAGE),true) INSTALL_PREREQS += install-binary-image endif # If a Secure ROM image is being handled, enable the target ifeq ($(ROM_IMAGE),true) INSTALL_PREREQS += install-romimage endif # Intel Hex output, requires ROM_IMAGE_SIZE be set to pad the image ifeq ($(INTEL_HEX),true) INSTALL_PREREQS += install-intelhex endif # If a header file is being generated, enable the target ifneq ($(IMAGE_WITH_HEADER),) INSTALL_PREREQS += install-headerfile endif # If additional headers should be installed, enable the target that installs them ifneq ($(INSTALL_HEADERS),) INSTALL_PREREQS += install-additional-headers endif # Default to no optional arguments to image3maker IMAGE3_OPTARGS := # If AES synch support is enabled, we need the header to be found. # This isn't generally safe as there are headers we own that get installed # there and we end up using a stale version. ifneq ($(AES_SYNCH_FIXUP),false) GLOBAL_INCLUDES += /usr/local/standalone/firmware endif build: $(PRODUCT) library_list: $(PRODUCT_HDRLIST) $(PRODUCT_LIBLIST) $(PRODUCT): $(PRODUCT_BIN) $(PRODUCT_BUILD).size install: $(INSTALL_PREREQS) install-image3: PRODUCT_IMG = $(PRODUCT_BUILD).img3 install-image3: $(PRODUCT) @echo installing Image3 object \'$(IMAGE_TYPE)\' from $(PRODUCT_BIN) $(_v)$(IMAGE3MAKER) \ --create \ --data $(PRODUCT_BIN) \ --version $(XBS_BUILD_TAG) \ --type $(IMAGE_TYPE) \ --imagefile $(PRODUCT_IMG) \ $(IMAGE3_OPTARGS) @mkdir -p $(INSTALL_DIR)/image3 @install -C -m 644 $(PRODUCT_IMG) $(INSTALL_DIR)image3/$(INSTALL_NAME).img3 install-dfuimage3: PRODUCT_IMG = $(PRODUCT_BUILD).img3 install-dfuimage3: $(PRODUCT) install-image3 @echo installing DFU object $(PRODUCT_IMG) as $(INSTALL_NAME).img3 ifneq ($(MAX_DFU_SIZE),) @if test "$(PRODUCT)" = "iBSS"; then \ tools/check_product_size $(PRODUCT_IMG) $(MAX_DFU_SIZE) "MAX_DFU_SIZE" ; \ fi endif @mkdir -p $(INSTALL_DIR)/dfu @install -C -m 644 $(PRODUCT_IMG) $(INSTALL_DIR)dfu/$(INSTALL_NAME).img3 install-image4: PRODUCT_IMG = $(PRODUCT_BUILD).im4p install-image4: $(PRODUCT) @echo installing Image4 object \'$(IMAGE_TYPE)\' from $(PRODUCT_BIN) $(_v)$(IMG4PAYLOAD) \ -i $(PRODUCT_BIN) \ -v $(XBS_BUILD_TAG) \ -t $(IMAGE_TYPE) \ -o $(PRODUCT_IMG) ifneq ($(MAX_DFU_SIZE),) @if test "$(PRODUCT)" = "iBSS" -o "$(PRODUCT)" = "LLB"; then \ tools/check_product_size $(PRODUCT_IMG) $(MAX_DFU_SIZE) "MAX_DFU_SIZE"; \ fi endif @mkdir -p $(INSTALL_DIR)/image4 @install -C -m 644 $(PRODUCT_IMG) $(INSTALL_DIR)image4/$(INSTALL_NAME).im4p install-binary-image: $(PRODUCT) @echo installing binary object $(PRODUCT_BIN) as $(INSTALL_NAME).bin @mkdir -p $(INSTALL_DIR) @install -C -m 644 $(PRODUCT_BIN) $(INSTALL_DIR)/$(INSTALL_NAME).bin install-romimage: $(PRODUCT) @echo installing binary object $(PRODUCT_BIN) as $(INSTALL_NAME).bin @mkdir -p $(INSTALL_DIR)/SecureROM @install -C -m 644 $(PRODUCT_BIN) $(INSTALL_DIR)SecureROM/$(INSTALL_NAME).bin install-intelhex: $(PRODUCT) @echo installing IntelHex file $(INSTALL_DIR)SecureROM/$(INSTALL_NAME).hex @$(BHC) -h $(PRODUCT_BIN) $(INSTALL_DIR)SecureROM/$(INSTALL_NAME).hex \ $(ROM_IMAGE_SIZE) 2>&1 > /dev/null install-headerfile: PRODUCT_HEADER = $(PRODUCT_BUILD).h install-headerfile: $(PRODUCT) @echo installing binary object $(PRODUCT_BIN) in headerfile $(INSTALL_NAME) using $(IMAGE_WITH_HEADER) @mkdir -p $(INSTALL_DIR) @NM=$(NM) \ OBJFILE=$(PRODUCT_MACHO) \ BINFILE=$(PRODUCT_BIN) \ XBS_BUILD_TAG=$(XBS_BUILD_TAG) \ $(AWK) -f $(SRCROOT)/makefiles/format-headerfile.awk < $(IMAGE_WITH_HEADER) > $(PRODUCT_HEADER) @install -C -m 644 $(PRODUCT_HEADER) $(INSTALL_DIR)$(INSTALL_NAME) # Note that we can't use install -C here as it can race with another # install's unlink of the destination due to the same header(s) being # installed by more than one invocation simultaneously. Ssen notes # in rdar://8317733 that -S doesn't fix this. install-additional-headers: $(INSTALL_HEADERS) @echo installing additional headers: $(INSTALL_HEADERS) @mkdir -p $(INSTALL_DIR) @test -w $(INSTALL_DIR) || (echo "ERROR: I just created $(INSTALL_DIR) but now I cannot write files to it." && exit 1) @install -m 644 $(INSTALL_HEADERS) $(INSTALL_DIR) # someone can request additional system dependencies $(PRODUCT): $(EXTRA_PRODUCTDEPS) # Produce the prelinked binary image. # # Configuration may supply the following options: # # BIN_IMAGE_PREFIX # A binary image to be prepended to the image. # # BIN_INCLUDES_BSS # The image is padded to include the initialised BSS. # # BIN_ROUND_UP # The output image is padded to a multiple of the supplied value. # # BIN_FIXUP # The output image is passed to this command once fully assembled. # BIN_ROUND_UP ?= 1 ifneq ($(BIN_ROUND_UP),1) ifeq ($(BIN_INCLUDES_BSS),true) $(error Cannot specify both BIN_ROUND_UP and BIN_INCLUDES_BSS) endif endif $(PRODUCT_BIN): $(PRODUCT_BUILD).stripped $(PRODUCT_DSYM) $(BIN_IMAGE_PREFIX) @$(SIZE) $< @echo BIN $@ ifneq ($(BIN_IMAGE_PREFIX),) $(_v)dd if=$(BIN_IMAGE_PREFIX) of=$@ else $(_v)dd if=/dev/zero of=$@ count=0 endif $(_v)dd if=$< ibs=1 skip=$(shell $(OTOOL) -lv $< | grep -m1 '^ fileoff ' | cut -c 11-) \ obs=$(BIN_ROUND_UP) conv=osync >> $@ ifeq ($(BIN_INCLUDES_BSS),true) @echo PAD $@ $(_v)dd if=/dev/zero \ of=$@ \ bs=1 \ seek=`stat -f %z $@` \ count=`expr \`$(SIZE) $< | tail -1 | cut -f 5\` - \`stat -f %z $@\`` endif ifneq ($(BIN_FIXUP),) $(_v)$(BIN_FIXUP) $@ endif ifneq ($(AES_SYNCH_FIXUP),false) $(AES_SYNCH_FIXUP) $(PRODUCT_BUILD) endif $(PRODUCT_DSYM): $(PRODUCT_MACHO) tools/lldb_init_iboot.py tools/lldb_os_iboot.py @echo dSYM $@ $(_v)$(DSYMUTIL) --out=$@ $< @mkdir -p $(PRODUCT_DSYM)/Contents/Resources/Python/ @install -C -m 644 tools/lldb_init_iboot.py $(PRODUCT_DSYM)/Contents/Resources/Python/$(notdir $(PRODUCT_BUILD))-disabled.py @install -C -m 644 tools/lldb_os_iboot.py $(PRODUCT_DSYM)/Contents/Resources/Python/lldb_os_iboot.py $(PRODUCT_BUILD).stripped: $(PRODUCT_MACHO) @echo STRIP $@ $(_v)$(STRIP) -o $@ $< $(PRODUCT_BUILD).size: $(PRODUCT_MACHO) @echo SIZE $@ $(_v)$(SIZE) $(ALL_OBJS) > $@ $(PRODUCT_HDRLIST): $(MAKEFILE_LIST) $(_v)$(MKDIR) $(_v)rm -f $(PRODUCT_HDRLIST) $(_v)touch $(PRODUCT_HDRLIST) $(_v)for i in $(GLOBAL_HEADERS) ; do \ echo "$(HDRDIR)@$$i" >> $(PRODUCT_HDRLIST) ; \ done ENCODED_LIBRARY_OPTIONS := $(subst $(empty) ,~,$(addprefix -D,$(strip $(LIBRARY_OPTIONS)))) ENCODED_LIBRARY_FLAGS := $(subst $(empty) ,~,$(strip $(GLOBAL_ALLFLAGS) $(LIBRARY_ALLFLAGS))) $(PRODUCT_LIBLIST): $(MAKEFILE_LIST) $(_v)$(MKDIR) $(_v)rm -f $(PRODUCT_LIBLIST) $(_v)touch $(PRODUCT_LIBLIST) $(_v)for i in $(LIBRARY_MODULE_LIST) ; do \ echo "$$i~$(LIBRARY_UNIQUE)-$(BUILD)~$(ENCODED_LIBRARY_OPTIONS)~$(ENCODED_LIBRARY_FLAGS)" \ >> $(PRODUCT_LIBLIST) ; \ done $(_v)$(CHECK_LIBLIST) $(PRODUCT_LIBLIST) # XXX build static libraries the 'libraries' pass didn't get # XXX need to differentiate these... $(LOCALLIB_LIBS): objs = $(value $(addsuffix _OBJS,$(basename $(notdir $@)))) $(LOCALLIB_LIBS): @$(MKDIR) @echo AR $@ $(_v)$(AR) -crS $@ $(objs) $(_v)$(RANLIB) $@ # build the options.h file from the OPTIONS variable $(OPTIONS_HEADER_FILE): $(MAKEFILE_LIST) @$(MKDIR) @rm -f $(OPTIONS_HEADER_FILE_TEMP); \ (for o in $(OPTIONS); do \ echo "#define $$o"; \ done) | sort | sed s/=/\ / >> $(OPTIONS_HEADER_FILE_TEMP); \ if [ -f "$(OPTIONS_HEADER_FILE)" ]; then \ if cmp "$(OPTIONS_HEADER_FILE_TEMP)" "$(OPTIONS_HEADER_FILE)"; then \ rm -f $(OPTIONS_HEADER_FILE_TEMP) ; \ else \ echo UPD $@ ; \ mv $(OPTIONS_HEADER_FILE_TEMP) $(OPTIONS_HEADER_FILE) ; \ fi \ else \ echo GEN $@ ; \ mv $(OPTIONS_HEADER_FILE_TEMP) $(OPTIONS_HEADER_FILE) ; \ fi \ # Now we can define object build rules include makefiles/build.mk clean: $(_v)rm -rf $(BUILDDIR) # Defining CLEAN_INCLUDE_TEST turns on this snippet which will cause an # error on 'make clean' if any directory mentioned in GLOBAL_INCLUDES does not exist ifneq ($(CLEAN_INCLUDE_TEST),) clean-include-test: $(filter-out $(BUILDDIR)/include,$(patsubst -I%,%,$(GLOBAL_INCLUDES))) clean: clean-include-test endif # Empty rule for .d files %.d: %.Td: ifeq ($(filter $(MAKECMDGOALS), clean), ) -include $(ALL_DEPS) endif # !ABORT endif