#!/bin/bash # After build.sh: the LGPL-only libvlc-all as org.videolan.android:libvlc-all:3.7.6-lgpl (without VLC's # Lua scripts, which are GPL and unused by NovArc), the licence files of every component built into # libVLC, and the complete corresponding source (LGPL-2.1 section 6). Output: $ROOT/out # Run in a throwaway container as root (the build user owns some folders), e.g. # docker run --rm -u 0 -v ~/builds/libvlc-lgpl:/build -e ROOT=/build registry.videolan.org/vlc-debian-android:20260610055743 bash /build/package.sh set -euo pipefail ROOT="${ROOT:-$HOME/builds/libvlc-lgpl}" [ -f /.dockerenv ] && git config --global --add safe.directory "*" OUT="$ROOT/out" SRC="$ROOT/vlc-android" VER=3.7.6-lgpl rm -rf "$OUT" && mkdir -p "$OUT/m2/org/videolan/android/libvlc-all/$VER" "$OUT/licenses" "$OUT/source" # 1. The package, without assets/lua, under its own version. python3 - "$ROOT/m2/org/videolan/android/libvlc-all/3.7.6" "$OUT/m2/org/videolan/android/libvlc-all/$VER" "$VER" <<'PY' import sys, zipfile, pathlib src, dst, ver = pathlib.Path(sys.argv[1]), pathlib.Path(sys.argv[2]), sys.argv[3] with zipfile.ZipFile(src / 'libvlc-all-3.7.6.aar') as zin, zipfile.ZipFile(dst / f'libvlc-all-{ver}.aar', 'w', zipfile.ZIP_DEFLATED) as zout: for info in zin.infolist(): if info.filename.startswith('assets/lua/'): continue zout.writestr(info, zin.read(info.filename)) pom = (src / 'libvlc-all-3.7.6.pom').read_text() pom = pom.replace('3.7.6', f'{ver}', 1) (dst / f'libvlc-all-{ver}.pom').write_text(pom) PY # 2. Licence files of every component VideoLAN's build compiled in (the contrib source trees, arm64; the # same set is built for every ABI). A package that keeps its terms in its README (libjpeg's "LEGAL # ISSUES") gets its README. One with nothing at all stops the packaging. CONTRIB="$SRC/libvlcjni/vlc/contrib/contrib-android-aarch64-linux-android" for dir in "$CONTRIB"/*/; do pkg=$(basename "$dir") # Build output, not a package. case "$pkg" in lib | bin | include | share) continue ;; esac files=$(find "$dir" -maxdepth 2 -type f \( -iname 'COPYING*' -o -iname 'LICENSE*' -o -iname 'LICENCE*' -o -iname 'COPYRIGHT*' -o -iname 'NOTICE*' -o -iname 'AUTHORS' \) | sort) [ -z "$files" ] && files=$(find "$dir" -maxdepth 1 -type f -iname 'README*' | sort) [ -z "$files" ] && { echo "no licence file in contrib $pkg"; exit 1; } mkdir -p "$OUT/licenses/$pkg" for f in $files; do cp "$f" "$OUT/licenses/$pkg/$(echo "${f#$dir}" | tr '/' '_')"; done done mkdir -p "$OUT/licenses/vlc" "$OUT/licenses/libvlcjni" "$OUT/licenses/libc++" "$OUT/licenses/hrtf" cp "$SRC/libvlcjni/vlc/COPYING.LIB" "$SRC/libvlcjni/vlc/COPYING" "$SRC/libvlcjni/vlc/AUTHORS" "$OUT/licenses/vlc/" cp "$SRC/libvlcjni/LICENSE" "$OUT/licenses/libvlcjni/LICENSE" cp "$SRC/libvlcjni/libvlc/COPYING.LIB" "$OUT/licenses/libvlcjni/COPYING.LIB" # The NDK's C++ library (libc++_shared.so), LLVM's licence. cp "$ROOT/extra-licenses/libc++-LICENSE.TXT" "$OUT/licenses/libc++/LICENSE.TXT" # The spatial audio filter's data file (assets/hrtfs), whose notice is inside it. strings -n 20 "$SRC/libvlcjni/vlc/share/hrtfs/dodeca_and_7channel_3DSL_HRTF.sofa" | sed -n '/Copyright/,/Boston\|www.gnu.org/p' > "$OUT/licenses/hrtf/NOTICE" [ -s "$OUT/licenses/hrtf/NOTICE" ] || { echo "no HRTF notice"; exit 1; } cp "$SRC/libvlcjni/vlc/COPYING.LIB" "$OUT/licenses/hrtf/COPYING.LIB" # Which version of each component (from the source tarballs it was built from). ls "$SRC/libvlcjni/vlc/contrib/tarballs" > "$OUT/licenses/TARBALLS.txt" # 3. The complete corresponding source: vlc-android at its tag, libvlcjni and VLC at the exact commits, # the contrib source tarballs (in two archives: each object in the download bucket is at most 300 MiB), # NovArc's one change to the build script, and the build commands. git -C "$SRC" archive --format=tar --prefix=vlc-android/ HEAD | xz -T4 > "$OUT/source/vlc-android-libvlc-3.7.6.tar.xz" git -C "$SRC/libvlcjni" archive --format=tar --prefix=libvlcjni/ HEAD | xz -T4 > "$OUT/source/libvlcjni-$(git -C "$SRC/libvlcjni" rev-parse --short HEAD).tar.xz" git -C "$SRC/libvlcjni/vlc" archive --format=tar --prefix=vlc/ HEAD | xz -T4 > "$OUT/source/vlc-$(git -C "$SRC/libvlcjni/vlc" rev-parse --short HEAD).tar.xz" ( cd "$SRC/libvlcjni/vlc/contrib" ls -S tarballs > /tmp/all : > /tmp/p1; : > /tmp/p2; s1=0; s2=0 while read -r f; do sz=$(stat -c %s "tarballs/$f") if [ "$s1" -le "$s2" ]; then echo "tarballs/$f" >> /tmp/p1; s1=$((s1 + sz)); else echo "tarballs/$f" >> /tmp/p2; s2=$((s2 + sz)); fi done < /tmp/all tar -cf - -T /tmp/p1 | xz -T4 > "$OUT/source/vlc-contrib-tarballs.part1.tar.xz" tar -cf - -T /tmp/p2 | xz -T4 > "$OUT/source/vlc-contrib-tarballs.part2.tar.xz" ) cp "$ROOT/libvlcjni-novarc.patch" "$ROOT/patch-blacklist.sh" "$ROOT/license-audit.py" "$ROOT/build.sh" "$ROOT/package.sh" "$OUT/source/" { echo "libVLC for NovArc IPTV Player (Android), LGPL-only build" echo echo "vlc-android: $(git -C "$SRC" describe --tags) $(git -C "$SRC" rev-parse HEAD)" echo "libvlcjni: $(git -C "$SRC/libvlcjni" rev-parse HEAD)" echo "vlc: $(git -C "$SRC/libvlcjni/vlc" rev-parse HEAD)" echo "Images: registry.videolan.org/vlc-debian-android:20260610055743 (arm64, x86_64)" echo " registry.videolan.org/vlc-debian-android-3.0:20260701183656 (armeabi-v7a, x86)" echo echo "How it's built (build.sh does all of it):" echo " - VideoLAN's own build: vlc-android's buildsystem/compile.sh -l -a -m2 release --license a" echo " (VLC's contribs built from these source tarballs in their LGPLv2 + ad-clauses mode), then" echo " GRADLE_ABI=ALL ./gradlew -p libvlcjni publishToMavenLocal." echo " - NovArc's one change (libvlcjni-novarc.patch, made by patch-blacklist.sh): 16 VLC modules whose source" echo " is GPL rather than LGPL are added to the module list VideoLAN's script already leaves out: lua," echo " access_realrtsp, headphone_channel_mixer, mono, dummy, file_logger, syslog, vod_rtsp, stream_out_rtp," echo " stream_out_cycle, dolby_surround_decoder, hqdn3d, rotate, deinterlace, i420_rgb_mmx, zvbi." echo " license-audit.py lists the licence of every VLC source file and header compiled into a build (from" echo " the build's dependency files): none is GPL in this one." echo " VLC's and the components' own source is unchanged." echo " - package.sh: assets/lua/ (VLC's GPL Lua scripts) removed from the AAR; version 3.7.6-lgpl." echo echo "To rebuild (or build your own libvlc.so to replace the app's):" echo " 1. Extract vlc-android-libvlc-3.7.6.tar.xz here (vlc-android/), libvlcjni-*.tar.xz into" echo " vlc-android/ (vlc-android/libvlcjni/), vlc-*.tar.xz into vlc-android/libvlcjni/ (…/libvlcjni/vlc/)," echo " and both vlc-contrib-tarballs.part*.tar.xz into vlc-android/libvlcjni/vlc/contrib/ (they hold" echo " contrib/tarballs/, so no download is needed)." echo " 2. Make each tree a git repository (git init; git add -A; git commit -m src) — VideoLAN's scripts" echo " expect them — and apply libvlcjni-novarc.patch in vlc-android/libvlcjni (git apply)." echo " 3. Run build.sh (Docker with the images above): it builds the four ABIs and publishes the AAR." } > "$OUT/source/README.txt" (cd "$OUT" && find m2 -type f -exec sha256sum {} \; > SHA256SUMS && sha256sum source/* >> SHA256SUMS) chmod -R a+rwX "$OUT" du -sh "$OUT"/* | sort -h