| #!/bin/bash |
| # Copyright (C) 2026 Open Containers Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| set -xEeuo pipefail |
| |
| # shellcheck source=./script/lib.sh |
| source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" |
| |
| PLATFORM="$(get_platform)" |
| |
| declare -A GOARCH_TO_RUST_TARGET=( |
| ["386"]=i686-unknown-linux-gnu |
| ["amd64"]=x86_64-unknown-linux-gnu |
| ["arm64"]=aarch64-unknown-linux-gnu |
| ["armel"]=armv5te-unknown-linux-gnueabi |
| ["armhf"]=armv7-unknown-linux-gnueabihf |
| ["ppc64le"]=powerpc64le-unknown-linux-gnu |
| ["s390x"]=s390x-unknown-linux-gnu |
| ["riscv64"]=riscv64gc-unknown-linux-gnu |
| ) |
| |
| declare -A RUST_TARGET_TO_CC=( |
| ["i686-unknown-linux-gnu"]="i686-${PLATFORM}-gcc" |
| ["x86_64-unknown-linux-gnu"]="x86_64-${PLATFORM}-gcc" |
| ["aarch64-unknown-linux-gnu"]="aarch64-${PLATFORM}-gcc" |
| ["armv5te-unknown-linux-gnueabi"]="arm-${PLATFORM}eabi-gcc" |
| ["armv7-unknown-linux-gnueabihf"]="arm-${PLATFORM}eabihf-gcc" |
| ["powerpc64le-unknown-linux-gnu"]="powerpc64le-${PLATFORM}-gcc" |
| ["s390x-unknown-linux-gnu"]="s390x-${PLATFORM}-gcc" |
| ["riscv64gc-unknown-linux-gnu"]="riscv64-${PLATFORM}-gcc" |
| ) |
| |
| # sha256 checksums for libpathrs release tarballs. |
| declare -A LIBPATHRS_SHA256=( |
| ["0.2.4"]=45aca68e698b844fae0cf7c459bc441519b0e7b48397caa7d3936cfc68d73f77 |
| ) |
| |
| function generate_cargo_config() { |
| for rust_target in "${GOARCH_TO_RUST_TARGET[@]}"; do |
| local target_gcc="${RUST_TARGET_TO_CC[$rust_target]}" |
| |
| # Based on <https://wiki.debian.org/Rust#Crosscompiling>. |
| cat <<-EOF |
| [target.$rust_target] |
| linker = "$target_gcc" |
| rustflags = ["-L", "$(rustc --print sysroot)/lib/rustlib/$rust_target/lib"] |
| EOF |
| done |
| } |
| |
| # Due to libpathrs being MPLv2/LGPLv3 we must include its sources, so |
| # download, install and build against it. |
| # Parameters: |
| # $1 -- libpathrs version to download and build. |
| # $2 -- destination directory. |
| # $@ -- additional architectures to cross-compile for (optional) |
| function build_libpathrs() { |
| local ver="$1" |
| shift |
| local dest="$1" |
| shift |
| local go_arches=("$@") |
| local tar="libpathrs-${ver}.tar.xz" |
| |
| # Download, check, and extract. |
| wget "https://github.com/cyphar/libpathrs/releases/download/v${ver}/${tar}"{,.asc} |
| sha256sum --strict --check - <<<"${LIBPATHRS_SHA256[${ver}]} *${tar}" |
| |
| local srcdir |
| srcdir="$(mktemp -d)" |
| tar xf "$tar" -C "$srcdir" |
| pushd "$srcdir/libpathrs-$ver" || return |
| |
| # Use cargo-auditable if available. |
| if cargo auditable --version &>/dev/null; then |
| export CARGO="cargo auditable" |
| fi |
| local extra_cargo_flags=("--locked") |
| |
| # If we are being asked to install this in a system library directory |
| # (i.e., --prefix=/usr or something similar), the correct place to put |
| # libpathrs.so depends very strongly on the distro we are running on, and |
| # detecting this in a generic way is quite difficult. |
| # |
| # The simplest solution is to use a disto-packaged binary to detect where |
| # libc.so is installed and use the same import path, so we look at |
| # /proc/self/maps and parse out the parent directory of the libc.so being |
| # used. |
| local native_libdir libdir= |
| native_libdir="$(awk '$NF ~ /\/libc([.-].*)?\.so/ { print $NF }' /proc/self/maps | |
| sort -u | head -n1 | xargs dirname)" |
| if [[ "$native_libdir" == "$dest/"* ]]; then |
| libdir="$native_libdir" |
| fi |
| |
| # Install native version for Dockerfile builds. |
| make \ |
| EXTRA_CARGO_FLAGS="${extra_cargo_flags[*]}" \ |
| release |
| ./install.sh \ |
| --prefix="$dest" \ |
| --libdir="$libdir" |
| cargo clean |
| |
| local cargo_config |
| cargo_config="$(mktemp --tmpdir runc-libpathrs-cargo.toml.XXXXXX)" |
| # shellcheck disable=SC2064 # We want to resolve the path here. |
| trap "rm -f '$cargo_config'" EXIT |
| |
| # Only use the cross-compile config when we actually need to cross-compile. |
| # RedHat-based distros insist on calling their targets "$ARCH-redhat-linux" |
| # which breaks our above logic, but we don't ever need to cross-compile on |
| # RedHat distros so we can ignore this. |
| generate_cargo_config >"$cargo_config" |
| extra_cargo_flags+=("--config=$cargo_config") |
| |
| for go_arch in "${go_arches[@]}"; do |
| local rust_target="${GOARCH_TO_RUST_TARGET[$go_arch]}" |
| make \ |
| EXTRA_CARGO_FLAGS="${extra_cargo_flags[*]} --target=$rust_target" \ |
| release |
| ./install.sh \ |
| --rust-target="$rust_target" \ |
| --prefix="$dest/$go_arch" |
| cargo clean |
| done |
| |
| # Place the source tarball to $dest/src. |
| popd || return |
| mkdir -p "$dest"/src |
| mv "$tar"{,.asc} "$dest"/src |
| } |
| |
| if [ $# -lt 2 ]; then |
| echo "Usage: $0 <version> <dest-dir> [<extra-arch> ...]" >&2 |
| exit 1 |
| fi |
| |
| build_libpathrs "$@" |