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:
1 parent
a9f8136e46
commit
5accf492ba
14 files changed
+124
-26
No files matched your search
@@ -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" "$@"
|
||||
@@ -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")
|
||||
|
||||
Reference in new issue
Block a user