blob: 990568402aefd253264c8a378ae9a06820d889a9 [file] [log] [blame]
#!/bin/sh
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# A script used to rebuild Vulkan host Linux prebuilts with the Fuchsia toolchain.
set -e
export LANG=C
export LC_ALL=C
readonly SCRIPT_NAME="$(basename $0)"
readonly SCRIPT_DIR="$(dirname $0)"
# Print an error message to stderr then exit the script immediately.
die () {
echo 2>&1 "$*"
exit 1
}
# Return true if $1 is an absolute file path
is_absolute_path () {
[[ "${1#/}" != "$1" ]]
}
# Get absolute directory path
# $1: directory path, must exist!
# Out: absolute path of $1
absolute_path () {
(cd "$1" && pwd)
}
# Set this variable to ensure that the corresponding directory
# is always removed when this script exits, even in case of error!
REMOVE_TMPDIR_ON_EXIT=
# Internal trap function used to ensure proper cleanups on script exit.
_on_exit () {
if [[ -n "$REMOVE_TMPDIR_ON_EXIT" ]]; then
rm -rf "$REMOVE_TMPDIR_ON_EXIT"
fi
return 0
}
trap _on_exit EXIT QUIT HUP
# Sanity checks
#
# Note that this script only works on Linux (i.e not OS X) because
# building the Vulkan-Loader requires running a host Linux executable generated
# during the build.
#
# It might be possible to support building on OS X by first performing a
# host build of the Vulkan-Loader only, followed by a cross-build to Linux
# with adequate PATH manipulation, but this use case is not important enough
# for now to support.
if [[ "$(uname)" != "Linux" ]]; then
die "ERROR: This script only works on a Linux build machine!"
fi
readonly DEFAULT_BUILD_CONFIG_FILE="${SCRIPT_DIR}/build_config"
DO_HELP=
DO_HELP_USAGE=
TOP_BUILD_DIR=
INSTALL_DIR=
DEST_INSTALL_DIR=
TOOLCHAIN_FILE=
BUILD_CONFIG_FILE=
NO_CCACHE=
NO_CLEAN_BUILD=
GENERATOR=
GIT_MIRRORS=()
git_mirror_src_prefix () {
printf %s "$1" | cut -d, -f1
}
git_mirror_dst_prefix () {
printf %s "$1" | cut -d, -f2
}
# Add a --git-mirror to the global list, while sanity checking the value.
add_git_mirror () {
local SRC_PREFIX="$(git_mirror_src_prefix "$1")"
local DST_PREFIX="$(git_mirror_dst_prefix "$1")"
if [[ -z "${DST_PREFIX}" ]]; then
die "--git-mirror value should use colon as delimiter: $1"
fi
if [[ -z "${SRC_PREFIX}" ]]; then
die "--git-mirror value is invalid!"
fi
GIT_MIRRORS+=($1)
}
# Rewrite URL if needed through global list of git mirrors.
# $1: input URL
# out: output URL
rewrite_git_url () {
local URL="$1"
local MIRROR SRC_PREFIX DST_PREFIX
for MIRROR in "${GIT_MIRRORS[@]}"; do
SRC_PREFIX="$(git_mirror_src_prefix "${MIRROR}")"
DST_PREFIX="$(git_mirror_dst_prefix "${MIRROR}")"
if [[ "${URL}" == "${SRC_PREFIX}"* ]]; then
# echo >&2 "XXX ${URL} -> ${DST_PREFIX} | ${SRC_PREFIX}"
URL="${DST_PREFIX}${URL##${SRC_PREFIX}}"
break
fi
done
printf %s "${URL}"
}
# The following variables are taken from the environment, or can be overriden
# with --<name>=<value> options below.
GIT="${GIT:-git}"
GIT_OPTS="${GIT_OPTS:-}"
CMAKE="${CMAKE:-cmake}"
CMAKE_OPTS="${CMAKE_OPTS:-}"
MAKE="${MAKE:-make}"
NINJA="${NINJA:-ninja}"
ENABLE_DEBUGGER_SUPPORT=
for OPT; do
case "${OPT}" in
--help|-?)
DO_HELP=true
;;
--help-usage)
DO_HELP_USAGE=usage
;;
--build-dir=*)
TOP_BUILD_DIR="${OPT##--build-dir=}"
;;
--install-dir=*)
INSTALL_DIR="${OPT##--install-dir=}"
;;
--dest-install-dir=*)
DEST_INSTALL_DIR="${OPT##--dest-install-dir=}"
;;
--cmake-toolchain-file=*)
TOOLCHAIN_FILE="${OPT##--cmake-toolchain-file=}"
;;
--build-config-file=*)
BUILD_CONFIG_FILE="${OPT##--build-config-file=}"
;;
--no-ccache)
NO_CCACHE=true
;;
--no-clean-build)
NO_CLEAN_BUILD=true
;;
--generator=*)
GENERATOR="${OPT##--generator=}"
;;
--git=*)
GIT="${OPT##--git=}"
;;
--git-opt=*)
GIT_OPTS="${OPT##--git-opt=}"
;;
--cmake=*)
CMAKE="${OPT##--cmake=}"
;;
--cmake-opts=*)
CMAKE_OPTS="${OPT##--cmake-opts=}"
;;
--make=*)
MAKE="${OPT##--make=}"
;;
--ninja=*)
NINJA="${OPT##--ninja=}"
;;
--enable-debugger-support)
ENABLE_DEBUGGER_SUPPORT=true
;;
--git-mirror=*)
add_git_mirror "${OPT##--git-mirror=}"
;;
-*)
die "Unknown option ${OPT}, see --help for supported ones."
esac
done
if [[ -n "${DO_HELP}" ]]; then
cat <<EOF
Usage: ${PROGNAME} [options]
Rebuild prebuilt host Linux binaries for SwiftShader and the Vulkan loader,
using the Fuchsia prebuilt toolchain and sysroot. The corresponding binaries
can then be used to run graphics tests on infra bots that don't have a GPU,
(see --help-usage for complete details).
Valid options:
--help|-? Print this message
--help-usage Print detailed usage instructions for this script
and the generated binaries.
--install-dir=<DIR> REQUIRED: Specify local installation directory
for generated binaries and data files.
--dest-install-dir=<DIR>
Destination installation directory. This is the
intended final installation location for the
binaries, which can be different from --install-dir
(e.g. when copying them to a different machine).
MUST BE an absolute path.
--build-config-file=<FILE>
Configuration file listing the exact git url and
revisions to use for the build. By default, this is:
${DEFAULT_BUILD_CONFIG_FILE}
--generator=<GENERATOR>
Specify generation build tool. Valid values are
'make' or 'ninja'. By default, use ninja if available,
or fallback to make.
--no-ccache Disable ccache use. By default, if 'ccache' is
in your path, it will be used to rebuild all
C and C++ binaries.
--git-mirror=<SRC_PREFIX>,<DST_PREFIX>
Ensure git urls beginning with SRC_PREFIX will be
replaced by ones beginning with DST_PREFIX.
Can be called multiple times to support
several mirrors.
The following options are used to specify the path and options to programs
invoked by this script. Their default value are taken from environment
variables if defined, or have a simple fallback.
--git=<PROGRAM> Specify git executable to use. Default is GIT environment
variable, or 'git'.
--git-opts=<LIST> Space-separated list of options to the git program.
Default is taken from the GIT_OPTS environment variable,
or an empty list as a fallback.
--cmake=<PROGRAM> Specify CMake executable to use. Default is CMAKE
environment variable, or 'cmake'.
--cmake-opts=<LIST> Space-separated list of options to the CMake program.
Default from CMAKE_OPTS environment variable, or empty
list as a fallback.
--make=<PROGRAM> Specify make executable to use. Default is MAKE
environment variable, or 'make'. Ignored if ninja is used.
--ninja=<PROGRAM> Specify ninja executable to use. Default is NINJA
environment variable, or 'ninja'. Ignored if make is used.
The following options are only useful when debugging this script's
operations, and should not be used to produce release binaries:
--build-dir=<DIR> Specify persistent build directory. By default,
a temporary directory with a random path under
/tmp will be used (and deleted on exit).
--no-clean-build Disable clean builds.
--cmake-toolchain-file=<FILE>
Specify an alternative CMake toolchain file for
this build. The default uses the Fuchsia prebuilt
toolchain and Linux sysroot to ensure the generated
binaries run on as many Linux distributions as
possible.
--enable-debugger-support
Enable SwiftShader debugger support. This feature
is still experimental and disabled by default in
the official build.
EOF
exit 0
fi
if [[ -n "${DO_HELP_USAGE}" ]]; then
cat <<EOF
This script will rebuild binaries required to run Vulkan graphics tests
on a Linux machine that has no GPU, using SwiftShader as the Vulkan driver.
Note that this requires an X server at the moment to run properly.
The binaries should be portable to many Linux distributions.
Complete usage instructions are:
1) Build and install the sources from scratch using this script, e.g.:
INSTALL_DIR=\$HOME/vulkan-swiftshader
${SCRIPT_NAME} --install-dir=\${INSTALL_DIR}
2) Source the \${INSTALL_DIR}/env_vars.sh file, it will set several
environment variables to ensure the right Vulkan libraries and
data files are used (feel free to look or modify this file if needed).
3) Ensure the DISPLAY environment variable is set to point to
an X11 server, if you don't have one, install Xvfb and start
it as a background service, e.g.:
# For installation only.
sudo apt-get install xvfb
# Start Xvfb server on display port 99
Xvfb :99 &
export DISPLAY=:99
4) Run your program.
A good way to check that you have a working environment is to run
the "vulkaninfo" program to verify that you are using SwiftShader as
the Vulkan driver/ICD, e.g.:
\$ vulkaninfo 2>/dev/null| grep deviceName
deviceName = SwiftShader Device (LLVM 7.0.1)
Special use cases:
* Use --dest-install-dir=<DIR> it you intend to install the binaries to
a different final location (e.g when copying them to a remote machine).
For example:
# Generate and install locally
INSTALL_DIR=\$HOME/vulkan-swiftshader
DEST_INSTALL_DIR=/opt/vulkan-swiftshader
${SCRIPT_NAME} \\
--install-dir=\${INSTALL_DIR} \\
--dest-install-dir=\${DEST_INSTALL_DIR}
# Copy to final location:
scp -r \${INSTALL_DIR} remote-machine:\${DEST_INSTALL_DIR}
EOF
exit 0
fi
if [[ -z "${TOP_BUILD_DIR}" ]]; then
TOP_BUILD_DIR="/tmp/fuchsia-vulkan-host-prebuilts-$$"
REMOVE_TMPDIR_ON_EXIT="${TOP_BUILD_DIR}"
else
# The SwiftShader build currently fails when the build install prefix
# contains a space! Detect this early!
if [[ "${TOP_BUILD_DIR}" =~ " " ]]; then
die "ERROR: Build directory cannot contain spaces: [${TOP_BUILD_DIR}]"
fi
fi
readonly SOURCES_DIR="${TOP_BUILD_DIR}/sources"
if [[ -z "${INSTALL_DIR}" ]]; then
die "ERROR: This script requires an --install-dir=<path> argument!"
fi
if [[ -z "${DEST_INSTALL_DIR}" ]]; then
mkdir -p "${INSTALL_DIR}"
DEST_INSTALL_DIR="$(absolute_path "${INSTALL_DIR}")"
else
if ! is_absolute_path "${DEST_INSTALL_DIR}"; then
die "ERROR: --dest-install-dir argument must be absolute path: ${DEST_INSTALL_DIR}"
fi
fi
if [[ -z "${TOOLCHAIN_FILE}" ]]; then
TOOLCHAIN_FILE="$(absolute_path "${SCRIPT_DIR}/../../..")/build/cmake/HostLinuxToolchain.cmake"
fi
if [[ ! -f "${TOOLCHAIN_FILE}" ]]; then
die "ERROR: Missing CMake toolchain file: ${TOOLCHAIN_FILE}"
fi
if [[ -z "${BUILD_CONFIG_FILE}" ]]; then
BUILD_CONFIG_FILE="${DEFAULT_BUILD_CONFIG_FILE}"
fi
if [[ ! -f "${BUILD_CONFIG_FILE}" ]]; then
die "ERROR: Missing build configuration file: ${BUILD_CONFIG_FILE}"
fi
source "${BUILD_CONFIG_FILE}"
# Temporary binaries are installed in this directory. This includes
# development headers, libraries, etc. Only a subset of them will be
# copied to the real installation directory specified by INSTALL_DIR
readonly INSTALL_PREFIX="${TOP_BUILD_DIR}/build-install"
# Fuchsia's clang defaults to errors if there are undefined symbols in
# the version script.
FUCHSIA_CLANG_WORKAROUND="-DCMAKE_SHARED_LINKER_FLAGS=\"-Wl,--undefined-version\""
# NOTE: For some reason, trying to use MinRelSize for the build type ends up
# with binaries that are far larger than Release (e.g. 43 MiB vs 23 MiB
# for libVkLayer_khronos_validation.so, or 95 MiB vs 29 MiB for
# libvk_swiftshader.so !!)
COMMON_CMAKE_FLAGS=(
"-DCMAKE_BUILD_TYPE=Release"
"-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE}"
"-DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX}"
$FUCHSIA_CLANG_WORKAROUND
)
# Auto-detect ccache and use it when available
if [[ -z "${NO_CCACHE}" ]]; then
readonly CCACHE="$(which ccache 2>/dev/null || true)"
if [[ -n "${CCACHE}" ]]; then
COMMON_CMAKE_FLAGS+=("-DUSE_CCACHE=1")
fi
fi
# The command used to build and install binaries to ${INSTALL_PREFIX}
readonly MAKE_JOBS="$(nproc)"
readonly GIT_PROGRAM="$(which "${GIT}" 2>/dev/null || true)"
if [[ -z "${GIT_PROGRAM}" ]]; then
die "ERROR: Cannot find git executable (${GIT})"
fi
readonly GIT_CMD=("${GIT_PROGRAM}" ${GIT_OPTS})
readonly CMAKE_PROGRAM="$(which "${CMAKE}" 2>/dev/null || true)"
if [[ -z "${CMAKE_PROGRAM}" ]]; then
die "ERROR: Cannot find 'cmake' executable (${CMAKE})"
fi
readonly CMAKE_CMD=("${CMAKE_PROGRAM}" ${CMAKE_OPTS})
readonly NINJA_PROGRAM="$(which "${NINJA}" 2>/dev/null || true)"
readonly MAKE_PROGRAM="$(which "${MAKE}" 2>/dev/null || true)"
if [[ -z "${GENERATOR}" ]]; then
if [[ -n "${NINJA_PROGRAM}" ]]; then
GENERATOR=ninja
elif [[ -n "${MAKE_PROGRAM}" ]]; then
GENERATOR=make
echo >&2 "WARNING: Using 'make' to build binaries, using 'ninja' would speed up the build considerably!"
else
die "ERROR: Neither 'make' or 'ninja' are in your path!"
fi
fi
case "${GENERATOR}" in
ninja)
if [[ -z "${NINJA_PROGRAM}" ]]; then
die "ERROR: Missing ninja executable (${NINJA})"
fi
COMMON_CMAKE_FLAGS+=(-GNinja)
readonly BUILD_INSTALL_CMD=("${NINJA_PROGRAM}" "-j${MAKE_JOBS}" install)
;;
make)
if [[ -z "${MAKE_PROGRAM}" ]]; then
die "ERROR: Missing make executable (${MAKE})"
fi
readonly BUILD_INSTALL_CMD=("${MAKE_PROGRAM}" "-j${MAKE_JOBS}" install)
;;
*)
die "ERROR: Invalid --generator value [${GENERATOR}], must be one of: make ninja"
;;
esac
# Clone or update a git repository
# $1: Target directory
# $2: URL (can include revision after a '@' separator)
clone_or_update () {
local URL="$(printf %s "$2" | cut -s -d@ -f1)"
local REVISION="$(printf %s "$2" | cut -s -d@ -f2)"
local DIR="$1"
if [[ -z "${URL}" ]]; then
URL="$2"
fi
URL="$(rewrite_git_url "${URL}")"
echo "Cloning from: $URL..."
if [[ ! -d "${DIR}" ]]; then
"${GIT_CMD[@]}" clone ${URL} "${DIR}"
if [[ "${REVISION}" ]]; then
"${GIT_CMD[@]}" -C "${DIR}" fetch origin --quiet "${REVISION}"
"${GIT_CMD[@]}" -C "${DIR}" checkout --quiet FETCH_HEAD
fi
# if [[ -f "${DIR}/.gitmodules" ]]; then
# "${GIT_CMD[@]}" -C "${DIR}" submodule update --init
# fi
else
if [[ "${REVISION}" ]]; then
"${GIT_CMD[@]}" -C "${DIR}" fetch origin "${REVISION}"
"${GIT_CMD[@]}" -C "${DIR}" checkout --quiet FETCH_HEAD
else
"${GIT_CMD[@]}" -C "${DIR}" pull
fi
# if [[ -f "${DIR}/.gitmodules" ]]; then
# "${GIT_CMD[@]}" -C "${DIR}" submodule update
# fi
fi
}
# $1: Source directory.
# $2: Target directory.
symlink_dir () {
# When using --build-dir, the linked might already exist.
if [[ -d "$1" ]]; then
rm -rf "$1"
fi
mkdir -p "$(dirname "$1")"
ln -sf "$2" "$1"
}
# Build a source directory with CMake.
# Make sure that any dependencies have been built and installed before.
#
# This performs a clean build, and installs the binaries to ${INSTALL_PREFIX}
#
# $1: Source directory
# $2+: Extra cmake arguments
build_with_cmake () {
local SRC_DIR="$(absolute_path "$1")"
local BUILD_DIR="${TOP_BUILD_DIR}/build-$(basename ${SRC_DIR})"
if [[ -z "${NO_CLEAN_BUILD}" ]]; then
rm -rf "${BUILD_DIR}"
fi
(mkdir -p "${BUILD_DIR}" && cd "${BUILD_DIR}" && "${CMAKE_CMD[@]}" "${SRC_DIR}" "${COMMON_CMAKE_FLAGS[@]}" "$@" && "${BUILD_INSTALL_CMD[@]}")
}
# Combine git repository clone/update and cmake build.
# Useful for most projects that don't need special setup between these two
# steps.
# $1: Source directory
# $2: git URL
# $3+: Extra cmake arguments
clone_and_build () {
local SRC_DIR="$1"
local URL="$2"
shift
shift
clone_or_update "${SRC_DIR}" "${URL}"
build_with_cmake ${SRC_DIR} "$@"
}
#
# Swiftshader dependencies.
#
if [[ -n "${ENABLE_DEBUGGER_SUPPORT}" ]]; then
CPPDAP_DIR="${SOURCES_DIR}/cppdap"
clone_or_update "${CPPDAP_DIR}" "${CPPDAP_GIT_URL}"
JSON_DIR="${SOURCES_DIR}/json"
clone_or_update "${JSON_DIR}" "${JSON_GIT_URL}"
LIBBACKTRACE_DIR="${SOURCES_DIR}/libbacktrace"
clone_or_update "${LIBBACKTRACE_DIR}" "${LIBBACKTRACE_GIT_URL}"
fi
#
# SwiftShader - no dependencies
#
readonly SWIFTSHADER_DIR="${SOURCES_DIR}/SwiftShader"
clone_or_update "${SWIFTSHADER_DIR}" "${SWIFTSHADER_GIT_URL}"
DEBUGGER_SUPPORT_FLAG=
if [[ -n "${ENABLE_DEBUGGER_SUPPORT}" ]]; then
symlink_dir "${SWIFTSHADER_DIR}/third_party/cppdap" "${CPPDAP_DIR}"
symlink_dir "${SWIFTSHADER_DIR}/third_party/json" "${CPPDAP_DIR}"
symlink_dir "${SWIFTSHADER_DIR}/third_party/libbacktrace/src" "${LIBBACKTRACE_DIR}"
DEBUGGER_SUPPORT_FLAG="-DSWIFTSHADER_ENABLE_DEBUGGER=1"
fi
build_with_cmake "${SWIFTSHADER_DIR}" \
-DSWIFTSHADER_BUILD_TESTS=OFF \
-DSWIFTSHADER_BUILD_SAMPLES=OFF \
-DSWIFTSHADER_BUILD_EGL=0 \
-DSWIFTSHADER_BUILD_GLESv2=0 \
-DSWIFTSHADER_BUILD_GLES_CM=0 \
-DSWIFTSHADER_BUILD_VULKAN=1 \
-DSWIFTSHADER_WARNINGS_AS_ERRORS=0 \
${DEBUGGER_SUPPORT_FLAG}
# Required because "make install" copies into $BUILD_DIR/Linux/ instead.
# The executable and .json files are relocatable, but must be in the same
# directory. Use VK_ICD_FILENAMES=${INSTALL_PREFIX}/lib/vk_swiftshader_icd.json
# to use the SwiftShader ICD with the Vulkan loader.
cp "${TOP_BUILD_DIR}"/build-SwiftShader/Linux/{libvk_swiftshader.so,vk_swiftshader_icd.json} "${INSTALL_PREFIX}/lib"
#
# Vulkan-Headers - no dependencies
#
readonly VULKAN_HEADERS_DIR="${SOURCES_DIR}/Vulkan-Headers"
clone_and_build "${VULKAN_HEADERS_DIR}" "${VULKAN_HEADERS_GIT_URL}"
readonly VULKAN_HEADERS_CMD=("-DVULKAN_HEADERS_INSTALL_DIR=${INSTALL_PREFIX}")
#
# Vulkan-Loader - depends on Vulkan-Headers
#
readonly VULKAN_LOADER_DIR="${SOURCES_DIR}/Vulkan-Loader"
clone_and_build "${VULKAN_LOADER_DIR}" "${VULKAN_LOADER_GIT_URL}" \
-DBUILD_TESTS=OFF \
-DBUILD_WSI_WAYLAND_SUPPORT=OFF \
"${VULKAN_HEADERS_CMD[@]}"
#
# Vulkan-Utility-Libraries - depends on Vulkan-Headers
#
readonly VULKAN_UTILITY_LIBRARIES_DIR="${SOURCES_DIR}/Vulkan-Utility-Libraries"
clone_and_build "${VULKAN_UTILITY_LIBRARIES_DIR}" "${VULKAN_UTILITY_LIBRARIES_GIT_URL}" \
"${VULKAN_HEADERS_CMD[@]}"
#
# effcee
#
readonly EFFCEE_DIR="${SOURCES_DIR}/effcee"
clone_or_update "${EFFCEE_DIR}" "${EFFCEE_GIT_URL}"
#
# RE2
#
readonly RE2_DIR="${SOURCES_DIR}/re2"
clone_or_update "${RE2_DIR}" "${RE2_GIT_URL}"
#
# SPIRV-Headers - no dependencies
#
readonly SPIRV_HEADERS_DIR="${SOURCES_DIR}/SPIRV-Headers"
clone_and_build "${SPIRV_HEADERS_DIR}" "${SPIRV_HEADERS_GIT_URL}"
#
# SPIRV-Tools - depends on SPIRV-Headers, effcee & re2
#
readonly SPIRV_TOOLS_DIR="${SOURCES_DIR}/SPIRV-Tools"
clone_or_update "${SPIRV_TOOLS_DIR}" "${SPIRV_TOOLS_GIT_URL}"
# Special setup of the external sub-directory
symlink_dir "${SPIRV_TOOLS_DIR}/external/spirv-headers" "${SPIRV_HEADERS_DIR}"
symlink_dir "${SPIRV_TOOLS_DIR}/external/effcee" "${EFFCEE_DIR}"
symlink_dir "${SPIRV_TOOLS_DIR}/external/re2" "${RE2_DIR}"
build_with_cmake "${SPIRV_TOOLS_DIR}" -DSPIRV_SKIP_TESTS=ON
#
# glslang - depends on SPIRV_Tools
#
readonly GLSLANG_DIR="${SOURCES_DIR}/glslang"
clone_or_update "${GLSLANG_DIR}" "${GLSLANG_GIT_URL}"
# Special setup of the external sub-directory
symlink_dir "${GLSLANG_DIR}/External/spirv-tools" "${SPIRV_TOOLS_DIR}"
build_with_cmake "${GLSLANG_DIR}"
readonly GLSLANG_CMD=("-DGLSLANG_INSTALL_DIR=${INSTALL_PREFIX}")
#
# Vulkan-ValidationLayers - depends on Vulkan-Headers + Vulkan-Utility-Libraries + glslang + SPIRV-Tools
#
# Note that when cross-compiling, the CMake probing will not find the installed
# SPIRV-Tools libraries (probably due to pkg-config issues), so force them
# through CMake variables below.
#
readonly VULKAN_VALIDATION_LAYERS="${SOURCES_DIR}/Vulkan-ValidationLayers"
clone_and_build "${VULKAN_VALIDATION_LAYERS}" "${VULKAN_VALIDATION_LAYERS_GIT_URL}" \
-DBUILD_TESTS=OFF \
-DBUILD_WSI_WAYLAND_SUPPORT=OFF \
"${VULKAN_HEADERS_CMD[@]}" "${GLSLANG_CMD[@]}" \
-DSPIRV_HEADERS_INSTALL_DIR="${INSTALL_PREFIX}" \
-DVULKAN_UTILITY_LIBRARIES_INSTALL_DIR="${INSTALL_PREFIX}" \
-DSPIRV_TOOLS_LIB="${INSTALL_PREFIX}/lib/libSPIRV-Tools.a" \
-DSPIRV_TOOLS_OPT_LIB="${INSTALL_PREFIX}/lib/libSPIRV-Tools-opt.a" \
-DUSE_ROBIN_HOOD_HASHING=OFF \
-DBUILD_WERROR=OFF
# Finally, copy files of interest to their final location
#
# NOTE: Both libvulkan.so and libvulkan.so.1 are symlinks.
#
# Executables are linked with "libvulkan.so.1", but the vulkan.hpp header may
# call dlopen on "libvulkan.so". On some systems, it will crash if these two
# files are not the same one.
#
# So we make libvulkan.so.1 a copy of the dynamic library it links to, and
# make libvulkan.so a symbolic link to libvulkan.so.1.
#
if [[ ! -f "${INSTALL_PREFIX}/lib/libvulkan.so.1" ]]; then
echo "Fatal: libvulkan.so.1 not found!" >&2
exit 1
fi
TMP_FILE=`mktemp -p ${INSTALL_PREFIX}`
cp -f "${INSTALL_PREFIX}/lib/libvulkan.so.1" "${TMP_FILE}"
mv -f "${TMP_FILE}" "${INSTALL_PREFIX}/lib/libvulkan.so.1"
chmod 640 "${INSTALL_PREFIX}/lib/libvulkan.so.1"
ln -sf "libvulkan.so.1" "${INSTALL_PREFIX}/lib/libvulkan.so"
FILES=(
lib/libvk_swiftshader.so
lib/vk_swiftshader_icd.json
lib/libvulkan.so.1
lib/libvulkan.so
lib/libVkLayer_khronos_validation.so
share/vulkan/explicit_layer.d/VkLayer_khronos_validation.json
)
echo "Installing to ${INSTALL_DIR}..."
mkdir -p "${INSTALL_DIR}" &&
(tar c -f- -C "${INSTALL_PREFIX}" --preserve-permissions "${FILES[@]}") | (tar x -f- --overwrite -C "${INSTALL_DIR}")
# Copy the build configuration file to the installation directory as well, for reference.
cp "${BUILD_CONFIG_FILE}" "${INSTALL_DIR}/swiftshader_vulkan.build_config"
# Generate a small shell script that sets all necessary environment variables
# NOTE: The output below is designed to be sourced from any user shell and
# cannot use Bash-specific features like `[[` instead of `[`.
cat > "${INSTALL_DIR}/env_vars.sh" <<EOF
# Auto-generated - Source this file in your environment to use these Vulkan
# binaries.
# Modify LD_LIBRARY_PATH to find libvulkan.so here.
# NOTE: An empty item in a PATH variable is treated as the current directory,
# which is often undesirable for security reasons. And this happens when
# using a leading or trailing column (i.e. PATH=:/bin really means
# "search in current directory, then in /bin").
if [ -z "\$LD_LIBRARY_PATH" ]; then
export LD_LIBRARY_PATH="${DEST_INSTALL_DIR}/lib"
else
LD_LIBRARY_PATH="${DEST_INSTALL_DIR}/lib:\$LD_LIBRARY_PATH"
fi
# Set VK_LAYER_PATH to force the Vulkan loader to use the rigth layers
export VK_LAYER_PATH="${DEST_INSTALL_DIR}/share/vulkan/explicit_layer.d"
# Set VK_ICD_FILENAMES to force the Vulkan loader to use SwiftShader.
export VK_ICD_FILENAMES="${DEST_INSTALL_DIR}/lib/vk_swiftshader_icd.json"
if [ -z "\$DISPLAY" ]; then
echo >&2 "WARNING: Define DISPLAY environment variable to run Vulkan programs!"
fi
EOF
echo "Done! Remember to source ${INSTALL_DIR}/env_vars.sh before running Vulkan programs."