diff --git a/.github/workflows/descript-build.yml b/.github/workflows/descript-build.yml new file mode 100644 index 00000000..b2375742 --- /dev/null +++ b/.github/workflows/descript-build.yml @@ -0,0 +1,27 @@ +name: build shared-libs for Descript + +on: + push: + paths-ignore: + - '*.md' + pull_request: + branches: + - charles/arm64 + - sk/ffmpeg-4.4-arm64 + +jobs: + build-macos-shared: + name: ffmpeg-ffprobe-shared-darwin + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: 3.8 #install the python needed + + - name: build-ffmpeg-descript.py + run: | + python ./descript/build-ffmpeg-descript.py diff --git a/.gitignore b/.gitignore index 4725dcff..e2053e2a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ workspace .idea linux .artifacts +.DS_Store diff --git a/build-ffmpeg b/build-ffmpeg index 1839e4c0..b3e86363 100755 --- a/build-ffmpeg +++ b/build-ffmpeg @@ -5,7 +5,7 @@ PROGNAME=$(basename "$0") FFMPEG_VERSION=4.4 -SCRIPT_VERSION=1.33 +SCRIPT_VERSION=1.40.rc.1 CWD=$(pwd) PACKAGES="$CWD/packages" WORKSPACE="$CWD/workspace" @@ -17,6 +17,8 @@ MACOS_M1=false CONFIGURE_OPTIONS=() NONFREE_AND_GPL=false LATEST=false +SHARED_LIBRARIES=false +FREE_AND_GPL=false # Check for Apple Silicon if [[ ("$(uname -m)" == "arm64") && ("$OSTYPE" == "darwin"*) ]]; then @@ -207,6 +209,8 @@ usage() { echo " --latest Build latest version of dependencies if newer available" echo " --full-static Build a full static FFmpeg binary (eg. glibc, pthreads etc...) **only Linux**" echo " Note: Because of the NSS (Name Service Switch), glibc does not recommend static links." + echo " --full-shared Build all shared libraries. Cannot be used with --full-static" + echo " --enable-gpl-and-free Enable GPL but not non-free codecs. Cannot be used with --enable-gpl-and-non-free - https://ffmpeg.org/legal.html" echo "" } @@ -247,6 +251,13 @@ while (($# > 0)); do if [[ "$1" == "--latest" ]]; then LATEST=true fi + if [[ "$1" == "--full-shared" ]]; then + SHARED_LIBRARIES=true + fi + if [[ "$1" == "--enable-gpl-and-free" ]]; then + CONFIGURE_OPTIONS+=("--enable-gpl") + FREE_AND_GPL=true + fi shift ;; *) @@ -264,6 +275,16 @@ if [ -z "$bflag" ]; then exit 0 fi +if [[ ($SHARED_LIBRARIES == true) && ($LDEXEFLAGS == true) ]]; then + usage + exit 1 +fi + +if [[ ($NONFREE_AND_GPL == true) && ($FREE_AND_GPL == true) ]]; then + usage + exit 1 +fi + echo "Using $MJOBS make jobs simultaneously." if $NONFREE_AND_GPL; then @@ -274,6 +295,14 @@ if [ -n "$LDEXEFLAGS" ]; then echo "Start the build in full static mode." fi +if $SHARED_LIBRARIES; then + echo "Building shared libraries." +fi + +if $FREE_AND_GPL; then + echo "GPL and free codecs" +fi + mkdir -p "$PACKAGES" mkdir -p "$WORKSPACE" @@ -315,7 +344,10 @@ if build "giflib" "5.2.1"; then download "https://sourceforge.net/p/giflib/bugs/_discuss/thread/4e811ad29b/c323/attachment/Makefile.patch" execute patch "${PACKAGES}/giflib-5.2.1/Makefile" ${PACKAGES}/Makefile.patch"" fi - execute make -j $MJOBS + # Descript: compilation will fail with more than 8 jobs, so + # force to not run in parallel + #execute make -j $MJOBS + execute make execute make PREFIX="${WORKSPACE}" install build_done "giflib" "5.2.1" fi @@ -338,18 +370,26 @@ fi if build "nasm" "2.15.05"; then download "https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.xz" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + fi execute make -j $MJOBS execute make install build_done "nasm" "2.15.05" fi -if build "zlib" "1.2.11"; then - download "https://www.zlib.net/zlib-1.2.11.tar.gz" - execute ./configure --static --prefix="${WORKSPACE}" +if build "zlib" "1.3"; then + download "https://www.zlib.net/zlib-1.3.tar.gz" + if $SHARED_LIBRARIES; then + execute ./configure --shared --prefix="${WORKSPACE}" + else + execute ./configure --static --prefix="${WORKSPACE}" + fi execute make -j $MJOBS execute make install - build_done "zlib" "1.2.11" + build_done "zlib" "1.3" fi if build "m4" "1.4.19"; then @@ -378,7 +418,11 @@ fi if build "libtool" "2.4.6"; then download "https://ftpmirror.gnu.org/libtool/libtool-2.4.6.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --enable-static --disable-shared + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --disable-static --enable-shared + else + execute ./configure --prefix="${WORKSPACE}" --enable-static --disable-shared + fi execute make -j $MJOBS execute make install build_done "libtool" "2.4.6" @@ -427,12 +471,26 @@ if command_exists "python3"; then if build "dav1d" "0.9.2"; then download "https://code.videolan.org/videolan/dav1d/-/archive/0.9.2/dav1d-0.9.2.tar.gz" make_dir build - execute meson build --prefix="${WORKSPACE}" --buildtype=release --default-library=static --libdir="${WORKSPACE}"/lib + # [ Descript - cvanwink ] + # Set extra CFLAGS for arm64 + # https://github.com/markus-perl/ffmpeg-build-script/issues/115 + if $MACOS_M1; then + export CFLAGS="-arch arm64" + fi + if $SHARED_LIBRARIES; then + execute meson build --prefix="${WORKSPACE}" --buildtype=release --default-library=shared --libdir="${WORKSPACE}"/lib + else + execute meson build --prefix="${WORKSPACE}" --buildtype=release --default-library=static --libdir="${WORKSPACE}"/lib + fi execute ninja -C build execute ninja -C build install + # [ Descript - cvanwink ] + # Restore default CFLAGS from line 12 + if $MACOS_M1; then + CFLAGS="-I$WORKSPACE/include" + fi build_done "dav1d" "0.9.2" fi - CONFIGURE_OPTIONS+=("--enable-libdav1d") fi fi @@ -442,7 +500,11 @@ if ! $MACOS_M1; then # Last known working commit which passed CI Tests from HEAD branch download "https://gitlab.com/AOMediaCodec/SVT-AV1/-/archive/1a3e32b8fdc4abf5c093ee01dfa82803afc75fb4/SVT-AV1-1a3e32b8fdc4abf5c093ee01dfa82803afc75fb4.tar.gz" "svtav1-1a3e32b.tar.gz" cd "${PACKAGES}"/svtav1-1a3e32b/Build/linux || exit - execute cmake -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=off -DBUILD_SHARED_LIBS=OFF ../.. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release + if $SHARED_LIBRARIES; then + execute cmake -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=on -DBUILD_SHARED_LIBS=ON ../.. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release + else + execute cmake -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=off -DBUILD_SHARED_LIBS=OFF ../.. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release + fi execute make -j $MJOBS execute make install execute cp SvtAv1Enc.pc "${WORKSPACE}/lib/pkgconfig/" @@ -453,60 +515,76 @@ if ! $MACOS_M1; then fi if command_exists "cargo"; then - if build "rav1e" "0.5.0-beta"; then + if build "rav1e" "0.6.6"; then execute cargo install cargo-c - download "https://github.com/xiph/rav1e/archive/refs/tags/v0.5.0-beta.tar.gz" + download "https://github.com/xiph/rav1e/archive/refs/tags/v0.6.6.tar.gz" execute cargo cinstall --prefix="${WORKSPACE}" --library-type=staticlib --crt-static --release - build_done "rav1e" "0.5.0-beta" + build_done "rav1e" "0.6.6" fi CONFIGURE_OPTIONS+=("--enable-librav1e") fi -if $NONFREE_AND_GPL; then +if $NONFREE_AND_GPL || $FREE_AND_GPL; then if build "x264" "5db6aa6"; then download "https://code.videolan.org/videolan/x264/-/archive/5db6aa6cab1b146e07b60cc1736a01f21da01154/x264-5db6aa6cab1b146e07b60cc1736a01f21da01154.tar.gz" "x264-5db6aa6.tar.gz" cd "${PACKAGES}"/x264-5db6aa6 || exit if [[ "$OSTYPE" == "linux-gnu" ]]; then - execute ./configure --prefix="${WORKSPACE}" --enable-static --enable-pic CXXFLAGS="-fPIC" + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --enable-pic CXXFLAGS="-fPIC" + else + execute ./configure --prefix="${WORKSPACE}" --enable-static --enable-pic CXXFLAGS="-fPIC" + fi else - execute ./configure --prefix="${WORKSPACE}" --enable-static --enable-pic + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --enable-pic + else + execute ./configure --prefix="${WORKSPACE}" --enable-static --enable-pic + fi fi execute make -j $MJOBS execute make install - execute make install-lib-static + if $SHARED_LIBRARIES; then + execute make install-lib-shared + else + execute make install-lib-static + fi build_done "x264" "5db6aa6" fi CONFIGURE_OPTIONS+=("--enable-libx264") fi -if $NONFREE_AND_GPL; then +if $NONFREE_AND_GPL || $FREE_AND_GPL; then if build "x265" "3.5"; then download "https://github.com/videolan/x265/archive/Release_3.5.tar.gz" "x265-3.5.tar.gz" # This is actually 3.4 if looking at x265Version.txt cd build/linux || exit - rm -rf 8bit 10bit 12bit 2>/dev/null - mkdir -p 8bit 10bit 12bit - cd 12bit || exit - execute cmake ../../../source -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=OFF -DBUILD_SHARED_LIBS=OFF -DHIGH_BIT_DEPTH=ON -DENABLE_HDR10_PLUS=ON -DEXPORT_C_API=OFF -DENABLE_CLI=OFF -DMAIN12=ON - execute make -j $MJOBS - cd ../10bit || exit - execute cmake ../../../source -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=OFF -DBUILD_SHARED_LIBS=OFF -DHIGH_BIT_DEPTH=ON -DENABLE_HDR10_PLUS=ON -DEXPORT_C_API=OFF -DENABLE_CLI=OFF - execute make -j $MJOBS - cd ../8bit || exit - ln -sf ../10bit/libx265.a libx265_main10.a - ln -sf ../12bit/libx265.a libx265_main12.a - execute cmake ../../../source -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=OFF -DBUILD_SHARED_LIBS=OFF -DEXTRA_LIB="x265_main10.a;x265_main12.a;-ldl" -DEXTRA_LINK_FLAGS=-L. -DLINKED_10BIT=ON -DLINKED_12BIT=ON - execute make -j $MJOBS - - mv libx265.a libx265_main.a - - if [[ "$OSTYPE" == "darwin"* ]]; then - execute "${MACOS_LIBTOOL}" -static -o libx265.a libx265_main.a libx265_main10.a libx265_main12.a 2>/dev/null + if $SHARED_LIBRARIES; then + execute cmake -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=on -DBUILD_SHARED_LIBS=on ../../source + execute make -j $MJOBS else - execute ar -M </dev/null + mkdir -p 8bit 10bit 12bit + cd 12bit || exit + execute cmake ../../../source -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=OFF -DBUILD_SHARED_LIBS=OFF -DHIGH_BIT_DEPTH=ON -DENABLE_HDR10_PLUS=ON -DEXPORT_C_API=OFF -DENABLE_CLI=OFF -DMAIN12=ON + execute make -j $MJOBS + cd ../10bit || exit + execute cmake ../../../source -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=OFF -DBUILD_SHARED_LIBS=OFF -DHIGH_BIT_DEPTH=ON -DENABLE_HDR10_PLUS=ON -DEXPORT_C_API=OFF -DENABLE_CLI=OFF + execute make -j $MJOBS + cd ../8bit || exit + ln -sf ../10bit/libx265.a libx265_main10.a + ln -sf ../12bit/libx265.a libx265_main12.a + execute cmake ../../../source -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DENABLE_SHARED=OFF -DBUILD_SHARED_LIBS=OFF -DEXTRA_LIB="x265_main10.a;x265_main12.a;-ldl" -DEXTRA_LINK_FLAGS=-L. -DLINKED_10BIT=ON -DLINKED_12BIT=ON + execute make -j $MJOBS + + mv libx265.a libx265_main.a + + if [[ "$OSTYPE" == "darwin"* ]]; then + execute "${MACOS_LIBTOOL}" -static -o libx265.a libx265_main.a libx265_main10.a libx265_main12.a 2>/dev/null + else + execute ar -M <build/make/Makefile.patched - sed "s/-Wl,--no-undefined -Wl,-soname/-Wl,-undefined,error -Wl,-install_name/g" build/make/Makefile.patched >build/make/Makefile - fi + if [[ "$OSTYPE" == "darwin"* ]]; then + echo "Applying Darwin patch" + sed "s/,--version-script//g" build/make/Makefile >build/make/Makefile.patched + sed "s/-Wl,--no-undefined -Wl,-soname/-Wl,-undefined,error -Wl,-install_name/g" build/make/Makefile.patched >build/make/Makefile + fi - execute ./configure --prefix="${WORKSPACE}" --disable-unit-tests --disable-shared --as=yasm --enable-vp9-highbitdepth - execute make -j $MJOBS - execute make install + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --disable-unit-tests --enable-shared --disable-static --as=yasm --enable-vp9-highbitdepth + else + execute ./configure --prefix="${WORKSPACE}" --disable-unit-tests --disable-shared --as=yasm --enable-vp9-highbitdepth + fi + execute make -j $MJOBS + execute make install - build_done "libvpx" "1.10.0" + build_done "libvpx" "1.10.0" + fi + CONFIGURE_OPTIONS+=("--enable-libvpx") fi -CONFIGURE_OPTIONS+=("--enable-libvpx") -if $NONFREE_AND_GPL; then +if $NONFREE_AND_GPL || $FREE_AND_GPL; then if build "xvidcore" "1.3.7"; then download "https://downloads.xvid.com/downloads/xvidcore-1.3.7.tar.gz" cd build/generic || exit - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + fi execute make -j $MJOBS execute make install @@ -574,7 +665,11 @@ if $NONFREE_AND_GPL; then patch -p1 include/libmp3lame.sym.patched + mv include/libmp3lame.sym.patched include/libmp3lame.sym + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + fi execute make -j $MJOBS execute make install @@ -700,7 +838,11 @@ CONFIGURE_OPTIONS+=("--enable-libmp3lame") if build "opus" "1.3.1"; then download "https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + fi execute make -j $MJOBS execute make install @@ -710,19 +852,31 @@ CONFIGURE_OPTIONS+=("--enable-libopus") if build "libogg" "1.3.3"; then download "https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.3.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + fi execute make -j $MJOBS execute make install build_done "libogg" "1.3.3" fi -if build "libvorbis" "1.3.6"; then - download "https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.6.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --enable-static --disable-shared --disable-oggtest +if build "libvorbis" "1.3.7"; then + download "https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.7.tar.gz" + echo $PWD + + patch configure.ac ${CWD%/descript}/vorbis.config.patch + ./autogen.sh + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --disable-static --enable-shared --disable-oggtest + else + execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --enable-static --disable-shared --disable-oggtest + fi execute make -j $MJOBS execute make install - build_done "libvorbis" "1.3.6" + build_done "libvorbis" "1.3.7" fi CONFIGURE_OPTIONS+=("--enable-libvorbis") @@ -731,10 +885,25 @@ if build "libtheora" "1.1.1"; then sed "s/-fforce-addr//g" configure >configure.patched chmod +x configure.patched mv configure.patched configure - execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --with-vorbis-libraries="${WORKSPACE}"/lib --with-vorbis-includes="${WORKSPACE}"/include/ --enable-static --disable-shared --disable-oggtest --disable-vorbistest --disable-examples --disable-asm --disable-spec + if $SHARED_LIBRARIES; then + if $MACOS_M1; then + # fix Libtool bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63610 + export MACOSX_DEPLOYMENT_TARGET=10.11 + fi + execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --with-vorbis-libraries="${WORKSPACE}"/lib --with-vorbis-includes="${WORKSPACE}"/include/ --disable-static --enable-shared --disable-oggtest --disable-vorbistest --disable-examples --disable-asm --disable-spec + else + execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --with-vorbis-libraries="${WORKSPACE}"/lib --with-vorbis-includes="${WORKSPACE}"/include/ --enable-static --disable-shared --disable-oggtest --disable-vorbistest --disable-examples --disable-asm --disable-spec + fi execute make -j $MJOBS execute make install + if $SHARED_LIBRARIES; then + if $MACOS_M1; then + # restore from Line 26 + export MACOSX_DEPLOYMENT_TARGET=11.0 + fi + fi + build_done "libtheora" "1.1.1" fi CONFIGURE_OPTIONS+=("--enable-libtheora") @@ -742,7 +911,11 @@ CONFIGURE_OPTIONS+=("--enable-libtheora") if $NONFREE_AND_GPL; then if build "fdk_aac" "2.0.2"; then download "https://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-2.0.2.tar.gz/download?use_mirror=gigenet" "fdk-aac-2.0.2.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static --enable-pic + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static --enable-pic + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static --enable-pic + fi execute make -j $MJOBS execute make install @@ -757,7 +930,11 @@ fi if build "libtiff" "4.2.0"; then download "https://download.osgeo.org/libtiff/tiff-4.2.0.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static --disable-dependency-tracking --disable-lzma --disable-webp --disable-zstd --without-x + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static --disable-dependency-tracking --disable-lzma --disable-webp --disable-zstd --without-x + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static --disable-dependency-tracking --disable-lzma --disable-webp --disable-zstd --without-x + fi execute make -j $MJOBS execute make install build_done "libtiff" "4.2.0" @@ -766,40 +943,45 @@ if build "libpng" "1.6.37"; then download "https://sourceforge.net/projects/libpng/files/libpng16/1.6.37/libpng-1.6.37.tar.gz/download?use_mirror=gigenet" "libpng-1.6.37.tar.gz" export LDFLAGS="${LDFLAGS}" export CPPFLAGS="${CFLAGS}" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + fi execute make -j $MJOBS execute make install build_done "libpng" "1.6.37" fi -## does not compile on monterey -> _PrintGifError -if [[ "$OSTYPE" != "darwin"* ]]; then - if build "libwebp" "1.2.1"; then - # libwebp can fail to compile on Ubuntu if these flags were left set to CFLAGS - CPPFLAGS= - download "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.2.1.tar.gz" "libwebp-1.2.1.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static --disable-dependency-tracking --disable-gl --with-zlib-include="${WORKSPACE}"/include/ --with-zlib-lib="${WORKSPACE}"/lib - make_dir build - cd build || exit - execute cmake -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_BINDIR=bin -DCMAKE_INSTALL_INCLUDEDIR=include -DENABLE_SHARED=OFF -DENABLE_STATIC=ON ../ - execute make -j $MJOBS - execute make install +if build "libwebp" "1.2.1"; then + # libwebp can fail to compile on Ubuntu if these flags were left set to CFLAGS + CPPFLAGS= + download "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.2.1.tar.gz" "libwebp-1.2.1.tar.gz" + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static --disable-dependency-tracking --disable-gl --with-zlib-include="${WORKSPACE}"/include/ --with-zlib-lib="${WORKSPACE}"/lib + make_dir build + cd build || exit + execute cmake -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_BINDIR=bin -DCMAKE_INSTALL_INCLUDEDIR=include -DENABLE_SHARED=OFF -DENABLE_STATIC=ON ../ + execute make -j $MJOBS + execute make install - build_done "libwebp" "1.2.1" - fi - CONFIGURE_OPTIONS+=("--enable-libwebp") + build_done "libwebp" "1.2.1" fi +CONFIGURE_OPTIONS+=("--enable-libwebp") ## ## other library ## -if build "libsdl" "2.0.14"; then - download "https://www.libsdl.org/release/SDL2-2.0.14.tar.gz" - execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static +if build "libsdl" "2.28.5"; then + download "https://www.libsdl.org/release/SDL2-2.28.5.tar.gz" + if $SHARED_LIBRARIES; then + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + else + execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static + fi execute make -j $MJOBS execute make install - build_done "libsdl" "2.0.14" + build_done "libsdl" "2.28.5" fi if $NONFREE_AND_GPL; then @@ -808,7 +990,11 @@ if $NONFREE_AND_GPL; then export OPENSSL_ROOT_DIR="${WORKSPACE}" export OPENSSL_LIB_DIR="${WORKSPACE}"/lib export OPENSSL_INCLUDE_DIR="${WORKSPACE}"/include/ - execute cmake . -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_BINDIR=bin -DCMAKE_INSTALL_INCLUDEDIR=include -DENABLE_SHARED=OFF -DENABLE_STATIC=ON -DENABLE_APPS=OFF -DUSE_STATIC_LIBSTDCXX=ON + if $SHARED_LIBRARIES; then + execute cmake . -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_BINDIR=bin -DCMAKE_INSTALL_INCLUDEDIR=include -DENABLE_SHARED=ON -DENABLE_STATIC=OFF -DENABLE_APPS=OFF -DUSE_STATIC_LIBSTDCXX=ON + else + execute cmake . -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_BINDIR=bin -DCMAKE_INSTALL_INCLUDEDIR=include -DENABLE_SHARED=OFF -DENABLE_STATIC=ON -DENABLE_APPS=OFF -DUSE_STATIC_LIBSTDCXX=ON + fi execute make install if [ -n "$LDEXEFLAGS" ]; then @@ -865,6 +1051,105 @@ if [[ "$OSTYPE" == "linux-gnu" ]]; then CONFIGURE_OPTIONS+=("--enable-amf") fi + +## +## Descript Additions +## + +if $SHARED_LIBRARIES; then + if build "twolame" "0.4.0"; then + download "https://downloads.sourceforge.net/twolame/twolame-0.4.0.tar.gz" + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + execute make -j $MJOBS + execute make install + + build_done "twolame" "0.4.0" + fi + CONFIGURE_OPTIONS+=("--enable-libtwolame") + + + if build "shine" "3.1.1"; then + download "https://github.com/toots/shine/archive/3.1.1.tar.gz" "shine-3.1.1.tar.gz" + execute autoreconf -i + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + execute make -j $MJOBS + execute make install + + build_done "shine" "3.1.1" + fi + CONFIGURE_OPTIONS+=("--enable-libshine") + + + if build "soxr" "0.1.3"; then + download "http://ftp.debian.org/debian/pool/main/libs/libsoxr/libsoxr_0.1.3.orig.tar.xz" "soxr-0.1.3.tar.xz" + make_dir build + cd build || exit + if [[ "$OSTYPE" == "darwin"* ]]; then + download "https://raw.githubusercontent.com/macports/macports-ports/master/audio/soxr/files/patch-pffft.c.diff" "patch-pffft.c.diff" + execute patch "${PACKAGES}/soxr-0.1.3/src/pffft.c" ${PACKAGES}/patch-pffft.c.diff"" + fi + execute cmake .. -DWITH_OPENMP:BOOL=OFF -Wno-dev -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS:BOOL=ON + execute make -j $MJOBS + execute make install + + build_done "soxr" "0.1.3" + fi + CONFIGURE_OPTIONS+=("--enable-libsoxr") + + + if build "speex" "1.2.0"; then + download "http://downloads.us.xiph.org/releases/speex/speex-1.2.0.tar.gz" + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + execute make -j $MJOBS + execute make install + + build_done "speex" "1.2.0" + fi + CONFIGURE_OPTIONS+=("--enable-libspeex") + + + if build "openjpeg" "2.3.1"; then + download "https://github.com/uclouvain/openjpeg/archive/v2.3.1.tar.gz" "openjpeg-v2.3.1.tar.gz" + make_dir build + cd build || exit + execute cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DBUILD_SHARED_LIBS:bool=on + execute make -j $MJOBS + execute make install + + build_done "openjpeg" "2.3.1" + fi + CONFIGURE_OPTIONS+=("--enable-libopenjpeg") + + + if build "snappy" "1.1.8"; then + download "https://github.com/google/snappy/archive/1.1.8.tar.gz" + make_dir build + cd build || exit + execute cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${WORKSPACE}" -DBUILD_SHARED_LIBS:bool=on + execute make -j $MJOBS + + #if [[ "$OSTYPE" == "darwin"* ]]; then + # execute install_name_tool -id "${WORKSPACE}/lib/libsnappy.1.dylib" libsnappy.1.dylib + #fi + + execute make install + + build_done "snappy" "1.1.8" + fi + CONFIGURE_OPTIONS+=("--enable-libsnappy") + + + if build "xz" "5.2.5"; then + download "https://tukaani.org/xz/xz-5.2.5.tar.gz" + execute ./configure --prefix="${WORKSPACE}" --enable-shared --disable-static + execute make -j $MJOBS + execute make install + + build_done "xz" "5.2.5" + fi + +fi + ## ## FFmpeg ## @@ -877,6 +1162,23 @@ fi build "ffmpeg" "$FFMPEG_VERSION" download "https://github.com/FFmpeg/FFmpeg/archive/refs/heads/release/$FFMPEG_VERSION.tar.gz" "FFmpeg-release-$FFMPEG_VERSION.tar.gz" # shellcheck disable=SC2086 +if $SHARED_LIBRARIES; then +./configure "${CONFIGURE_OPTIONS[@]}" \ + --disable-debug \ + --disable-doc \ + --disable-static \ + --enable-pthreads \ + --enable-shared\ + --enable-version3 \ + --extra-cflags="${CFLAGS}" \ + --extra-ldexeflags="${LDEXEFLAGS}" \ + --extra-ldflags="${LDFLAGS}" \ + --extra-libs="${EXTRALIBS}" \ + --pkgconfigdir="$WORKSPACE/lib/pkgconfig" \ + --pkg-config-flags="--static" \ + --prefix="${WORKSPACE}" \ + --extra-version="${EXTRA_VERSION}" +else ./configure "${CONFIGURE_OPTIONS[@]}" \ --disable-debug \ --disable-doc \ @@ -893,6 +1195,7 @@ download "https://github.com/FFmpeg/FFmpeg/archive/refs/heads/release/$FFMPEG_VE --pkg-config-flags="--static" \ --prefix="${WORKSPACE}" \ --extra-version="${EXTRA_VERSION}" +fi execute make -j $MJOBS execute make install diff --git a/descript/.gitignore b/descript/.gitignore new file mode 100644 index 00000000..28757cf4 --- /dev/null +++ b/descript/.gitignore @@ -0,0 +1 @@ +mac \ No newline at end of file diff --git a/descript/README.md b/descript/README.md new file mode 100644 index 00000000..66f919f7 --- /dev/null +++ b/descript/README.md @@ -0,0 +1,96 @@ +![](../ffmpeg-build-script.png) + +# Build FFmpeg for Descript + +## Author / Contact: + - [Charles Van Winkle](https://github.com/cvanwinkle) + - [Steve Rubin](https://github.com/srubin) + +## Instructions +- Run `build-ffmpeg-descript.py` + + +## Build Overview +The build script automates the following basic operations. +- Creates a log file to archive the compiler/linker and packaging steps +- Runs the modified `buildFFmpeg` shell script, outputs to log file +- Recursively generates or copies `.dSYM` symbol files for each dependency into a `.zip` file + - Also fixes `dlyd` loader paths for each dependency +- Checks that each executable (i.e. `ffmpeg` & `ffprobe`) are runnable +- Copies `includes` header folder +- Checks for any linked dependencies which are linked to locations on the build machine and not present in the archive bundle +- Archives the upstream tar bundles for each `ffmpeg` component + - This is important in case upstream FTP or source servers go offline in the future +- Generates checksum for each created artifact (build, symbols, packages, log) + +## Development +Known issues: +- CI can only build `x86_64` and doesn't yet cross-compile to `arm64` +- When running on CI, there's libraries linked from `/usr/local/opt/...` which are non-portable + - Watch the script output at the end for warnings about this. These could turn into errors later. + +## Patches +- The build-ffmpeg shell script is modified directly to allow for + - building shared libraries + - disable non-free codecs + - add additional codecs that Descript uses + +## Deployment / Releases +- Currently, the script is run manually on a developer's machine + - once for each platform (`x86_64` and `arm64`) +- Build artifacts (`*.zip` files) are manually uploaded to a GitHub release and tagged +- `SHAMSUM256.txt` files need to be merged between the two platforms when adding to a release. + +## Clients +- This build is consumed by Descript's Beamcoder fork + - https://github.com/descriptinc/beamcoder + +## Previous Documentation of targeted differences (prior to `arm64` port) +- ❌ don't need +- ✅ already in ffmpeg-build-script build +- 🕒 need to add to ffmpeg-build-script + +Target (`evermeet.cx` static build) +- `--cc=/usr/bin/clang` +- `--prefix=/opt/ffmpeg` +- `--extra-version=tessus` +- ❌ `--enable-avisynth` - non-linear editing +- ❌ `--enable-fontconfig` +- ✅ `--enable-gpl` +- ✅ `--enable-libaom` +- ❌ `--enable-libass` +- ❌ `--enable-libbluray` - bluray playback +- 🕒✅ `--enable-libdav1d` +- ❌ `--enable-libfreetype` - text rendering +- ❌ `--enable-libgsm` - GSM audio +- ❌ `--enable-libmodplug` - midi/instrument support (https://github.com/Konstanty/libmodplug) +- ✅ `--enable-libmp3lame` +- ❌ `--enable-libmysofa` - spatial audio +- ✅ `--enable-libopencore-amrnb` +- ✅ `--enable-libopencore-amrwb` +- 🕒✅ `--enable-libopenh264` +- 🕒✅ `--enable-libopenjpeg` +- ✅ `--enable-libopus` +- ❌ `--enable-librubberband` - time stretching +- 🕒✅ `--enable-libshine` - mp3 encoder +- 🕒✅ `--enable-libsnappy` - compression/decompression +- 🕒✅ `--enable-libsoxr` - resampling +- 🕒✅ `--enable-libspeex` - speex audio file format +- ✅ `--enable-libtheora` +- 🕒✅ `--enable-libtwolame` - mpeg2 +- ✅ `--enable-libvidstab` +- ❌ `--enable-libvmaf` - perceptual video quality metric +- ❌ `--enable-libvo-amrwbenc` - VisualOn AMR-WB encoder library +- ✅ `--enable-libvorbis` +- ✅ `--enable-libvpx` +- ✅ `--enable-libwebp` +- ✅ `--enable-libx264` +- ✅ `--enable-libx265` +- ❌ `--enable-libxavs` - AV standard of China +- ✅ `--enable-libxvid` +- 🕒✅ `--enable-libzimg` - Scaling, colorspace conversion, and dithering library +- ❌ `--enable-libzmq` - ZeroMQ Support To Let Multiple Clients Connect To A Single Instance (streaming) +- ❌ `--enable-libzvbi` - capture and decode VBI (vertical blanking interval) data +- ✅ `--enable-version3` +- `--pkg-config-flags=--static` +- `--disable-ffplay` diff --git a/descript/build-ffmpeg-descript.py b/descript/build-ffmpeg-descript.py new file mode 100755 index 00000000..5c792ede --- /dev/null +++ b/descript/build-ffmpeg-descript.py @@ -0,0 +1,488 @@ +#!/usr/bin/env python3 + +''' +This file is created by Descript to document and augment +the FFmpeg building process, for use in Descript's environment. + +(1) Call build-ffmpeg with the build command +(2) Copy or generate dSYM symbol files to the workspace folder +(3) Copy executables from the workspace folder and all built dependencies to platform output folder +(4) Fix dyld ids and loader paths for all built libraries +(5) Zip up the build artifacts +''' + +import glob +import os +import pathlib +import platform +import re +import shutil +import subprocess +import sys +import zipfile + +# +# Constants +# +cwd = os.path.dirname(os.path.realpath(__file__)) +base_dir = pathlib.Path(cwd).parent.absolute() +packages_dir = os.path.join(base_dir, 'packages') +workspace_dir = os.path.join(base_dir, 'workspace') +workspace_bin_dir = os.path.join(workspace_dir, 'bin') +workspace_lib_dir = os.path.join(workspace_dir, 'lib') +deployment_target = '11.0' if platform.machine() == 'arm64' else '10.11' + +# +# Keep track of which libraries are copied, skipped, or missing +# +skipped_libs = set() +copied_libs = set() +missing_libs = set() + +# +# Global Logging File +# +log_file = None + +# +# +# +def log(str): + """ + Logs to stdout and to log_file + """ + log_file.write(str + '\n') + print(str, flush=True) + +# +# +# +def log_pipe(pipe): + """ + logs from a pipe by calling log() + """ + for line in iter(pipe.readline, b''): # b'\n'-separated lines + log(line.decode('utf-8').strip()) + +# +# +# +def buildFFmpeg(script_dir, log_file): + """ + builds FFmpeg and logs output to `log_file` + """ + # set environment variables + env = os.environ + env['SKIPINSTALL'] = 'yes' # append 'SKIPINSTALL=yes' to skip prompt for installing FFmpeg to /usr/local/bin/etc + env['VERBOSE'] = 'yes' + env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target + + # call main build script + build_ffmpeg_path = os.path.join(script_dir, 'build-ffmpeg') + args = [ + build_ffmpeg_path, + '-b', # build + '--full-shared', # custom Descript shim to build shared libraries instead of static + '--enable-gpl-and-free'] # custom Descript shim to build GPL but not non-free (libpostproc is needed by Beamcoder and requires GPL) + log(' '.join(args) + '\n') + log_file.flush() + shell_proc = subprocess.Popen(args, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + with shell_proc.stdout: + log_pipe(shell_proc.stdout) + exitcode = shell_proc.wait() # 0 means success + if (exitcode != 0): + raise exitcode + +# +# +# +def copyOrGenerateSymbolFile(file, dest, log_file): + """ + Copies a single symbol file to the workspace destination + skips symlinks to avoid duplication + Copies entire `dSYM` packages for `dylib` files already within `.dSYM` packages + """ + fileref = pathlib.Path(file) + if not fileref.is_symlink(): + symbolFileName = fileref.name + '.dSYM' + destPath = os.path.join(dest, symbolFileName) + + # See if there's a matching pre-existing symbol file. + # If so, copy it, replacing the destination + # example: + # ./packages/libtheora-1.1.1/lib/.libs/libtheoraenc.1.dylib.dSYM/Contents/Resources/DWARF/libtheoraenc.1.dylib + try: + allParts = fileref.parts + symbolDirIndex = allParts.index(symbolFileName) # throws ValueError if not in allParts + symbolDirParts = allParts[:symbolDirIndex + 1] + symbolDir = os.path.join(*symbolDirParts) + if os.path.exists(destPath): + shutil.rmtree(destPath) + shutil.copytree(symbolDir, destPath) + + # Otherwise, generate a symbol file and place it at the destination + # example: + # ./packages/libtheora-1.1.1/lib/.libs/libtheora.dylib + except ValueError as e: + args = ['/usr/bin/dsymutil', str(fileref), '-o', destPath] + log(' '.join(args) + '\n') + process_result = subprocess.run(args, stdout=subprocess.PIPE) + log(process_result.stdout.decode('utf-8')) + +# +# +# +def copyOrGenerateSymbolFiles(source, dest, log_file): + """ + Recursively copies symbol files to the workspace destination + skips symlinks to avoid duplication + Copies entire `dSYM` packages for `dylib` files already within `.dSYM` packages + """ + for fileref in pathlib.Path(source + '/').glob('**/*.dylib'): + copyOrGenerateSymbolFile(str(fileref), dest, log_file) + for fileref in pathlib.Path(source + '/').glob('**/*.so*'): + copyOrGenerateSymbolFile(str(fileref), dest, log_file) + +# +# +# +def readDeploymentTarget(src_file) -> str: + """ + Reads the deployment target of a binary + :return: something like `'10.11'` or an empty string + """ + args = ['/usr/bin/otool', '-l', src_file] + otool_proc = subprocess.Popen(args, stdout=subprocess.PIPE) + inLoaderCommand = False + for line in otool_proc.stdout: + ln = line.decode('utf-8').strip() + if inLoaderCommand: + if ln.startswith('minos') or ln.startswith('version'): + return ln.split(' ')[1] + if ln.startswith('sdk'): + continue + elif 'LC_VERSION_MIN_MACOSX' in ln or 'LC_BUILD_VERSION' in ln: + inLoaderCommand = True + + return '' + + +# +# +# +def copyLibraryAndSymbolPackage(src_file, dest_folder, overwrite): + """ + Copies a library and its corresponding `.dSYM` bundle + (if present) + """ + this_deployment_target = readDeploymentTarget(src_file) + assert this_deployment_target == deployment_target, '{0} wrong deployment target {1}'.format(src_file, this_deployment_target) + + dest_file = os.path.join(dest_folder, os.path.basename(src_file)) + + # copy file + if overwrite and os.path.exists(dest_file): + os.remove(dest_file) + shutil.copy2(src_file, dest_file, follow_symlinks=False) + + # copy symbol file + src_symbol_package = src_file + '.dSYM' + if os.path.exists(src_symbol_package): + dest_symbol_package = os.path.join(dest_folder, os.path.basename(src_symbol_package)) + if overwrite and os.path.exists(dest_symbol_package): + shutil.rmtree(dest_symbol_package) + if not os.path.exists(dest_symbol_package): + shutil.copytree(src_symbol_package, dest_symbol_package) + +# +# +# +def getFileBaseNameWithoutVersion(file_path) -> str: + """ + :return: `'libpostproc'` for something like `'/foo/bar/libpostproc.55.9.100.dylib'` + """ + base_name = os.path.basename(file_path) + base_name = base_name.split('.')[0] # keep everything before first '.' + # libSDL2 weirdly has hypthen after then name (i.e., libSDL2-2.0.0.dylib) + if base_name.startswith('libSDL2'): + base_name = 'libSDL2' + return base_name + +# +# +# +def getVersionVariantsForFile(file_path): + """ + Returns the following three files for any one of the file paths provided: + `'.../ffmpeg-build-script/workspace/lib/libavcodec.58.134.100.dylib'` + `'.../ffmpeg-build-script/workspace/lib/libavcodec.58.dylib'` + `'.../ffmpeg-build-script/workspace/lib/libavcodec.dylib'` + + """ + result = set() + result.add(file_path) + if (pathlib.Path(file_path).is_symlink()): + result.add(os.path.realpath(file_path)) + + dependency_name_without_version = getFileBaseNameWithoutVersion(file_path) + unversioned_dependency_base_name = os.path.join( + os.path.dirname(file_path), + dependency_name_without_version) + + for variant in glob.glob(unversioned_dependency_base_name + r'.*dylib'): + result.add(variant) + + return list(result) + +# +# +# +def copyLibraryAndDependencies(src_file, dest_folder, log_file, parent_path = ''): + """ + Recursive function to copy a library and its (non-system) dependencies + also fixes loader paths for each library to be `@loader_path` + :param: `parent_path` - optional argument to show which parent is linking against `src_file` + """ + + dest_file = os.path.join(dest_folder, os.path.basename(src_file)) + + # copy file + copyLibraryAndSymbolPackage(src_file, dest_folder, True) + copied_libs.add(src_file) + copied_libs.add(dest_file) + + # identifier for _this_ library + this_id = '' + + # recursively copy dependencies + args = ['/usr/bin/otool', '-L', src_file] + otool_proc = subprocess.Popen(args, stdout=subprocess.PIPE) + loader_paths_to_rewrite = [] + for line in otool_proc.stdout: + ln = line.decode('utf-8').strip() + match = re.match('[^\s:]+', ln) + if not match: + continue + src_dependency_file = match[0] + + # fix incorrect usage of @rpath + rpath_token = '@rpath/' + if src_dependency_file.startswith(rpath_token): + fixed_path = os.path.join(workspace_lib_dir, src_dependency_file[len(rpath_token):]) + loader_paths_to_rewrite.append({'old_path': src_dependency_file, 'new_path': fixed_path}) + src_dependency_file = fixed_path + + if src_dependency_file.startswith('/usr/local'): + # the build grabbed libraries installed on this machine + # which might not be available on other machines + missing_libs.add(f'{src_dependency_file} (dependency of {os.path.basename(parent_path)})') + elif src_dependency_file.startswith(workspace_dir): + dependency_name = os.path.basename(src_dependency_file) + if not len(this_id): + # first dependency is the identifier for this library + this_id = dependency_name + dest_dependency_path = os.path.join(dest_folder, dependency_name) + if not src_dependency_file in copied_libs: + if src_dependency_file != dest_dependency_path: + # Copy each version variant file (often symlinks) + for variant_src_file in getVersionVariantsForFile(src_dependency_file): + copyLibraryAndSymbolPackage(variant_src_file, dest_folder, False) + variant_dest_file = os.path.join(dest_folder, os.path.basename(variant_src_file)) + copied_libs.add(variant_src_file) + copied_libs.add(variant_dest_file) + + # RECURSIVELY copy dependencies + copyLibraryAndDependencies( + os.path.realpath(src_dependency_file), + dest_folder, + log_file, + src_file) + + loader_paths_to_rewrite.append({'old_path': src_dependency_file, 'new_path': dest_dependency_path}) + else: + skipped_libs.add(src_dependency_file) + + # find the non-sym-linked version of this library + actual_binary_path = os.path.realpath(dest_file) + + # correct the loader path for this library + if len(this_id): + args = ['/usr/bin/install_name_tool', '-id', '@loader_path/' + this_id, actual_binary_path] + log(' '.join(args)) + subprocess.check_output(args) + + # correct the loader paths for all dependencies + if len(loader_paths_to_rewrite) > 0: + for loader_path in loader_paths_to_rewrite: + args = ['/usr/bin/install_name_tool', '-change', loader_path['old_path'], '@loader_path/' + os.path.basename(loader_path['new_path']), actual_binary_path] + log(' '.join(args)) + subprocess.check_output(args) + +# +# +# +def readVersion() -> str: + """ + Reads the version string from ../build-ffmpeg + :return: something like `'1.31rc1'` + """ + result = '' + with open(os.path.join(base_dir, 'build-ffmpeg')) as f: + lines = f.readlines() + for line in lines: + if line.startswith('SCRIPT_VERSION='): + result = line[15:].strip() + return result + +# +# +# +def getPlatformMachineVersion() -> str: + """ + :return: a string like `'darwin-x86_64.1.31rc2'` + """ + return sys.platform + '-' + platform.machine() + '.' + readVersion() + + +# +# +# +def generateChecksum(output_folder): + """ + Calculates checksums for every file in `output_folder` + and puts it in a `SHAMSUM256.txt` file + """ + checksums = set() + + # calculate checksums for all files + for (dirpath, dirnames, filenames) in os.walk(output_folder): + for file in filenames: + args = ['shasum', '-a', '256', os.path.join(dirpath, file)] + output = subprocess.check_output(args) + checksum = output.decode('utf-8').strip() + + # replace absolute path to just filename + # From: '0a88d3f97f356c6a42449fd548f9b586f565899144849019014e36c7683b745e /Users/cvanwink/Source/git/electron/src/out/Testing/dist.zip' + # To: '0a88d3f97f356c6a42449fd548f9b586f565899144849019014e36c7683b745e *electron-v13.1.6-darwin-x64.zip' + checksum = checksum.replace(os.path.join(dirpath, ''), '*') + checksums.add(checksum) + break + + # Write Checksums to file + checksum_file_path = os.path.join(output_folder, 'SHAMSUM256.txt') + checksum_file = open(checksum_file_path, 'w') + for checksum in checksums: + checksum_file.write(f'{checksum}\n') + checksum_file.close() + +# +# +# +def main(): + output_dir = os.path.join(cwd, 'mac') + if os.path.exists(output_dir): + shutil.rmtree(output_dir) + temp_dir = os.path.join(output_dir, platform.machine()) + os.makedirs(temp_dir) + symbol_temp_dir = os.path.join(output_dir, platform.machine() + '-symbols') + + executables = ['ffmpeg', 'ffprobe'] + base_artifact_name = '-'.join(executables) + '-shared-' + getPlatformMachineVersion() + + # create a log file for the build-ffmpeg command for build archival purposes + log_file_name = base_artifact_name + '-log.txt' + log_file_path = os.path.join(output_dir, log_file_name) + globals()['log_file'] = open(log_file_path, 'w') + + log('Begin build-ffmpeg-descript.py') + log('=======================') + + # Run the script + buildFFmpeg(base_dir, log_file) + + # Generate dSYM files for each built library + log('\nGenerating Symbols') + log('=======================') + copyOrGenerateSymbolFiles(packages_dir, symbol_temp_dir, log_file) + + # Generate dSYM files for each executable + # and copy their dependencies + for executable in executables: + log('\nCopying & Linking ' + executable) + log('=======================') + executable_path = os.path.join(workspace_bin_dir, executable) + copyOrGenerateSymbolFile(executable_path, symbol_temp_dir, log_file) + copyLibraryAndDependencies(executable_path, temp_dir, log_file, executable_path) + + # check that the copied file is runnable + log('\nChecking ' + executable) + log('=======================') + args = [os.path.join(temp_dir, executable), '-version'] + log(' '.join(args)) + output = subprocess.check_output(args) + log(output.decode('utf-8')) + + symbol_file_name = base_artifact_name + '-symbols' + shutil.make_archive(os.path.join(output_dir, symbol_file_name), 'zip', symbol_temp_dir) + shutil.rmtree(symbol_temp_dir) + + # Copy Includes + shutil.copytree( + os.path.join(workspace_dir, 'include'), + os.path.join(temp_dir, 'include')) + + log('\nLibrary Info') + log('=======================') + + for lib in sorted(missing_libs): + log('[WARNING] missing ' + lib) + + for lib in sorted(skipped_libs): + log('[NOTE] skipped ' + lib) + + for lib in sorted(copied_libs): + log('Copied ' + lib) + + log('\nArchiving third-party source') + log('=======================') + + # bundle up the third-party source + # grab each .tar.* and any downloaded patches from the packages folder + packages_zip_name = base_artifact_name + '-packages.zip' + with zipfile.ZipFile(os.path.join(output_dir, packages_zip_name), 'w', zipfile.ZIP_DEFLATED) as myzip: + types = ['*.tar.*', '*.patch', '*.diff'] + for file_type in types: + archives = pathlib.Path(packages_dir + '/').glob(file_type) + for archive in sorted(archives, key=lambda s: str(s).lower()): + log(os.path.join('packages', archive.name)) + myzip.write(str(archive.absolute()), archive.name) + + log('\nArchiving libraries') + log('=======================') + + # bundle up the build artifacts + os.chdir(temp_dir) + shared_zip_name = base_artifact_name + '.zip' + dest_file = os.path.join(output_dir, shared_zip_name) + args = ['/usr/bin/zip', '--symlinks', '-r', os.path.join('..', shared_zip_name), '.'] + log(' '.join(args)) + subprocess.check_output(args) + + shutil.rmtree(temp_dir) + + log('\nEnd of build-ffmpeg-descript.py') + log('=======================') + log_file.close() + + # zip up log file + with zipfile.ZipFile(os.path.splitext(log_file_path)[0] + '.zip', 'w', zipfile.ZIP_DEFLATED) as myzip: + myzip.write(log_file_path, os.path.basename(log_file_path)) + os.remove(log_file_path) + + generateChecksum(output_dir) + +# +# entry +# +if __name__ == '__main__': + main() diff --git a/vorbis.config.patch b/vorbis.config.patch new file mode 100644 index 00000000..67fcd67b --- /dev/null +++ b/vorbis.config.patch @@ -0,0 +1,15 @@ +--- libvorbis-1.3.7/configure.ac 2020-07-03 18:52:28 ++++ configure.ac 2023-12-18 10:48:08 +@@ -202,9 +202,9 @@ + CFLAGS="-O3 -Wall -Wextra -ffast-math -D__NO_MATH_INLINES -fsigned-char $sparc_cpu" + PROFILE="-pg -g -O3 -D__NO_MATH_INLINES -fsigned-char $sparc_cpu" ;; + *-*-darwin*) +- DEBUG="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -O0 -fsigned-char" +- CFLAGS="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -O3 -ffast-math -fsigned-char" +- PROFILE="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -pg -O3 -ffast-math -fsigned-char";; ++ DEBUG="-DDARWIN -fno-common -Wall -g -O0 -fsigned-char" ++ CFLAGS="-DDARWIN -fno-common -Wall -g -O3 -ffast-math -fsigned-char" ++ PROFILE="-DDARWIN -fno-common -Wall -g -pg -O3 -ffast-math -fsigned-char";; + *-*-os2*) + # Use -W instead of -Wextra because gcc on OS/2 is an old version. + DEBUG="-g -Wall -W -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"