| #!/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 |