Linux: RUNPATH guard, packaging in the container on CI, source archives per commit (L1.7)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-11 14:32:36 -04:00
1 parent a9f8136e46
commit 5accf492ba
14 files changed
+124 -26

No files matched your search

+4 -1
View File
@@ -11,7 +11,10 @@ image=ely-office-linux-build
docker build -q -t "$image" "$root/packaging/linux" >/dev/null
# Own target and Cargo home: host builds need newer glibc.
mkdir -p "$root/target/ubuntu" "$root/target/ubuntu-cargo" "$root/target/ubuntu-home"
docker run --rm --user "$(id -u):$(id -g)" -v "$root:$root" -w "$root" \
# Engines shared from another clone resolve inside too.
share=()
[ -z "${ELY_SHARE:-}" ] || share=(-v "$ELY_SHARE:$ELY_SHARE")
docker run --rm --user "$(id -u):$(id -g)" -v "$root:$root" ${share[@]+"${share[@]}"} -w "$root" \
-e HOME="$root/target/ubuntu-home" -e CARGO_HOME="$root/target/ubuntu-cargo" \
-e CARGO_TARGET_DIR="$root/target/ubuntu" -e ELY_RELEASE_TOKEN \
"$image" "$@"
+35
View File
@@ -34,6 +34,10 @@ fi
echo "package.sh: Linux only" >&2
exit 1
}
command -v patchelf >/dev/null || {
echo "package.sh: no patchelf; run in packaging/linux/container.sh" >&2
exit 1
}
arch=$(uname -m)
case $arch in
x86_64)
@@ -131,6 +135,7 @@ broken() {
}
find "$appdir" \( -type f -o -type l \) -name '*.so*' -print0 >"$work/libs.list" || broken "cannot list $appdir"
find "$appdir" -type f -print0 >"$work/files.list" || broken "cannot list $appdir"
real=$(realpath "$appdir")
declare -A bundled=()
while IFS= read -r -d '' file; do
bundled[${file##*/}]=1
@@ -141,6 +146,36 @@ while IFS= read -r -d '' file; do
magic=$(head -c 4 "$file" | od -An -c | tr -d ' ') || broken "cannot read $file"
[ "$magic" = '177ELF' ] || continue
dynamic=$(readelf -dW "$file") || broken "readelf cannot read $file"
# Library paths resolve inside the package.
records=$(awk '/\((RUNPATH|RPATH)\)/ { n++ } END { print n + 0 }' <<<"$dynamic") || broken "cannot count paths of $file"
[ "$records" -le 1 ] || broken "${file#"$appdir"/} has $records library path records"
lines=()
if [ "$records" -eq 1 ]; then
# The raw string; readelf's text can hide a newline.
path=$(patchelf --print-rpath "$file" && printf x) || broken "patchelf cannot read $file"
path=${path%x}
path=${path%$'\n'}
[[ $path != *$'\n'* ]] || broken "${file#"$appdir"/} has a newline in its library path"
lines=("$path")
fi
entries=()
for line in "${lines[@]}"; do
# An empty entry searches the working directory.
[[ $line != :* && $line != *: && $line != *::* && -n $line ]] ||
broken "${file#"$appdir"/} searches the working directory: $line"
IFS=: read -r -a parts <<<"$line"
entries+=("${parts[@]}")
done
for path in "${entries[@]}"; do
case $path in
'$ORIGIN' | '$ORIGIN/'*) rest=${path#'$ORIGIN'} ;;
'${ORIGIN}' | '${ORIGIN}/'*) rest=${path#'${ORIGIN}'} ;;
*) broken "${file#"$appdir"/} loads from $path, not from \$ORIGIN" ;;
esac
target=$(realpath -m "$(dirname "$file")$rest") || broken "cannot resolve $path for $file"
[[ $target == "$real" || $target == "$real"/* ]] ||
broken "${file#"$appdir"/} loads from $path, outside the package"
done
while IFS= read -r lib; do
[ -n "${bundled[$lib]:-}" ] || needed+=("$lib")
done < <(sed -n 's/.*Shared library: \[\(.*\)\]/\1/p' <<<"$dynamic")