iBoot/makefiles/main.mk

538 lines
17 KiB
Makefile
Raw Normal View History

2023-07-08 13:03:17 -07:00
# 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 <NAME>=<value>. -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