blob: 8d0d3f8526ad91e4ef274d993bbc5d0e3af07cea [file] [log] [blame]
#!/bin/bash
#
# Copyright (c) 2016-2022 The Brenwill Workshop Ltd.
#
# fetchDependencies - Retrieves the correct versions of all dependencies
#
# macOS usage: ./fetchDependencies [--macos] [--ios] [--iossim] [--tvos] [--tvossim] [--all] [--none]
# [-v] [--debug] [--build-spirv-tools]
# [--v-headers-root path] [--spirv-cross-root path] [--glslang-root path]
#
# --macos
# Build the external libraries for the macOS platform.
#
# --ios
# Build the external libraries for the iOS platform.
#
# --iossim
# Build the external libraries for the iOS Simulator platform.
#
# --maccat
# Build the external libraries for the Mac Catalyst platform.
#
# --tvos
# Build the external libraries for the tvOS platform.
#
# --tvossim
# Build the external libraries for the tvOS Simulator platform.
#
# --all
# Equivalent to specifying [--macos --ios --iossim --maccat --tvos --tvossim].
# Results in one XCFramework for each external library, each containing
# binaries for all supported platforms.
#
# --none
# Don't build the external libraries for any platform (this is the default).
#
# Multiple platform options may be specified. At least one platform option must be specified.
#
# --asan
# Build the external libraries against Address Sanitizer, which may be useful when debugging
# and tracing calls into those libraries.
#
# --tsan
# Build the external libraries against Thread Sanitizer, which may be useful when debugging
# and tracing calls into those libraries.
#
# --ubsan
# Build the external libraries against Undefined Behavior Sanitizer, which may be useful when debugging
# and tracing calls into those libraries.
#
# --debug
# Build the external libraries in Debug mode, which may be useful when debugging
# and tracing calls into those libraries.
#
# --parallel-build
# Build the external libraries in parallel using background processes.
#
# --no-parallel-build
# Build the external libraries serially instead of in parallel. This is the default.
#
# --glslang-root path
# "path" specifies a directory path to a KhronosGroup/glslang repository.
# This repository does need to be built and the build directory must be in the
# specified directory. It should be built the same way this script builds it.
#
# --build-spirv-tools
# Build the full spirv-tools distribution. Normally this is not needed, because
# MoltenVK includes a template of pre-generated SPIRV-Tools header files, which
# is all that is needed. Avoiding the spirv-tools build saves significant time
# during the running of this script, and is necessary during CI because Travis CI
# cannot support the required use of Python3 by the spirv-tools build. This flag
# is used by the packagePregenSpirvToolsHeaders script which regenerates the
# spirv-tools header files and repackages the Templates/spirv-tools/build.zip
# file when the spirv-tools library version is upgraded.
#
# --spirv-cross-root path
# "path" specifies a directory path to a KhronosGroup/SPIRV-Cross repository.
# This repository does not have to be built.
#
# -v verbose output
#
# --v-headers-root path
# "path" specifies a directory path to a KhronosGroup/Vulkan-Headers repository.
# This repository does not have to be built.
#
set -e
# ----------------- Functions -------------------
BLD_NONE=""
BLD_IOS=""
BLD_IOS_SIM=""
BLD_MAC_CAT=""
BLD_TVOS=""
BLD_TVOS_SIM=""
BLD_MACOS=""
BLD_SPECIFIED=""
XC_CONFIG="Release"
XC_BUILD_VERBOSITY="-quiet"
XC_USE_BCKGND=""
XC_USE_ASAN="NO"
XC_USE_TSAN="NO"
XC_USE_UBSAN="NO"
V_HEADERS_ROOT=""
SPIRV_CROSS_ROOT=""
GLSLANG_ROOT=""
BLD_SPV_TLS=""
while (( "$#" )); do
case "$1" in
--ios)
BLD_IOS="Y"
shift 1
;;
--iossim)
BLD_IOS_SIM="Y"
shift 1
;;
--maccat)
BLD_MAC_CAT="Y"
shift 1
;;
--tvos)
BLD_TVOS="Y"
shift 1
;;
--tvossim)
BLD_TVOS_SIM="Y"
shift 1
;;
--macos)
BLD_MACOS="Y"
shift 1
;;
--all)
BLD_IOS="Y"
BLD_IOS_SIM="Y"
BLD_MAC_CAT="Y"
BLD_TVOS="Y"
BLD_TVOS_SIM="Y"
BLD_MACOS="Y"
shift 1
;;
--none)
BLD_NONE="Y"
shift 1
;;
--debug)
XC_CONFIG="Debug"
shift 1
;;
--asan)
XC_USE_ASAN="YES"
shift 1
;;
--tsan)
XC_USE_TSAN="YES"
shift 1
;;
--ubsan)
XC_USE_UBSAN="YES"
shift 1
;;
--parallel-build)
XC_USE_BCKGND="Y"
shift 1
;;
--no-parallel-build)
XC_USE_BCKGND=""
shift 1
;;
-v)
XC_BUILD_VERBOSITY=""
shift 1
;;
--build-spirv-tools)
BLD_SPV_TLS="Y"
shift 1
;;
--skip-spirv-tools-build) #deprecated
BLD_SPV_TLS=""
shift 1
;;
--v-headers-root)
V_HEADERS_ROOT=$2
shift 2
;;
--spirv-cross-root)
SPIRV_CROSS_ROOT=$2
shift 2
;;
--glslang-root)
GLSLANG_ROOT=$2
shift 2
;;
-*|--*=)
echo "Error: Unsupported option $1" >&2
exit 1
;;
esac
done
# Update a repository. If it exists, fetch it; if not, clone it.
# $1 repo name
# $2 repo url
# $3 repo revision (commit SHA)
function update_repo() {
echo "$1 repo: $2"
echo "$1 revision: $3"
if [ -d $1 -a -d $1/.git ]; then
cd $1
git fetch --all
git checkout --force $3
cd - > /dev/null
else
rm -rf $1
git clone $2 $1
cd $1
git checkout $3
cd - > /dev/null
fi
}
# Build a repository
# $1 repo name
function build_repo() {
echo "Building $1"
mkdir -p $1/build
cd $1/build
if type ninja >/dev/null 2>&1 ; then
cmake -G Ninja -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install ..
ninja
else
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install ..
make -j $(sysctl -n hw.activecpu)
fi
cd - > /dev/null
}
# ----------------- Main -------------------
EXT_DIR=External
EXT_REV_DIR=../ExternalRevisions
echo
echo ========== Retrieving MoltenVK dependencies into ${EXT_DIR} ==========
mkdir -p ${EXT_DIR}
cd ${EXT_DIR}
# ----------------- Cereal -------------------
echo
echo ========== Cereal ==========
echo
REPO_NAME=cereal
REPO_URL="https://github.com/USCiLab/${REPO_NAME}.git"
REPO_REV=$(cat "${EXT_REV_DIR}/${REPO_NAME}_repo_revision")
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
# ----------------- Vulkan-Headers -------------------
echo
echo ========== Vulkan-Headers ==========
echo
# When MoltenVK is built by something that already has
# a copy of this repo, use it by creating a symlink.
REPO_NAME=Vulkan-Headers
if [ ! "$V_HEADERS_ROOT" = "" ]; then
rm -rf ${REPO_NAME}
ln -sfn ${V_HEADERS_ROOT} ${REPO_NAME}
else
REPO_URL="https://github.com/KhronosGroup/${REPO_NAME}.git"
REPO_REV=$(cat "${EXT_REV_DIR}/${REPO_NAME}_repo_revision")
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
fi
# ----------------- SPIRV-Cross -------------------
echo
echo ========== SPIRV-Cross ==========
echo
# When MoltenVK is built by something that already has
# a copy of this repo, use it by creating a symlink.
REPO_NAME=SPIRV-Cross
if [ ! "$SPIRV_CROSS_ROOT" = "" ]; then
rm -rf ${REPO_NAME}
ln -sfn ${SPIRV_CROSS_ROOT} ${REPO_NAME}
else
REPO_URL="https://github.com/KhronosGroup/${REPO_NAME}.git"
REPO_REV=$(cat "${EXT_REV_DIR}/${REPO_NAME}_repo_revision")
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
fi
# ----------------- glslang -------------------
echo
echo ========== glslang and SPIRV-Tools ==========
echo
# When MoltenVK is built by something that already has
# a copy of this repo, use it by creating a symlink.
REPO_NAME=glslang
if [ ! "$GLSLANG_ROOT" = "" ]; then
rm -rf ${REPO_NAME}
ln -sfn ${GLSLANG_ROOT} ${REPO_NAME}
else
REPO_URL="https://github.com/KhronosGroup/${REPO_NAME}.git"
REPO_REV=$(cat "${EXT_REV_DIR}/${REPO_NAME}_repo_revision")
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
cd ${REPO_NAME}
./update_glslang_sources.py
rm -rf build
./build_info.py . \
-i build_info.h.tmpl \
-o build/include/glslang/build_info.h
cd - > /dev/null
fi
# Build the embedded spirv-tools, or use option of pre-generated headers
SPV_TLS_DIR="${REPO_NAME}/External/spirv-tools"
if [ "$BLD_SPV_TLS" = "Y" ]; then
build_repo "${SPV_TLS_DIR}"
else
unzip -o -q -d "${SPV_TLS_DIR}" ../Templates/spirv-tools/build.zip
rm -rf "${SPV_TLS_DIR}/__MACOSX"
fi
# ----------------- Vulkan-Tools -------------------
echo
echo ========== Vulkan-Tools ==========
echo
REPO_NAME=Vulkan-Tools
REPO_URL="https://github.com/KhronosGroup/${REPO_NAME}.git"
REPO_REV=$(cat "${EXT_REV_DIR}/${REPO_NAME}_repo_revision")
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
# ----------------- Cleanup -------------------
cd ..
# -------------- Build MoltenVK external library dependencies -----------------
echo
echo ========== Started building dependency libraries at `date +"%r"` ==========
echo Please be patient on first build
function execute_xcodebuild_command () {
if [ -n "${XCPRETTY}" ]; then
set -o pipefail && xcodebuild "$@" | tee -a "dependenciesbuild.log" | ${XCPRETTY}
else
xcodebuild "$@"
fi
}
# Build an Xcode scheme for an OS and platform
# 1 - OS
# 2 - Platform
# 3 - Destination (Optional. Defaults to same as platform)
function build_impl() {
BLD_SPECIFIED="Y"
XC_OS=${1}
XC_PLTFM=${2}
if [ "${3}" != "" ]; then
XC_DEST=${3};
else
XC_DEST=${XC_PLTFM};
fi
XC_SCHEME="${EXT_DEPS}-${XC_OS}"
XC_LCL_DD_PATH="${XC_DD_PATH}/Intermediates/${XC_PLTFM}"
echo Building external libraries for platform ${XC_PLTFM} and destination ${XC_DEST}
execute_xcodebuild_command \
-project "${XC_PROJ}" \
-scheme "${XC_SCHEME}" \
-destination "generic/platform=${XC_DEST}" \
-configuration "${XC_CONFIG}" \
-enableAddressSanitizer "${XC_USE_ASAN}" \
-enableThreadSanitizer "${XC_USE_TSAN}" \
-enableUndefinedBehaviorSanitizer "${XC_USE_UBSAN}" \
-derivedDataPath "${XC_LCL_DD_PATH}" \
${XC_BUILD_VERBOSITY} \
build
echo Completed building external libraries for ${XC_PLTFM}
}
# Select whether or not to run the build in parallel.
# 1 - OS
# 2 - platform
function build() {
if [ "$XC_USE_BCKGND" != "" ]; then
build_impl "${1}" "${2}" "${3}" &
else
build_impl "${1}" "${2}" "${3}"
fi
}
EXT_DEPS=ExternalDependencies
XC_PROJ="${EXT_DEPS}.xcodeproj"
XC_DD_PATH="${EXT_DIR}/build"
# Determine if xcpretty is present
XCPRETTY_PATH=$(command -v xcpretty 2> /dev/null || true) # ignore failures
# If xcpretty is present, use it to format xcodebuild output
XCPRETTY=""
if [ -n "$XCPRETTY_PATH" ]; then
XCPRETTY="xcpretty -c"
fi
if [ "$XC_USE_BCKGND" != "" ]; then
# For now, avoid using xcpretty if parallel background tasks are being used
XCPRETTY=""
fi
# Structure build tasks by platform so they can be built in parallel per platform.
# Content for each platform must be built in series to avoid
if [ "$XC_USE_BCKGND" != "" ]; then
trap "exit" INT TERM ERR
trap "kill 0" EXIT
fi
if [ "$BLD_MACOS" != "" ]; then
build "macOS" "macOS"
fi
if [ "$BLD_IOS" != "" ]; then
build "iOS" "iOS"
fi
if [ "$BLD_IOS_SIM" != "" ]; then
build "iOS" "iOS Simulator"
fi
if [ "$BLD_MAC_CAT" != "" ]; then
build "iOS" "Mac Catalyst" "macOS,variant=Mac Catalyst"
fi
if [ "$BLD_TVOS" != "" ]; then
build "tvOS" "tvOS"
fi
if [ "$BLD_TVOS_SIM" != "" ]; then
build "tvOS" "tvOS Simulator"
fi
# Wait for any background process (if selected) to finish
if [ "$XC_USE_BCKGND" != "" ]; then
wait
fi
if [ "$BLD_SPECIFIED" != "" ]; then
# Build XCFrameworks, update latest symlink, and clean MoltenVK for rebuild
PROJECT_DIR="."
CONFIGURATION=${XC_CONFIG}
. "./Scripts/create_ext_lib_xcframeworks.sh"
. "./Scripts/package_ext_libs_finish.sh"
else
if [ "$BLD_NONE" != "" ]; then
echo Not building any platforms
else
echo "WARNING: You did not specify a platform to build."
echo "To build the external libraries, include one or"
echo "more of the following platform options:"
echo " --macos --ios --iossim --maccat --tvos --tvossim --all"
echo "See the instructions in the fetchDependencies script for more info."
fi
fi
echo ========== Finished at `date +"%r"` ==========
exit 0