109 lines
4.4 KiB
Shell
109 lines
4.4 KiB
Shell
|
|
#!/usr/bin/env bash
|
||
|
|
# Builds the CultMesh native QUIC bridge for Linux x64.
|
||
|
|
#
|
||
|
|
# The Windows counterpart (build-quic-native.ps1) takes MsQuic from a pinned
|
||
|
|
# NuGet package. There is no Linux binary in any MsQuic NuGet and the GitHub
|
||
|
|
# releases for v2.5.9 carry only test bundles, so the runtime here comes from
|
||
|
|
# Microsoft's Debian 13 pool and the headers come from the msquic source tree at
|
||
|
|
# the matching tag. Both are pinned by SHA-256 the same way the NuGet is: a
|
||
|
|
# digest that stops matching is a changed dependency, not a warning.
|
||
|
|
#
|
||
|
|
# This must run on a Debian 13 host (the container in .github/workflows, or the
|
||
|
|
# workstation's Docker engine for the development loop). The artifact is linked
|
||
|
|
# against that distribution's glibc, so where it was built is part of what it is.
|
||
|
|
#
|
||
|
|
# scripts/build-quic-native.sh [output-directory]
|
||
|
|
#
|
||
|
|
# Default output: artifacts/quic-native/linux-x64, which is git-ignored build
|
||
|
|
# output and never delivery.
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
|
|
version="2.5.9"
|
||
|
|
output_directory="${1:-${repo_root}/artifacts/quic-native/linux-x64}"
|
||
|
|
case "${output_directory}" in
|
||
|
|
/*) ;;
|
||
|
|
*) output_directory="${repo_root}/${output_directory}" ;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
cache_root="${repo_root}/artifacts/dependencies/msquic-linux-${version}"
|
||
|
|
deb_path="${cache_root}/libmsquic_${version}_amd64.deb"
|
||
|
|
extract_root="${cache_root}/package"
|
||
|
|
include_root="${cache_root}/include"
|
||
|
|
build_root="${repo_root}/artifacts/quic-native-build/linux-x64/Release"
|
||
|
|
|
||
|
|
deb_url="https://packages.microsoft.com/debian/13/prod/pool/main/libm/libmsquic/libmsquic_${version}_amd64.deb"
|
||
|
|
deb_sha256="1baa61ade0b7b4a99f6dcb6b00d9aedb12b5566d00918a325be7425e878e51ba"
|
||
|
|
header_base="https://raw.githubusercontent.com/microsoft/msquic/v${version}/src/inc"
|
||
|
|
|
||
|
|
# The three headers the POSIX build needs. msquic.h includes msquic_posix.h,
|
||
|
|
# which includes quic_sal_stub.h; the NuGet ships only the Windows trio.
|
||
|
|
header_names=("msquic.h" "msquic_posix.h" "quic_sal_stub.h")
|
||
|
|
header_sha256s=(
|
||
|
|
"c9abfdd02c45910649dd335d6bd82718e4ddd2fdb35fe550567c78f032551e0c"
|
||
|
|
"b285fa66b9c9bdc886c30ef92910da472692b25f5c6192416fb40f08f64e22ec"
|
||
|
|
"9b13328d9aec8807a754b2bc391b31b5d09b1c5f6cec064012051683ed169055"
|
||
|
|
)
|
||
|
|
|
||
|
|
verify_sha256() {
|
||
|
|
local path="$1" expected="$2"
|
||
|
|
local actual
|
||
|
|
actual="$(sha256sum "${path}" | cut -d' ' -f1)"
|
||
|
|
if [[ "${actual}" != "${expected}" ]]; then
|
||
|
|
echo "Digest mismatch for ${path}" >&2
|
||
|
|
echo " expected ${expected}" >&2
|
||
|
|
echo " actual ${actual}" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
mkdir -p "${cache_root}" "${include_root}"
|
||
|
|
|
||
|
|
if [[ ! -f "${deb_path}" ]]; then
|
||
|
|
echo "Fetching ${deb_url}"
|
||
|
|
curl -fsSL -o "${deb_path}" "${deb_url}"
|
||
|
|
fi
|
||
|
|
verify_sha256 "${deb_path}" "${deb_sha256}"
|
||
|
|
|
||
|
|
if [[ ! -f "${extract_root}/usr/lib/x86_64-linux-gnu/libmsquic.so.${version}" ]]; then
|
||
|
|
rm -rf "${extract_root}"
|
||
|
|
mkdir -p "${extract_root}"
|
||
|
|
dpkg-deb -x "${deb_path}" "${extract_root}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
for index in "${!header_names[@]}"; do
|
||
|
|
header="${header_names[${index}]}"
|
||
|
|
target="${include_root}/${header}"
|
||
|
|
if [[ ! -f "${target}" ]]; then
|
||
|
|
echo "Fetching ${header_base}/${header}"
|
||
|
|
curl -fsSL -o "${target}" "${header_base}/${header}"
|
||
|
|
fi
|
||
|
|
verify_sha256 "${target}" "${header_sha256s[${index}]}"
|
||
|
|
done
|
||
|
|
|
||
|
|
library_directory="${extract_root}/usr/lib/x86_64-linux-gnu"
|
||
|
|
# CMake links `-lmsquic`, which wants a plain `libmsquic.so` to resolve against;
|
||
|
|
# the deb ships only the versioned file and its SONAME symlink.
|
||
|
|
ln -sf "libmsquic.so.${version}" "${library_directory}/libmsquic.so"
|
||
|
|
|
||
|
|
cmake -S "${repo_root}/native/GameCult.Mesh.Quic.Native" -B "${build_root}" -G Ninja \
|
||
|
|
-DCMAKE_BUILD_TYPE=Release \
|
||
|
|
-DMSQUIC_INCLUDE_DIR="${include_root}" \
|
||
|
|
-DMSQUIC_LIB_DIR="${library_directory}"
|
||
|
|
cmake --build "${build_root}"
|
||
|
|
|
||
|
|
mkdir -p "${output_directory}"
|
||
|
|
cp "${build_root}/bin/libgamecult_mesh_quic_native.so" "${output_directory}/"
|
||
|
|
# The real file under the SONAME the bridge records, not the symlink: what ships
|
||
|
|
# beside the bridge has to be a file, because the package directory is copied.
|
||
|
|
cp "${library_directory}/libmsquic.so.${version}" "${output_directory}/libmsquic.so.2"
|
||
|
|
# The deb carries three library files and no licence text, so the MIT licence
|
||
|
|
# comes from the copy this repo already committed for the Windows plugin. It is
|
||
|
|
# the same text for both platforms.
|
||
|
|
cp "${repo_root}/unity/org.gamecult.cultlib/Third Party Notices/MSQUIC-LICENSE.txt" \
|
||
|
|
"${output_directory}/MSQUIC-LICENSE.txt"
|
||
|
|
|
||
|
|
echo "CultMesh native QUIC runtime: ${output_directory}"
|
||
|
|
ls -l "${output_directory}"
|
||
|
|
sha256sum "${output_directory}"/* | sed "s|${output_directory}/||"
|