Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,34 @@ GIT_BRANCH="${GIT_BRANCH_OVERRIDE:-$GIT_BRANCH}"
BUILD_SCRIPT="$(mktemp)"
trap "rm -f -- '$BUILD_SCRIPT'" EXIT

cat <<EOF >"$BUILD_SCRIPT"
cat <<'EOF' >"$BUILD_SCRIPT"
set -xe
cd /ffbuild
rm -rf ffmpeg prefix
EOF

# Append the $ORIGIN rpath flags here rather than in scripts.d/99-rpath.sh, so
# the value never has to survive xargs, printf and Dockerfile ENV parsing.
#
# Both quotings below are needed:
# - the heredoc delimiter is quoted, so the host expands nothing
# - the appended fragment is single-quoted and *concatenated*, so the
# container's shell performs no substitution on it either
# Do not switch this to "${FF_LDEXEFLAGS//@PLACEHOLDER@/$var}" -- bash's pattern
# substitution eats a backslash from the replacement on some bash versions but
# not others, which silently costs one escaping level.
#
# configure must receive exactly -Wl,-rpath=\\\$\$ORIGIN because from there:
# configure's append() eval \\\$\$ORIGIN -> \$$ORIGIN (into config.mak)
# make expanding config.mak \$$ORIGIN -> \$ORIGIN
# the shell running the link \$ORIGIN -> $ORIGIN
if [[ $TARGET == linux* && $VARIANT == *shared* ]]; then
cat <<'EOF' >>"$BUILD_SCRIPT"
FF_LDEXEFLAGS="$FF_LDEXEFLAGS "'-Wl,-rpath=\\\$\$ORIGIN -Wl,-rpath=\\\$\$ORIGIN/../lib'
EOF
fi

cat <<EOF >>"$BUILD_SCRIPT"
git clone --filter=blob:none --branch='$GIT_BRANCH' '$FFMPEG_REPO' ffmpeg
cd ffmpeg

Expand All @@ -44,6 +67,19 @@ cat <<EOF >"$BUILD_SCRIPT"
make install install-doc
EOF

# A broken $ORIGIN rpath still builds and still runs anywhere ld.so.cache
# happens to know the libs, so it fails silently - so check and assert.
if [[ $TARGET == linux* && $VARIANT == *shared* ]]; then
cat <<'EOF' >>"$BUILD_SCRIPT"
readelf -d /ffbuild/prefix/bin/ffmpeg | grep -q ORIGIN || {
echo "ERROR: ffmpeg was linked without an \$ORIGIN rpath." >&2
echo " See the FF_LDEXEFLAGS rpath append earlier in build.sh." >&2
readelf -d /ffbuild/prefix/bin/ffmpeg | grep -i rpath >&2
exit 1
}
EOF
fi

[[ -t 1 ]] && TTY_ARG="-t" || TTY_ARG=""

docker run --rm -i $TTY_ARG "${UIDARGS[@]}" -v "$PWD/ffbuild":/ffbuild -v "$BUILD_SCRIPT":/build.sh "$IMAGE" bash /build.sh
Expand Down
15 changes: 10 additions & 5 deletions scripts.d/99-rpath.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ ffbuild_dockerbuild() {
ffbuild_ldexeflags() {
echo '-pie'

if [[ $VARIANT == *shared* ]]; then
# Can't escape escape hell
echo -Wl,-rpath='\\\\\\\$\\\$ORIGIN'
echo -Wl,-rpath='\\\\\\\$\\\$ORIGIN/../lib'
fi
# The $ORIGIN rpath flags for shared linux builds are deliberately NOT
# emitted here -- build.sh appends them inside the container instead.
#
# A literal $ORIGIN written here would have to survive, in order: xargs and
# printf in generate.sh, Dockerfile ENV parsing, ffmpeg configure's append()
# eval, make expanding config.mak, and finally the shell that runs the link.
# Each strips escapes and the required count is not stable: the xargs added
# in 281ab29 (2024-03-14) silently ate one level, and every linux shared
# build since has shipped RPATH "-Wl:../lib" instead of
# "$ORIGIN:$ORIGIN/../lib".
}
Loading