#!/bin/sh
# Copyright (c) 2015-2022 LunarG, Inc.
set -eu

usage() {
    echo "Script to build repositories that are useful for Vulkan development"
    echo ""
    echo "Usage: $0 [--clean|--help] [OPTION...] [REPO...]"
    echo "OPTIONS:"
    echo "    [--help|help] prints this usage and exits"
    echo "    [--clean|-c] deletes all the build directories and exits"
    echo "    [--debug|-d] build binaries as debuggable (will replace existing binaries)"
    echo "    [--numjobs #|-j #] specify the number of jobs to use for building, defaults to using 1 job"
    echo "    [--maxjobs] uses nproc to use max jobs possible"
    echo "    [--skip-installing-deps] skips attempting to install package dependencies to build SDK"
    echo "REPOS:"
    echo "    Any or no repositories can be specified for building. If none are specified, then all are built"
    echo "        [all] this will build all repositories, same as specifying no repositories"
    echo "    Repositories that can be specified:"
    echo "        [glslang] [vulkan-headers] [vulkan-loader|loader]"
    echo "        [vulkan-validationlayers|layers] [vulkan-tools|tools] [vulkantools|lunarg-tools]"
    echo "        [shaderc] [spirv-headers] [spirv-tools|spirvtools] [spirv-cross|spirvcross]"
    echo "        [gfxreconstruct] [spirv-reflect] [vulkan-extensionlayer] [vulkan-profiles]"
    echo "        [DirectXShaderCompiler|dxc] [volk] [VulkanMemoryAllocator|vma] [VulkanCapsViewer|vcv]"
    echo "        [jsoncpp] [valijson]"
    echo "EXAMPLES:"
    echo "    './vulkansdk --maxjobs' this will build everything and use as many jobs as possible"
    echo "    './vulkansdk -j 4 vulkan-validationlayers' this will build vulkan-validationlayers using 4 jobs"
    echo "    './vulkansdk --debug vulkan-loader' this will build a debuggable loader"
    echo "    './vulkansdk --clean' deletes all the build directories and exits"
    echo "    './vulkansdk glslang vulkan-tools' builds glslang and vulkan-tools"
    echo ""
    exit
}

build_spirv_headers() {
    echo "~~~Building SPIRV-Headers~~~"
    cd "${SPIRV_HEADERS_DIR}"
    [ -d "${SPIRV_HEADERS_DIR}/${BUILD_DIR}" ] || mkdir -p "${SPIRV_HEADERS_DIR}/${BUILD_DIR}"
    cd "${SPIRV_HEADERS_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="Release" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        "${SPIRV_HEADERS_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_spirv_tools() {
    echo "~~~Building SPIRV-Tools~~~"
    cd "${SPIRV_TOOLS_DIR}"
    [ -d "${SPIRV_TOOLS_DIR}/${BUILD_DIR}" ] || mkdir -p "${SPIRV_TOOLS_DIR}/${BUILD_DIR}"
    cd "${SPIRV_TOOLS_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="Release" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DSPIRV-Headers_SOURCE_DIR="$ARCHDIR" \
        -DSPIRV_SKIP_TESTS="ON" \
        "${SPIRV_TOOLS_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_glslang() {
    echo "~~~Building glslang~~~"
    cd "$GLSL_DIR"
    [ -d "${GLSL_DIR}/${BUILD_DIR}" ] || mkdir -p "${GLSL_DIR}/${BUILD_DIR}"
    cd "${GLSL_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DBUILD_TESTING="OFF" \
        -DENABLE_OPT="OFF" \
        "${GLSL_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_headers() {
    echo "~~~Building Vulkan-Headers~~~"
    cd "$VH_DIR"
    [ -d "$VH_DIR/${BUILD_DIR}" ] || mkdir "$VH_DIR/${BUILD_DIR}"
    cd "$VH_DIR/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        "${VH_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_loader() {
    echo "~~~Building Vulkan-Loader~~~"
    cd "$VL_DIR"
    [ -d "${VL_DIR}/${BUILD_DIR}" ] || mkdir -p "${VL_DIR}/${BUILD_DIR}"
    cd "${VL_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELDEBINFO_TYPE" \
        -DVULKAN_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DSYSCONFDIR="/etc" \
        "${VL_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_robin_hood_hashing() {
    echo "~~~Building Robin-Hood-Hashing~~~"
    cd "$RH_DIR"
    [ -d "${RH_DIR}/${BUILD_DIR}" ] || mkdir -p "${RH_DIR}/${BUILD_DIR}"
    cd "${RH_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DRH_STANDALONE_PROJECT="OFF" \
        "${RH_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_validation_layers() {
    echo "~~~Building Vulkan-ValidationLayers~~~"
    cd "$VV_DIR"
    [ -d "${VV_DIR}/${BUILD_DIR}" ] || mkdir -p "${VV_DIR}/${BUILD_DIR}"
    cd "${VV_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELDEBINFO_TYPE" \
        -DVULKAN_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DGLSLANG_INSTALL_DIR="$ARCHDIR" \
        -DSPIRV_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DSPIRV_TOOLS_INSTALL_DIR="$ARCHDIR" \
        -DCMAKE_INSTALL_DATAROOTDIR="etc" \
        -DBUILD_TESTS="OFF" \
        -DBUILD_LAYER_SUPPORT_FILES="ON" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DANNOTATED_SPEC_LINK="\"https://vulkan.lunarg.com/doc/view/_MAGIC_VERSION_ID_.0/linux/_MAGIC_ANNOTATED_SPEC_TYPE_/vkspec.html\"" \
        -DROBIN_HOOD_HASHING_INSTALL_DIR="$ARCHDIR" \
        "${VV_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_extension_layer() {
    echo "~~~Building Vulkan-ExtensionLayer~~~"
    cd "$EXT_LAYER_DIR"
    [ -d "${EXT_LAYER_DIR}/${BUILD_DIR}" ] || mkdir -p "${EXT_LAYER_DIR}/${BUILD_DIR}"
    cd "${EXT_LAYER_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELDEBINFO_TYPE" \
        -DVULKAN_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DSPIRV_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DSPIRV_TOOLS_INSTALL_DIR="$ARCHDIR" \
        -DBUILD_TESTS="OFF" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DCMAKE_INSTALL_DATAROOTDIR="etc" \
        "${EXT_LAYER_DIR}"
    make $NUMJOBS install
    [ -e "${LIBDIR}/libVkLayer_khronos_timeline_semaphore.so" ] &&\
        rm -v "${LIBDIR}/libVkLayer_khronos_timeline_semaphore.so"
    [ -e "${ARCHDIR}/etc/vulkan/explicit_layer.d/VkLayer_khronos_timeline_semaphore.json" ] &&\
        rm -v "${ARCHDIR}/etc/vulkan/explicit_layer.d/VkLayer_khronos_timeline_semaphore.json"
    cd "${SDKDIR}"
}

build_tools() {
    echo "~~~Building Vulkan-Tools~~~"
    cd "$VT_DIR"
    [ -d "${VT_DIR}/${BUILD_DIR}" ] || mkdir -p "${VT_DIR}/${BUILD_DIR}"
    cd "${VT_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELDEBINFO_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DVULKAN_LOADER_INSTALL_DIR="$ARCHDIR" \
        -DGLSLANG_INSTALL_DIR="$ARCHDIR" \
        -DVULKAN_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        "${VT_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_lunarg_tools() {
    echo "~~~Building LunarG VulkanTools~~~"
    cd "$LGVT_DIR"
    [ -d "${LGVT_DIR}/${BUILD_DIR}" ] || mkdir -p "${LGVT_DIR}/${BUILD_DIR}"
    cd "${LGVT_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELDEBINFO_TYPE" \
        -DVULKAN_LOADER_INSTALL_DIR="$ARCHDIR" \
        -DVULKAN_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DVULKAN_VALIDATIONLAYERS_INSTALL_DIR="$ARCHDIR" \
        -DBUILD_TESTS="OFF" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
	-DJSONCPP_INCLUDE_DIR="$LGVT_DIR/submodules/jsoncpp/dist" \
	-DJSONCPP_SOURCE_DIR="$LGVT_DIR/submodules/jsoncpp/dist" \
        -DINSTALL_GTEST="OFF" \
        "${LGVT_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_shaderc() {
    echo "~~~Building shaderc~~~"
    cd "${SHADERC_DIR}"
    python update_shaderc_sources.py
    cd src
    [ -d "${SHADERC_DIR}/src/${BUILD_DIR}" ] || mkdir "${SHADERC_DIR}/src/${BUILD_DIR}"
    cd "${SHADERC_DIR}/src/${BUILD_DIR}"
    cmake -G"Unix Makefiles" \
        -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DSHADERC_SKIP_INSTALL="ON" \
        -DSHADERC_ENABLE_INSTALL="ON" \
        -DSHADERC_SKIP_TESTS="ON" \
        -DSKIP_SPIRV_TOOLS_INSTALL="ON" \
        -DSKIP_GLSLANG_INSTALL="ON" \
        -DSKIP_GOOGLETEST_INSTALL="ON" \
        -DSHADERC_SKIP_EXAMPLES="ON" \
        -DSHADERC_SKIP_COPYRIGHT_CHECK="ON" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        "${SHADERC_DIR}/src/"
    make $NUMJOBS install
    install -vm644 "${SHADERC_DIR}/src/${BUILD_DIR}/libshaderc_util/libshaderc_util.a" "$LIBDIR"
    cd "${SDKDIR}"
}

build_spirv_cross() {
    echo "~~~Building SPIRV-Cross~~~"
    cd "${SPIRV_CROSS_DIR}"
    [ -d "${SPIRV_CROSS_DIR}/${BUILD_DIR}" ] || mkdir "${SPIRV_CROSS_DIR}/${BUILD_DIR}"
    cd "${SPIRV_CROSS_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DSPIRV_CROSS_ENABLE_TESTS="OFF" \
        -DSPIRV_CROSS_SHARED="ON" \
        -DSPIRV_CROSS_FORCE_PIC="ON" \
        "${SPIRV_CROSS_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_gfxreconstruct() {
    echo "~~~Building GFXreconstruct~~~"
    cd "$GFXRECONSTRUCT_DIR"
    [ -d "${GFXRECONSTRUCT_DIR}/${BUILD_DIR}" ] || mkdir "${GFXRECONSTRUCT_DIR}/${BUILD_DIR}"
    cd "${GFXRECONSTRUCT_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELDEBINFO_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_DATAROOTDIR="etc" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DD3D12_SUPPORT="OFF" \
        "${GFXRECONSTRUCT_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_dxc() {
    echo "~~~Building DXC~~~"
    cd "$DXC_DIR"
    [ -d "${DXC_DIR}/${BUILD_DIR}" ] || mkdir "${DXC_DIR}/${BUILD_DIR}"
    cd "${DXC_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -GNinja \
        -DLLVM_BUILD_TOOLS="OFF" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -C"${DXC_DIR}"/cmake/caches/PredefinedParams.cmake \
        "${DXC_DIR}"
    ninja $NUMJOBS install
    install -vd "${INCLUDEDIR}/dxc/"
    install -v "${DXC_DIR}/include/dxc/dxcapi.h" "${INCLUDEDIR}/dxc/"
    install -v "${DXC_DIR}/include/dxc/WinAdapter.h" "${INCLUDEDIR}/dxc/"
    cd "${SDKDIR}"
}

build_spirv_reflect() {
    echo "~~~Building SPIRV-Reflect~~~"
    cd "${SPIRV_REFLECT_DIR}"
    [ -d "${SPIRV_REFLECT_DIR}/${BUILD_DIR}" ] || mkdir "${SPIRV_REFLECT_DIR}/${BUILD_DIR}"
    cd "${SPIRV_REFLECT_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DSPIRV_REFLECT_BUILD_TESTS="OFF" \
        "${SPIRV_REFLECT_DIR}"
    make $NUMJOBS install
    install -vd "${INCLUDEDIR}/SPIRV-Reflect/"
    install -v "${SPIRV_REFLECT_DIR}/spirv_reflect.c" "${INCLUDEDIR}/SPIRV-Reflect/"
    install -v "${SPIRV_REFLECT_DIR}/spirv_reflect.h" "${INCLUDEDIR}/SPIRV-Reflect/"
    install -vd "${INCLUDEDIR}/SPIRV-Reflect/include/spirv/unified1/"
    install -v "${SPIRV_REFLECT_DIR}/include/spirv/unified1/spirv.h" "${INCLUDEDIR}/SPIRV-Reflect/include/spirv/unified1/"
    cd "$SDKDIR"
}

build_vulkan_profiles() {
    echo "~~~Building Vulkan-Profiles~~~"
    cd "${VULKAN_PROFILES_DIR}"
    [ -d "${VULKAN_PROFILES_DIR}/${BUILD_DIR}" ] || mkdir "${VULKAN_PROFILES_DIR}/${BUILD_DIR}"
    cd "${VULKAN_PROFILES_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_BINDIR="$BINDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_DATAROOTDIR="$ARCHDIR/etc/" \
        -DCMAKE_INSTALL_DATADIR="$SHAREDIR" \
        -DVULKAN_HEADERS_INSTALL_DIR="$ARCHDIR" \
        -DVULKAN_LOADER_INSTALL_DIR="$ARCHDIR" \
        -DVULKAN_VALIDATIONLAYERS_INSTALL_DIR="$ARCHDIR" \
        -DJSONCPP_INSTALL_DIR="$ARCHDIR" \
        -DVALIJSON_INSTALL_DIR="$ARCHDIR" \
        -DPROFILES_BUILD_TESTS="OFF" \
        "${VULKAN_PROFILES_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_volk() {
    echo "~~~Building volk~~~"
    cd "$VOLK_DIR"
    [ -d "${VOLK_DIR}/${BUILD_DIR}" ] || mkdir "${VOLK_DIR}/${BUILD_DIR}"
    cd "${VOLK_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DVOLK_INSTALL="ON" \
        -DCMAKE_INSTALL_INCLUDEDIR="$INCLUDEDIR/volk" \
        "${VOLK_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_vma() {
    echo "~~~Building VulkanMemoryAllocator~~~"
    cd "$VMA_DIR"
    install -vd "${INCLUDEDIR}/vma/"
    install -v "${VMA_DIR}/include/vk_mem_alloc.h" "${INCLUDEDIR}/vma/"
    cd "${SDKDIR}"
}

build_VulkanCapsViewer() {
    echo "~~~Building VulkanCapsViewer~~~"
    cd "$VCV_DIR"
    [ -d "${VCV_DIR}/${BUILD_DIR}" ] || mkdir "${VCV_DIR}/${BUILD_DIR}"
    cd "${VCV_DIR}/${BUILD_DIR}"
    if [ -x "$(command -v qmake-qt5)" ]; then #fedora
        qmake-qt5 "${VCV_DIR}"
    else
        qmake "${VCV_DIR}"
    fi
    LIBRARY_PATH="${LIBDIR}" make $NUMJOBS
    install -v "vulkanCapsViewer" "${BINDIR}"
    cd "${SDKDIR}"
}

build_jsoncpp() {
    echo "~~~Building jsoncpp~~~"
    cd "$JSONCPP_DIR"
    [ -d "${JSONCPP_DIR}/${BUILD_DIR}" ] || mkdir "${JSONCPP_DIR}/${BUILD_DIR}"
    cd "${JSONCPP_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_INCLUDEDIR="$INCLUDEDIR" \
        -DJSONCPP_WITH_TESTS="OFF" \
        -DJSONCPP_WITH_POST_BUILD_UNITTEST="OFF" \
        -DJSONCPP_WITH_WARNING_AS_ERROR="OFF" \
        -DJSONCPP_WITH_PKGCONFIG_SUPPORT="OFF" \
        -DCMAKE_POSITION_INDEPENDENT_CODE="ON" \
        "${JSONCPP_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

build_valijson() {
    echo "~~~Building valijson~~~"
    cd "$VALIJSON_DIR"
    [ -d "${VALIJSON_DIR}/${BUILD_DIR}" ] || mkdir "${VALIJSON_DIR}/${BUILD_DIR}"
    cd "${VALIJSON_DIR}/${BUILD_DIR}"
    cmake -DCMAKE_BUILD_TYPE="$BUILD_RELEASE_TYPE" \
        -DCMAKE_INSTALL_PREFIX="$ARCHDIR" \
        -DCMAKE_INSTALL_LIBDIR="$LIBDIR" \
        -DCMAKE_INSTALL_INCLUDEDIR="$INCLUDEDIR" \
        "${VALIJSON_DIR}"
    make $NUMJOBS install
    cd "${SDKDIR}"
}

clean_builds() {
    [ -d "${SPIRV_HEADERS_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${SPIRV_HEADERS_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${SPIRV_TOOLS_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${SPIRV_TOOLS_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${GLSL_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${GLSL_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VH_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VH_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VL_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VL_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${RH_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${RH_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VV_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VV_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VT_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VT_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${LGVT_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${LGVT_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${SHADERC_DIR:?}/src/${BUILD_DIR:?}" ] && rm -r "${SHADERC_DIR}/src/${BUILD_DIR}" 2>/dev/null
    [ -d "${SPIRV_CROSS_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${SPIRV_CROSS_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${GFXRECONSTRUCT_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${GFXRECONSTRUCT_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${DXC_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${DXC_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${SPIRV_REFLECT_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${SPIRV_REFLECT_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${EXT_LAYER_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${EXT_LAYER_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VULKAN_PROFILES_DIR:?}/${BUILD_DIR:?}" ] && rm -rf "${VULKAN_PROFILES_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VOLK_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VOLK_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VMA_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VMA_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VCV_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VCV_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${JSONCPP_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${JSONCPP_DIR}/${BUILD_DIR}" 2>/dev/null
    [ -d "${VALIJSON_DIR:?}/${BUILD_DIR:?}" ] && rm -r "${VALIJSON_DIR}/${BUILD_DIR}" 2>/dev/null
    echo "All Build Directories Removed"
    exit
}

install_deps() {
    echo "~~~Attempting to install dependencies~~~"
    ID=$(grep '^ID=' /etc/os-release | cut -d= -f2)
    if [ "$ID" = "ubuntu" ]; then
        VERSION=$(grep '^VERSION_ID=' /etc/os-release | cut -d= -f2 | tr -d '"')
        if [ "$VERSION" = "20.04" ]; then
	    QT5_PACKAGE="qt5-default"
        else
	    QT5_PACKAGE="qtbase5-dev"
        fi
        sudo apt-get update
        sudo apt-get install libglm-dev cmake libxcb-dri3-0 libxcb-present0 libpciaccess0 \
             libpng-dev libxcb-keysyms1-dev libxcb-dri3-dev libx11-dev g++ gcc g++-multilib \
             libwayland-dev libxrandr-dev libxcb-randr0-dev libxcb-ewmh-dev \
             git python-is-python3 bison libx11-xcb-dev liblz4-dev libzstd-dev python3-distutils \
             ocaml-core ninja-build pkg-config libxml2-dev wayland-protocols python3-jsonschema $QT5_PACKAGE
    elif [ "$ID" = "fedora" ]; then
        sudo dnf update
        sudo dnf install @development-tools glm-devel cmake libpng-devel wayland-devel \
             libpciaccess-devel libX11-devel libXpresent libxcb xcb-util libxcb-devel libXrandr-devel \
             xcb-util-keysyms-devel xcb-util-wm-devel python python3 git lz4-devel libzstd-devel python3-distutils-extra qt \
             gcc-g++ wayland-protocols-devel ninja-build python3-jsonschema qt5-qtbase-devel python-unversioned-command
    elif [ "$ID" = "arch" ]; then
        sudo pacman -Sy
        sudo pacman -S --needed base-devel glm cmake libpng wayland libpciaccess libx11 libxpresent \
             libxcb xcb-util libxrandr xcb-util-keysyms xcb-util-wm python git lz4 zstd python-distlib qt5-base \
             wayland-protocols ninja python-jsonschema
    else
        echo "OS was not identified - skipping installing dependencies"
    fi
}

SDKDIR="$( dirname "$( readlink -f "${BASH_SOURCE:-$0}" )" )"
if [ -z "${SDKDIR}" ] || [ ! -n "${SDKDIR}" ] || [ ! -d "${SDKDIR}" ]; then
    echo "The SDK directory is invalid"
    exit 1
fi
ARCH="$(uname -m)"
ARCHDIR="${SDKDIR}/${ARCH}"
[ -d "${ARCHDIR}" ] || mkdir "${ARCHDIR}"
BINDIR="${ARCHDIR}"/bin
[ -d "${BINDIR}" ] || mkdir "${BINDIR}"
SHAREDIR="${ARCHDIR}"/share
[ -d "${SHAREDIR}" ] || mkdir "${SHAREDIR}"
LIBDIR="${ARCHDIR}"/lib
[ -d "${LIBDIR}" ] || mkdir "${LIBDIR}"
INCLUDEDIR="${ARCHDIR}"/include
[ -d "${INCLUDEDIR}" ] || mkdir -p "${INCLUDEDIR}/vulkan/"
ETCDIR="${ARCHDIR}"/etc
[ -d "${ETCDIR}" ] || mkdir -p "${ETCDIR}/vulkan/explicit_layer.d/"
SOURCEDIR="${SDKDIR}"/source

SPIRV_HEADERS_DIR="${SOURCEDIR}"/SPIRV-Headers
SPIRV_TOOLS_DIR="${SOURCEDIR}"/SPIRV-Tools
GLSL_DIR="${SOURCEDIR}"/glslang
VH_DIR="${SOURCEDIR}"/Vulkan-Headers
VL_DIR="${SOURCEDIR}"/Vulkan-Loader
RH_DIR="${SOURCEDIR}"/robin-hood-hashing
VV_DIR="${SOURCEDIR}"/Vulkan-ValidationLayers
VT_DIR="${SOURCEDIR}"/Vulkan-Tools
LGVT_DIR="${SOURCEDIR}"/VulkanTools
SHADERC_DIR="${SOURCEDIR}"/shaderc
SPIRV_CROSS_DIR="${SOURCEDIR}"/SPIRV-Cross
GFXRECONSTRUCT_DIR="${SOURCEDIR}"/gfxreconstruct
DXC_DIR="${SOURCEDIR}"/DirectXShaderCompiler
SPIRV_REFLECT_DIR="${SOURCEDIR}"/SPIRV-Reflect
EXT_LAYER_DIR="${SOURCEDIR}"/Vulkan-ExtensionLayer
VULKAN_PROFILES_DIR="${SOURCEDIR}"/Vulkan-Profiles
VOLK_DIR="${SOURCEDIR}"/volk
VMA_DIR="${SOURCEDIR}"/VulkanMemoryAllocator
VCV_DIR="${SOURCEDIR}"/VulkanCapsViewer
JSONCPP_DIR="${SOURCEDIR}"/jsoncpp
VALIJSON_DIR="${SOURCEDIR}"/valijson

NUMJOBS="-j1"
INSTALL_DEPS=1

BUILD_DIR="build"
BUILD_RELDEBINFO_TYPE="RelWithDebInfo"
BUILD_RELEASE_TYPE="Release"
BUILD_DEBUG_TYPE="Debug"

BUILD_HEADERS=0
BUILD_LOADER=0
BUILD_ROBIN_HOOD_HASHING=0
BUILD_VALIDATION_LAYERS=0
BUILD_EXTENSION_LAYERS=0
BUILD_TOOLS=0
BUILD_LUNARG_TOOLS=0
BUILD_SHADERC=0
BUILD_SPIRV_HEADERS=0
BUILD_SPIRV_TOOLS=0
BUILD_GLSLANG=0
BUILD_SPIRV_CROSS=0
BUILD_GFXRECONSTRUCT=0
BUILD_DXC=0
BUILD_SPIRV_REFLECT=0
BUILD_VULKAN_PROFILES=0
BUILD_VOLK=0
BUILD_VMA=0
BUILD_VCV=0
BUILD_JSONCPP=0
BUILD_VALIJSON=0

build_all() {
    BUILD_HEADERS=1
    BUILD_LOADER=1
    BUILD_ROBIN_HOOD_HASHING=1
    BUILD_VALIDATION_LAYERS=1
    BUILD_EXTENSION_LAYERS=1
    BUILD_TOOLS=1
    BUILD_LUNARG_TOOLS=1
    BUILD_SHADERC=1
    BUILD_SPIRV_HEADERS=1
    BUILD_SPIRV_TOOLS=1
    BUILD_GLSLANG=1
    BUILD_SPIRV_CROSS=1
    BUILD_GFXRECONSTRUCT=1
    BUILD_DXC=1
    BUILD_SPIRV_REFLECT=1
    BUILD_VULKAN_PROFILES=1
    BUILD_VOLK=1
    BUILD_VMA=1
    BUILD_VCV=1
    BUILD_JSONCPP=1
    BUILD_VALIJSON=1
}

BUILD_EVERYTHING=1
while test $# -gt 0; do
    case "$1" in
        help|--help|-h)
            usage
            ;;
        all)
            build_all
            ;;
        --clean|-c|clean)
            clean_builds
            ;;
        --numjobs|-j)
            shift 1
            NUMJOBS="-j${1}"
            ;;
        --maxjobs)
            if [ -z ${MAKEFLAGS+xyz} ]; then
                if [ -x "$(command -v nproc)" ]; then
                    NUMJOBS="-j$(expr $(nproc) - 1)"
                fi
            fi
            ;;
        --skip-installing-deps|--disable-installing-deps)
            INSTALL_DEPS=0
            ;;
        --debug|-d|debug)
            BUILD_RELDEBINFO_TYPE="Debug"
            BUILD_RELEASE_TYPE="Debug"
            BUILD_DEBUG_TYPE="Debug"
            ;;
        [Vv]ulkan-[Hh]eaders|headers)
            BUILD_EVERYTHING=0
            BUILD_HEADERS=1
            ;;
        [Vv]ulkan-[Ll]oader|loader)
            BUILD_EVERYTHING=0
            BUILD_HEADERS=1
            BUILD_LOADER=1
            ;;
        [Vv]ulkan-[Vv]alidation[Ll]ayers|layers)
            BUILD_EVERYTHING=0
            BUILD_SPIRV_HEADERS=1
            BUILD_SPIRV_TOOLS=1
            BUILD_GLSLANG=1
            BUILD_HEADERS=1
            BUILD_SPIRV_HEADERS=1
            BUILD_SPIRV_TOOLS=1
            BUILD_ROBIN_HOOD_HASHING=1
            BUILD_VALIDATION_LAYERS=1
            ;;
        [Vv]ulkan-[Ee]xtension[Ll]ayer)
            BUILD_EVERYTHING=0
            BUILD_HEADERS=1
            BUILD_EXTENSION_LAYERS=1
            ;;
        [Vv]ulkan-[Tt]ools|[Kk]hronos-[Tt]ools|tools)
            BUILD_EVERYTHING=0
            BUILD_HEADERS=1
            BUILD_LOADER=1
            BUILD_TOOLS=1
            ;;
        [Vv]ulkan[Tt]ools|lunarg-tools)
            BUILD_EVERYTHING=0
            BUILD_SPIRV_HEADERS=1
            BUILD_SPIRV_TOOLS=1
            BUILD_GLSLANG=1
            BUILD_HEADERS=1
            BUILD_LOADER=1
            BUILD_ROBIN_HOOD_HASHING=1
            BUILD_VALIDATION_LAYERS=1
            BUILD_LUNARG_TOOLS=1
            ;;
        shaderc)
            BUILD_EVERYTHING=0
            BUILD_SHADERC=1
            ;;
        [Ss]pirv-[Hh]eaders)
            BUILD_EVERYTHING=0
            BUILD_SPIRV_HEADERS=1
            ;;
        SPIRV-Tools|spirv-tools|spirvtools|[Ss]pirv-[Tt]ools)
            BUILD_EVERYTHING=0
            BUILD_SPIRV_HEADERS=1
            BUILD_SPIRV_TOOLS=1
            ;;
        glslang)
            BUILD_EVERYTHING=0
            BUILD_SPIRV_HEADERS=1
            BUILD_SPIRV_TOOLS=1
            BUILD_GLSLANG=1
            ;;
        SPIRV-Cross|spirv-cross|spirvcross)
            BUILD_EVERYTHING=0
            BUILD_SPIRV_CROSS=1
            ;;
        gfxreconstruct|gfxrecon)
            BUILD_EVERYTHING=0
            BUILD_GFXRECONSTRUCT=1
            ;;
        DirectXShaderCompiler|DXC|dxc)
            BUILD_EVERYTHING=0
            BUILD_DXC=1
            ;;
        SPIRV-Reflect|spirv-reflect|spirvreflect)
            BUILD_EVERYTHING=0
            BUILD_SPIRV_REFLECT=1
            ;;
        Vulkan-Profiles|vulkan-profiles|vulkanprofiles)
            BUILD_EVERYTHING=0
            BUILD_JSONCPP=1
            BUILD_VALIJSON=1
            BUILD_SPIRV_HEADERS=1
            BUILD_SPIRV_TOOLS=1
            BUILD_HEADERS=1
            BUILD_LOADER=1
            BUILD_VALIDATION_LAYERS=1
            BUILD_VULKAN_PROFILES=1
            ;;
        Volk|volk)
            BUILD_EVERYTHING=0
            BUILD_VOLK=1
            ;;
        VMA|vma|VulkanMemoryAllocator)
            BUILD_EVERYTHING=0
            BUILD_VMA=1
            ;;
        VCV|vcv|Hardwarecaps|VulkanCapsViewer)
            BUILD_EVERYTHING=0
            BUILD_LOADER=1
            BUILD_VCV=1
            ;;
        *)
            echo "error: unknown option" && usage
            ;;
    esac
    shift
done

if [ $INSTALL_DEPS -eq 1 ]; then
    install_deps
fi
if [ $BUILD_EVERYTHING -eq 1 ]; then
    build_all
fi
if [ $BUILD_SPIRV_HEADERS -eq 1 ]; then
    build_spirv_headers
fi
if [ $BUILD_SPIRV_TOOLS -eq 1 ]; then
    build_spirv_tools
fi
if [ $BUILD_GLSLANG -eq 1 ]; then
    build_glslang
fi
if [ $BUILD_HEADERS -eq 1 ]; then
    build_headers
fi
if [ $BUILD_LOADER -eq 1 ]; then
    build_loader
fi
if [ $BUILD_ROBIN_HOOD_HASHING -eq 1 ]; then
    build_robin_hood_hashing
fi
if [ $BUILD_VALIDATION_LAYERS -eq 1 ]; then
    build_validation_layers
fi
if [ $BUILD_EXTENSION_LAYERS -eq 1 ]; then
    build_extension_layer
fi
if [ $BUILD_TOOLS -eq 1 ]; then
    build_tools
fi
if [ $BUILD_LUNARG_TOOLS -eq 1 ]; then
    build_lunarg_tools
fi
if [ $BUILD_SHADERC -eq 1 ]; then
    build_shaderc
fi
if [ $BUILD_SPIRV_CROSS -eq 1 ]; then
    build_spirv_cross
fi
if [ $BUILD_GFXRECONSTRUCT -eq 1 ]; then
    build_gfxreconstruct
fi
if [ $BUILD_DXC -eq 1 ]; then
    build_dxc
fi
if [ $BUILD_SPIRV_REFLECT -eq 1 ]; then
    build_spirv_reflect
fi
if [ $BUILD_JSONCPP -eq 1 ]; then
    build_jsoncpp
fi
if [ $BUILD_VALIJSON -eq 1 ]; then
    build_valijson
fi
if [ $BUILD_VULKAN_PROFILES -eq 1 ]; then
    build_vulkan_profiles
fi
if [ $BUILD_VOLK -eq 1 ]; then
    build_volk
fi
if [ $BUILD_VMA -eq 1 ]; then
    build_vma
fi
if [ $BUILD_VCV -eq 1 ]; then
    build_VulkanCapsViewer
fi
