iBoot/Makefile

293 lines
11 KiB
Makefile
Raw Permalink Normal View History

2023-07-08 13:03:17 -07:00
# Copyright (C) 2007-2014 Apple 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.
###############################################################################
# This is the top-level makefile for everything built out of the iBoot source
# tree.
# Find out what OS we're building on
export BUILD_OS := $(shell uname -s| tr '[:upper:]' '[:lower:]')
$(info %%% building on OS $(BUILD_OS))
# Find the root of the source tree from the build system's perspective.
# could be $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) with a newer make
# Note that buildit sets SRCROOT to the destination for installsrc, so it can be
# empty which breaks the VALID_APPLICATIONS probe.
ORIGINAL_SRCROOT := $(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
export SRCROOT ?= ${ORIGINAL_SRCROOT}
# Applications listed in the APPLICATIONS argument are processed one at a
# time, and the per-application makefile in ./makefiles is invoked.
VALID_APPLICATIONS := $(filter-out .%,$(notdir $(shell find $(ORIGINAL_SRCROOT)/apps -mindepth 1 -maxdepth 1 -type d)))
# Valid applications that should not be built by default
SUPPRESSED_APPLICATIONS :=
# Options that must not be set if building default or multiple APPLICATIONS
SPECIFIC_OPTIONS := TARGETS CONFIGS
# Default SDK platform
ifeq ($(BUILD_OS),darwin)
export SDK_PLATFORM ?= iphoneos.internal
ifeq ($(SDKROOT),)
SDKROOT_PATH := $(shell xcodebuild -version -sdk $(SDK_PLATFORM) Path)
export SDKROOT := $(SDKROOT_PATH)
else
# SDKROOT may be a canonical name (iphoneos.internal). Normalize into a path.
SDKROOT_PATH := $(shell xcodebuild -version -sdk $(SDKROOT) Path)
export SDKROOT := $(SDKROOT_PATH)
export SDK_PLATFORM := $(shell xcodebuild -version -sdk $(SDKROOT) | head -1 | grep -o '(.*)' | tr -d \(\))
endif
export SDK_PRODUCT_NAME := $(shell xcodebuild -version -sdk $(SDKROOT) ProductName)
ifeq ($(SDKVERSION),)
export SDKVERSION := $(shell xcodebuild -version -sdk $(SDK_PLATFORM) SDKVersion | head -1)
endif
ifeq ($(PLATFORMROOT),)
export PLATFORMROOT := $(shell xcodebuild -version -sdk $(SDK_PLATFORM) PlatformPath)
endif
export HOST_PLATFORM ?= macosx
ifeq ($(HOST_SDKROOT),)
export HOST_SDKROOT := $(shell xcodebuild -version -sdk $(HOST_PLATFORM) Path)
endif
endif
export OBJROOT ?= .
export SYMROOT ?= .
export INSTALL_DIR ?= $(DSTROOT)/usr/local/standalone/firmware/
###############################################################################
# No user-serviceable parts below
# Check for spaces in critical paths - we can't handle that
SPACE_CHECK = $(filter ALL,$(and $(findstring $(subst ~, ,~),$(1)),$(error $(2))))
SDK_ADVICE = A path to a component of the SDK contains one or more spaces; this is not supported. Please relocate your SDK to a path without spaces
$(call SPACE_CHECK,$(SDKROOT_PATH),$(SDK_ADVICE) (SDKROOT=$(SDKROOT_PATH)))
$(call SPACE_CHECK,$(PLATFORMROOT),$(SDK_ADVICE) (PLATFORMROOT=$(PLATFORMROOT)))
$(call SPACE_CHECK,$(HOST_SDKROOT),$(SDK_ADVICE) (HOST_SDKROOT=$(HOST_SDKROOT)))
DIR_ADVICE = A path supplied in a variable contains one or more spaces; this is not supported.
$(call SPACE_CHECK,$(DSTROOT),$(DIR_ADVICE) (DSTROOT=$(DSTROOT)))
$(call SPACE_CHECK,$(OBJROOT),$(DIR_ADVICE) (OBJROOT=$(OBJROOT)))
$(call SPACE_CHECK,$(SYMROOT),$(DIR_ADVICE) (SYMROOT=$(SYMROOT)))
$(call SPACE_CHECK,$(SRCROOT),The iBoot sources are in a folder with one or more spaces in the path; this is not supported (SRCROOT=$(SRCROOT)))
# Check for the existence of required directories
DIRECTORY_CHECK = $(filter ALL,$(or $(findstring Directory,$(shell stat -Lf %HT $(1))),$(error $(2))))
DIR_MISSING_ADVICE = A path to a component of the SDK specifies a directory that does not exist
ifeq ($(BUILD_OS),darwin)
$(call DIRECTORY_CHECK,$(SDKROOT_PATH),$(DIR_MISSING_ADVICE) (SDKROOT=$(SDKROOT_PATH)))
$(call DIRECTORY_CHECK,$(PLATFORMROOT),$(DIR_MISSING_ADVICE) (PLATFORMROOT=$(PLATFORMROOT)))
$(call DIRECTORY_CHECK,$(HOST_SDKROOT),$(DIR_MISSING_ADVICE) (HOST_SDKROOT=$(HOST_SDKROOT)))
endif
# Force the tools to emit consistent punctuation in diagnostics
export LC_ALL=C
# Work out what we are building
ifneq ($(APPS),)
# APPS is a shortcut for APPLICATIONS, combine if you're dumb enough to specify both
override APPLICATIONS := $(strip $(APPLICATIONS) $(APPS))
endif
APPLICATIONS ?= $(filter-out $(SUPPRESSED_APPLICATIONS), $(VALID_APPLICATIONS))
MAKE_APPLICATIONS := $(filter $(VALID_APPLICATIONS), $(APPLICATIONS))
ERROR_APPLICATIONS := $(filter-out $(VALID_APPLICATIONS), $(APPLICATIONS))
ifneq ($(ERROR_APPLICATIONS),)
$(error Unrecognized application(s) - $(ERROR_APPLICATIONS))
endif
# Protect against application-specific options if we are building multiple
# applications
ifneq ($(strip $(foreach opt,$(SPECIFIC_OPTIONS),$(value $(opt)))),)
ifneq ($(strip $(shell echo $(MAKE_APPLICATIONS) | wc -w)),1)
$(error must not specify multiple (or default) APPLICATIONS if any of [$(strip $(SPECIFIC_OPTIONS))] is set)
endif
endif
# Export the list of standard actions, and define targets for each per application.
# Application Makefiles will in turn generate targets based on STANDARD_ACTIONS
# so that we can tunnel more or less arbitrary targets into main.mk.
export STANDARD_ACTIONS := build install library_list
APPLICATION_TEMPLATE := $(addprefix %-,$(MAKE_APPLICATIONS))
ACTIONS := $(foreach action,$(STANDARD_ACTIONS),$(addprefix $(action)-,$(MAKE_APPLICATIONS)))
# The 'help' target is special, in that applications are responsible for handling
# it directly.
HELP_APPLICATIONS := $(addprefix help-,$(MAKE_APPLICATIONS))
ACTIONS += $(HELP_APPLICATIONS)
# The 'build' targets are special, in that they depend on the non-standard
# 'libraries' target.
BUILD_APPLICATIONS := $(addprefix build-,$(MAKE_APPLICATIONS))
# Library list
export LIBLIST := $(OBJROOT)/build/library_list
# Global header list
export HDRLIST := $(OBJROOT)/build/header_list
# Where generated host tools are to be found
export TOOLS_BIN := $(OBJROOT)/build/tools
# Pick up or generate the XBS tag
ifeq ($(RC_ProjectSourceVersion),)
export XBS_BUILD_TAG ?= "$(shell echo localbuild...$$(whoami)...$$(git symbolic-ref --short HEAD 2>/dev/null || echo 'detached')_$$(git rev-parse --short HEAD 2>/dev/null)$$([[ $$(expr $$(git status --porcelain 2>/dev/null| egrep -v '^( |\?\?)' | wc -l)) == '0' ]] || echo '_dirty')...$$(date '+%Y/%m/%d-%H:%M:%S'))"
else
export XBS_BUILD_TAG := "iBoot-$(RC_ProjectSourceVersion)"
endif
# Work out whether we are building under XBS or just buildit
ifneq ($(RC_XBS),)
ifeq ($(RC_BUILDIT),)
$(warning building under XBS)
export BUILDING_UNDER_XBS := true
else
export BUILDING_UNDER_BUILDIT := true
$(warning building under BUILDIT)
endif
endif
# Find our tools, now that we know what we're building and in what environment.
include makefiles/tools.mk
# Verbosity for build rules
VERBOSE ?= NO
ifeq ($(VERBOSE),YES)
export _v =
else
export _v = @
endif
# Setup for parallel sub-makes based on 2 times number of logical CPUs
ifndef MAKEJOBS
ifeq ($(BUILD_OS),darwin)
export MAXJOBS := $(shell echo $$((`/usr/sbin//sysctl -n hw.logicalcpu` * 2)) )
else
export MAXJOBS := $(shell echo $$((`nproc` * 2)))
endif
ifeq ($(BUILDING_UNDER_XBS),true)
export MAKEJOBS := --jobs=$(MAXJOBS)
else
export MAKEJOBS := --jobs=$(shell echo $$(( $(MAXJOBS) > 8 ? 8 : $(MAXJOBS))) )
endif
endif
# Help does not look so good if built parallel...
ifeq ($(MAKECMDGOALS),help)
export MAKEJOBS = --jobs=1
endif
# debug filename hashes are needed for both library and application build phases
export DEBUG_FILENAME_HASHES := $(shell ./tools/generate_debug_hashes.py --src .)
################################################################################
# Toplevel rules
#
all: build
ifeq ($(BUILD_OS),darwin)
# By depending on libraries, we get the depended library pass out of the way
# and then application targets can build parallel.
build: build-headers-and-libraries
# Don't depend on build; the target install knows how to do that.
install: build-headers-and-libraries
else
# Linux can only build tests for now
build: tests
endif
# Global headers must be built before the libraries but after we've generated
# the libary list so order them properly with this rule.
build-headers-and-libraries: $(LIBLIST) build-headers build-libraries
build-libraries: $(LIBLIST)
@echo "%%%% building libraries"
@$(MAKE) $(MAKEJOBS) -f makefiles/libraries.mk build MAKEPHASE=libraries SDKROOT=$(SDKROOT_PATH)
$(LIBLIST): library_list
@echo "%%%% making $(LIBLIST)"
@cat /dev/null `find $(OBJROOT)/build -name *.library_list` | sort | uniq > $(LIBLIST)
@$(CHECK_LIBLIST) $(LIBLIST)
build-headers:
@echo "%%%% building global headers"
@cat /dev/null `find $(OBJROOT)/build -name *.header_list` | sort | uniq > $(HDRLIST)
@$(MAKE) $(MAKEJOBS) -f makefiles/headers.mk build MAKEPHASE=headers SDKROOT=$(SDKROOT_PATH)
clean:
$(_v)rm -rf $(OBJROOT)/build
$(_v)rm -rf $(SYMROOT)/build
pre-help:
@echo "%%% printing help"
@echo "Valid APPLICATIONS"
@echo " ${VALID_APPLICATIONS}"
@echo "Default APPLICATIONS"
@echo " ${MAKE_APPLICATIONS}"
@echo ""
help: pre-help $(HELP_APPLICATIONS)
build-tools:
@echo "%%%% generating build tools"
@$(MAKE) -f tools/Makefile build-tools
install-tools:
@echo Generating install tools
@$(MAKE) -f tools/Makefile install-tools
installsrc:
ditto . $(SRCROOT)
installhdrs:
@echo no headers installed
build-tests:
@$(MAKE) $(MAKEJOBS) -f makefiles/tests.mk SDKROOT=$(SDKROOT_PATH) build
.PHONY: tests
tests:
@$(MAKE) $(MAKEJOBS) -f makefiles/tests.mk SDKROOT=$(SDKROOT_PATH) run
cscope.files:
@echo "Building file list for cscope and tags"
@find . -name '*.h' -type f | grep -v ^..build > _cscope.files 2> /dev/null
@find . -name '*.c' -type f | grep -v ^..build >> _cscope.files 2> /dev/null
@find . -name '*.cpp' -type f | grep -v ^..build >> _cscope.files 2> /dev/null
@find . -name '*.S' -type f | grep -v ^..build >> _cscope.files 2> /dev/null
@echo > cscope.files 2> /dev/null
@sort -u < _cscope.files >> cscope.files 2> /dev/null
@rm -f _cscope.files _cscope.files2 2> /dev/null
cscope: cscope.files
@echo "Building cscope database"
@cscope -bvU 2> /dev/null
spotless realclean:
rm -rf build cscope.*
# Linux only knows how to build tests for now, so elide this on Linux
ifeq ($(BUILD_OS),darwin)
# Define this late, so that manual dependencies stated above for
# the standard actions are satisfied before the automatic depdencies.
$(STANDARD_ACTIONS) : % : $(APPLICATION_TEMPLATE)
# Build actions require the build-libraries target, which is otherwise only seen as
# a co-dependency of the build target
$(BUILD_APPLICATIONS): build-libraries
$(ACTIONS): action = $(word 1, $(subst -, ,$@))
$(ACTIONS): application = $(word 2, $(subst -, ,$@))
$(ACTIONS):
@echo "%%%%%% $(action) $(application)"
@$(MAKE) $(MAKEJOBS) -f apps/$(application)/$(application).mk $(action) SDKROOT=$(SDKROOT_PATH) APPLICATION=$(application) MAKEPHASE=$(action)
endif