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")
|
||||
|
||||
@@ -12,17 +12,7 @@ releases=https://git.zacharyzhang.com/ZacharyZhang-NY/ElyOffice/releases
|
||||
echo "release.sh: notarizing needs ELY_SIGN_IDENTITY, a Developer ID" >&2
|
||||
exit 1
|
||||
}
|
||||
# Our source as published: the committed tree.
|
||||
source=$dist/ElyOffice-$version-source.tar.gz
|
||||
mkdir -p "$dist"
|
||||
git -C "$root" archive --format=tar.gz --prefix="ElyOffice-$version/" -o "$source" HEAD
|
||||
echo "$source"
|
||||
# Copyleft upstream as shipped: patched MuPDF (AGPL), Git (GPLv2).
|
||||
upstream=$dist/ElyOffice-$version-upstream-source.tar.gz
|
||||
[ -f "$root/engines/mupdf-src/COPYING" ] || { echo "release.sh: no engines/mupdf-src; run the MuPDF build" >&2; exit 1; }
|
||||
tar -czf "$upstream" --exclude .git --exclude .DS_Store \
|
||||
-C "$root/engines" mupdf-src -C "$root/reference" git
|
||||
echo "$upstream"
|
||||
"$root/packaging/source.sh" "$dist"
|
||||
awk -F'\t' -v batch="$batch" '$4 == batch { print $1 "\t" $2 }' "$root/packaging/apps.tsv" |
|
||||
while IFS=$'\t' read -r slug name; do
|
||||
"$root/packaging/macos/bundle.sh" "$slug" release
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# Usage: source.sh <dist>; the source of what this commit builds.
|
||||
set -euo pipefail
|
||||
|
||||
root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
dist=${1:?the folder to write into}
|
||||
version=$(awk -F'"' '/^version = / { print $2; exit }' "$root/Cargo.toml")
|
||||
# Binaries match a commit only when the tree is clean.
|
||||
changed=$(git -C "$root" status --porcelain --untracked-files=all)
|
||||
[ -z "$changed" ] || {
|
||||
echo "source.sh: uncommitted changes; commit before a release:" >&2
|
||||
echo "$changed" >&2
|
||||
exit 1
|
||||
}
|
||||
commit=$(git -C "$root" rev-parse --short=12 HEAD)
|
||||
mkdir -p "$dist"
|
||||
# Our source as published: the committed tree.
|
||||
ours=$dist/ElyOffice-$version-$commit-source.tar.gz
|
||||
git -C "$root" archive --format=tar.gz --prefix="ElyOffice-$version/" -o "$ours" HEAD
|
||||
echo "$ours"
|
||||
# Copyleft upstream as shipped: patched MuPDF (AGPL), Git (GPLv2).
|
||||
upstream=$dist/ElyOffice-$version-$commit-upstream-source.tar.gz
|
||||
[ -f "$root/engines/mupdf-src/COPYING" ] || {
|
||||
echo "source.sh: no engines/mupdf-src; run scripts/build-mupdf.sh" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$root/reference/git/COPYING" ] || {
|
||||
echo "source.sh: no reference/git; run scripts/fetch-references.sh" >&2
|
||||
exit 1
|
||||
}
|
||||
tar -czf "$upstream" --exclude .git --exclude .DS_Store -C "$root/engines" mupdf-src -C "$root/reference" git
|
||||
echo "$upstream"
|
||||
Reference in new issue
Block a user