293 lines
11 KiB
Makefile
293 lines
11 KiB
Makefile
# 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
|