From acbe01dfcd129dedba10c5bbb7158d79c8561d35 Mon Sep 17 00:00:00 2001 From: Frankie Dintino Date: Fri, 27 Oct 2023 18:11:48 -0400 Subject: [PATCH] feat(cmake): Use FetchContent and ExternalProject for local deps --- .../workflows/ci-android-emulator-tests.yml | 6 - .github/workflows/ci-android-jni.yml | 6 - .github/workflows/ci-disable-gtest.yml | 45 ++---- .github/workflows/ci-linux-golden-tests.yml | 15 +- .../workflows/ci-unix-shared-installed.yml | 12 -- .github/workflows/ci-unix-shared-local.yml | 27 ---- .github/workflows/ci-unix-static-av2.yml | 50 ++----- .github/workflows/ci-unix-static.yml | 73 ++++------ .github/workflows/ci-windows.yml | 60 ++------ CMakeLists.txt | 20 ++- appveyor.yml | 6 - cmake/Meson/crossfile-apple.meson.in | 16 ++ cmake/Modules/AvifExternalProjectUtils.cmake | 13 ++ cmake/Modules/LocalAom.cmake | 137 +++++++++++++++++- cmake/Modules/LocalAvm.cmake | 12 +- cmake/Modules/LocalDav1d.cmake | 114 ++++++++++++--- cmake/Modules/LocalGoogletest.cmake | 42 +++--- cmake/Modules/LocalJpeg.cmake | 9 +- cmake/Modules/LocalLibXml2.cmake | 30 +++- cmake/Modules/LocalLibargparse.cmake | 20 +-- cmake/Modules/LocalLibgav1.cmake | 33 +++-- cmake/Modules/LocalLibsharpyuv.cmake | 41 +++++- cmake/Modules/LocalLibyuv.cmake | 34 +++-- cmake/Modules/LocalRav1e.cmake | 92 +++++++++++- cmake/Modules/LocalSvt.cmake | 71 ++++++++- cmake/Modules/LocalZlibpng.cmake | 49 +++++-- tests/oss-fuzz/build.sh | 50 +------ 27 files changed, 676 insertions(+), 407 deletions(-) create mode 100644 cmake/Meson/crossfile-apple.meson.in create mode 100644 cmake/Modules/AvifExternalProjectUtils.cmake diff --git a/.github/workflows/ci-android-emulator-tests.yml b/.github/workflows/ci-android-emulator-tests.yml index 9a616c3a5c..734206f3d2 100644 --- a/.github/workflows/ci-android-emulator-tests.yml +++ b/.github/workflows/ci-android-emulator-tests.yml @@ -45,12 +45,6 @@ jobs: run: pip install meson - name: Setup nasm uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1 - - name: Build dav1d with the Android NDK - working-directory: ext - run: bash dav1d_android.sh ${{ steps.setup-ndk.outputs.ndk-path }} - - name: Build libyuv with the Android NDK - working-directory: ext - run: bash libyuv_android.sh ${{ steps.setup-ndk.outputs.ndk-path }} - name: Setup JDK uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: diff --git a/.github/workflows/ci-android-jni.yml b/.github/workflows/ci-android-jni.yml index 19d2105ae4..f6b7cf420b 100644 --- a/.github/workflows/ci-android-jni.yml +++ b/.github/workflows/ci-android-jni.yml @@ -39,12 +39,6 @@ jobs: run: pip install meson - name: Setup nasm uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1 - - name: Build dav1d with the Android NDK - working-directory: ext - run: bash dav1d_android.sh ${{ steps.setup-ndk.outputs.ndk-path }} - - name: Build libyuv with the Android NDK - working-directory: ext - run: bash libyuv_android.sh ${{ steps.setup-ndk.outputs.ndk-path }} - name: Setup JDK uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: diff --git a/.github/workflows/ci-disable-gtest.yml b/.github/workflows/ci-disable-gtest.yml index c07974a721..c8c12a16b8 100644 --- a/.github/workflows/ci-disable-gtest.yml +++ b/.github/workflows/ci-disable-gtest.yml @@ -41,12 +41,12 @@ jobs: toolchain: stable override: true - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 - with: - path: ext - key: ${{ runner.os }}-disable-gtest-${{ hashFiles('ext/*.cmd', 'ext/svt.sh') }} + - name: Install cargo-c + env: + LINK: https://github.com/lu-zero/cargo-c/releases/latest/download + CARGO_C_FILE: cargo-c-x86_64-unknown-linux-musl.tar.gz + run: | + curl -L $LINK/$CARGO_C_FILE | tar xz -C ~/.cargo/bin - name: Setup cmake uses: jwlawson/actions-setup-cmake@d06b37b47cfd043ec794ffa3e40e0b6b5858a7ec # v1.14.2 with: @@ -59,30 +59,6 @@ jobs: version: 2.15.05 - uses: seanmiddleditch/gha-setup-ninja@8b297075da4cd2a5f1fd21fe011b499edf06e9d2 # v4 - run: pip install meson - - name: Build aom - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e aom.cmd - - name: Build dav1d - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e dav1d.cmd - - name: Build rav1e - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e rav1e.cmd - - name: Build SVT-AV1 - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e svt.cmd - - name: Build libyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libyuv.cmd - - name: Build libsharpyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libsharpyuv.cmd - name: Prepare libavif (cmake) run: > @@ -96,6 +72,15 @@ jobs: -DAVIF_BUILD_EXAMPLES=ON -DAVIF_BUILD_APPS=ON -DAVIF_BUILD_TESTS=ON -DAVIF_ENABLE_GTEST=OFF -DAVIF_ENABLE_WERROR=ON + - name: Cache cargo registry + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + continue-on-error: true + with: + path: ~/.cargo/registry/cache + key: cargo-registry-${{ runner.os }}-${{ hashFiles('ext/rav1e/Cargo.lock') }}-disable-gtest + restore-keys: | + cargo-registry-${{ runner.os }}-${{ hashFiles('ext/rav1e/Cargo.lock') }}- + cargo-registry-${{ runner.os }}- - name: Build libavif (ninja) working-directory: ./build run: ninja diff --git a/.github/workflows/ci-linux-golden-tests.yml b/.github/workflows/ci-linux-golden-tests.yml index 2a5a0b5b1b..b10bc70965 100644 --- a/.github/workflows/ci-linux-golden-tests.yml +++ b/.github/workflows/ci-linux-golden-tests.yml @@ -38,7 +38,8 @@ jobs: uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: ext - key: ${{ runner.os }}-golden-tests-${{ hashFiles('ext/aom.cmd', 'ext/libyuv.cmd', 'ext/libxml2.cmd', 'ext/mp4box.sh') }} + key: ${{ runner.os }}-golden-tests-${{ hashFiles('ext/mp4box.sh') }} + - name: Setup cmake uses: jwlawson/actions-setup-cmake@d06b37b47cfd043ec794ffa3e40e0b6b5858a7ec with: @@ -50,18 +51,6 @@ jobs: with: version: 2.15.05 - uses: seanmiddleditch/gha-setup-ninja@8b297075da4cd2a5f1fd21fe011b499edf06e9d2 # v4 - - name: Build aom - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e aom.cmd - - name: Build libyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libyuv.cmd - - name: Build libxml2 - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libxml2.cmd - name: Build mp4box if: steps.cache-ext.outputs.cache-hit != 'true' working-directory: ./ext diff --git a/.github/workflows/ci-unix-shared-installed.yml b/.github/workflows/ci-unix-shared-installed.yml index 8f05f95072..37c41dc8cd 100644 --- a/.github/workflows/ci-unix-shared-installed.yml +++ b/.github/workflows/ci-unix-shared-installed.yml @@ -29,13 +29,6 @@ jobs: - name: Set GCC & G++ compiler (on Linux) if: runner.os == 'Linux' run: echo "CC=gcc-${{matrix.gcc}}" >> $GITHUB_ENV && echo "CXX=g++-${{matrix.gcc}}" >> $GITHUB_ENV - - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 - with: - path: ext - key: ${{ runner.os }}-shared-installed-${{ hashFiles('ext/*.cmd') }} - name: Setup cmake uses: jwlawson/actions-setup-cmake@d06b37b47cfd043ec794ffa3e40e0b6b5858a7ec # v1.14.2 with: @@ -59,11 +52,6 @@ jobs: # `sudo apt-get install googletest libgtest-dev` leads to the following: # "libgtest.a(gtest-all.cc.o): undefined reference to `std::__throw_bad_array_new_length()'" # so build it locally instead. - - name: Build GoogleTest - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e googletest.cmd - - name: Prepare libavif (cmake) run: > mkdir build && cd build diff --git a/.github/workflows/ci-unix-shared-local.yml b/.github/workflows/ci-unix-shared-local.yml index 2317e2b7d9..59e9b86abc 100644 --- a/.github/workflows/ci-unix-shared-local.yml +++ b/.github/workflows/ci-unix-shared-local.yml @@ -37,13 +37,6 @@ jobs: - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 with: python-version: '3.x' - - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 - with: - path: ext - key: ${{ runner.os }}-shared-local-${{ hashFiles('ext/*.cmd') }} - name: Setup cmake uses: jwlawson/actions-setup-cmake@d06b37b47cfd043ec794ffa3e40e0b6b5858a7ec # v1.14.2 with: @@ -58,26 +51,6 @@ jobs: - run: pip install meson - name: Print ImageMagick version run: convert --version - - name: Build aom - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e aom.cmd - - name: Build dav1d - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e dav1d.cmd - - name: Build libyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libyuv.cmd - - name: Build libsharpyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libsharpyuv.cmd - - name: Build GoogleTest - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e googletest.cmd - name: Prepare libavif (cmake) run: > diff --git a/.github/workflows/ci-unix-static-av2.yml b/.github/workflows/ci-unix-static-av2.yml index 6e3ecea5ab..d33fbc5fd7 100644 --- a/.github/workflows/ci-unix-static-av2.yml +++ b/.github/workflows/ci-unix-static-av2.yml @@ -34,13 +34,13 @@ jobs: profile: minimal toolchain: stable override: true + - name: Install cargo-c + env: + LINK: https://github.com/lu-zero/cargo-c/releases/latest/download + CARGO_C_FILE: cargo-c-x86_64-unknown-linux-musl.tar.gz + run: | + curl -L $LINK/$CARGO_C_FILE | tar xz -C ~/.cargo/bin - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 - with: - path: ext - key: ${{ runner.os }}-static-av2-${{ hashFiles('ext/*.cmd', 'ext/svt.sh') }} - name: Setup cmake uses: jwlawson/actions-setup-cmake@d06b37b47cfd043ec794ffa3e40e0b6b5858a7ec # v1.14.2 with: @@ -53,35 +53,6 @@ jobs: version: 2.15.05 - uses: seanmiddleditch/gha-setup-ninja@8b297075da4cd2a5f1fd21fe011b499edf06e9d2 # v4 - run: pip install meson - - name: Build avm - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e avm.cmd - - name: Build dav1d - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e dav1d.cmd - - name: Build rav1e - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e rav1e.cmd - - name: Build SVT-AV1 - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e svt.cmd - - name: Build libyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libyuv.cmd - - name: Build libsharpyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libsharpyuv.cmd - - name: Build GoogleTest - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - # Note: "apt install googletest" is sometimes insufficient for find_package(GTest) so build in ext/ instead. - run: bash -e googletest.cmd - name: Prepare libavif (cmake) run: > @@ -98,6 +69,15 @@ jobs: -DAVIF_BUILD_EXAMPLES=ON -DAVIF_BUILD_APPS=ON -DAVIF_BUILD_TESTS=ON -DAVIF_ENABLE_GTEST=ON -DAVIF_LOCAL_GTEST=ON -DAVIF_ENABLE_WERROR=ON + - name: Cache cargo registry + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + continue-on-error: true + with: + path: ~/.cargo/registry/cache + key: cargo-registry-${{ runner.os }}-${{ hashFiles('ext/rav1e/Cargo.lock') }}-unix-static-av2 + restore-keys: | + cargo-registry-${{ runner.os }}-${{ hashFiles('ext/rav1e/Cargo.lock') }}- + cargo-registry-${{ runner.os }}- - name: Build libavif (ninja) working-directory: ./build run: ninja diff --git a/.github/workflows/ci-unix-static.yml b/.github/workflows/ci-unix-static.yml index 65f08a8bce..078eb95ebf 100644 --- a/.github/workflows/ci-unix-static.yml +++ b/.github/workflows/ci-unix-static.yml @@ -35,18 +35,28 @@ jobs: profile: minimal toolchain: stable override: true + - name: Install cargo-c (linux) + if: matrix.os == 'ubuntu-latest' + env: + LINK: https://github.com/lu-zero/cargo-c/releases/latest/download + CARGO_C_FILE: cargo-c-x86_64-unknown-linux-musl.tar.gz + run: | + curl -L $LINK/$CARGO_C_FILE | tar xz -C ~/.cargo/bin + - name: Install cargo-c (mac) + if: matrix.os == 'macos-latest' + env: + LINK: https://github.com/lu-zero/cargo-c/releases/latest/download + CARGO_C_FILE: cargo-c-macos.zip + run: | + curl -sLo $CARGO_C_FILE $LINK/$CARGO_C_FILE + unzip -o $CARGO_C_FILE -d ~/.cargo/bin + rm $CARGO_C_FILE - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 - with: - path: ext - key: ${{ runner.os }}-${{ matrix.build-type }}-${{ hashFiles('ext/*.cmd', 'ext/svt.sh') }} - name: Setup cmake uses: jwlawson/actions-setup-cmake@d06b37b47cfd043ec794ffa3e40e0b6b5858a7ec # v1.14.2 with: - # CMake version 3.17 is required to build libwebp (which libsharpyuv is part of) on macOS. - cmake-version: '3.17.x' + # CMake version 3.18 is required to build libxml2 + cmake-version: '3.18.x' - name: Print cmake version run: cmake --version - uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1 @@ -56,44 +66,6 @@ jobs: - run: pip install meson - name: Print ImageMagick version run: convert --version - - name: Build aom - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e aom.cmd - - name: Build dav1d - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e dav1d.cmd - - name: Build rav1e - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e rav1e.cmd - - name: Build SVT-AV1 - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e svt.cmd - - name: Build libgav1 - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libgav1.cmd - - name: Build libyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libyuv.cmd - - name: Build libsharpyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libsharpyuv.cmd - - name: Build libargparse - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: bash -e libargparse.cmd - - name: Build GoogleTest - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - # Note: "apt install googletest" is sometimes insufficient for find_package(GTest) so build in ext/ instead. - run: bash -e googletest.cmd - - name: Prepare libavif (cmake) run: > mkdir build && cd build @@ -110,6 +82,15 @@ jobs: -DAVIF_ENABLE_EXPERIMENTAL_GAIN_MAP=ON -DAVIF_ENABLE_EXPERIMENTAL_AVIR=ON -DAVIF_ENABLE_WERROR=ON + - name: Cache cargo registry + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + continue-on-error: true + with: + path: ~/.cargo/registry/cache + key: cargo-registry-${{ runner.os }}-${{ hashFiles('ext/rav1e/Cargo.lock') }}-unix-static + restore-keys: | + cargo-registry-${{ runner.os }}-${{ hashFiles('ext/rav1e/Cargo.lock') }}- + cargo-registry-${{ runner.os }}- - name: Build libavif (ninja) working-directory: ./build run: ninja diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml index dd9f684f00..76e6767ded 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -43,12 +43,12 @@ jobs: toolchain: stable override: true - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 - with: - path: ext - key: ${{ runner.os }}-${{ hashFiles('ext/*.cmd') }}-alldeps + - name: Install cargo-c + run: | + $LINK = "https://github.com/lu-zero/cargo-c/releases/latest/download" + $CARGO_C_FILE = "cargo-c-windows-msvc" + curl -LO "$LINK/$CARGO_C_FILE.zip" + 7z e -y "$CARGO_C_FILE.zip" -o"${env:USERPROFILE}\.cargo\bin" - name: Print cmake version run: cmake --version - uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1 @@ -58,46 +58,6 @@ jobs: - run: pip install meson - name: Print ImageMagick version run: magick --version - - name: Build aom - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./aom.cmd - - name: Build dav1d - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./dav1d.cmd - - name: Build rav1e - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./rav1e.cmd - - name: Build SVT-AV1 - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./svt.cmd - - name: Build libgav1 - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./libgav1.cmd - - name: Build libyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./libyuv.cmd - - name: Build libjpeg - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./libjpeg.cmd - - name: Build libsharpyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./libsharpyuv.cmd - - name: Build zlib and libpng - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./zlibpng.cmd - - name: Build GoogleTest - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./googletest.cmd - name: Prepare libavif (cmake) run: > @@ -115,6 +75,14 @@ jobs: -DAVIF_ENABLE_EXPERIMENTAL_YCGCO_R=ON -DAVIF_ENABLE_EXPERIMENTAL_GAIN_MAP=ON -DAVIF_ENABLE_EXPERIMENTAL_AVIR=ON -DAVIF_ENABLE_WERROR=ON + - name: Cache cargo registry + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + continue-on-error: true + with: + path: ~/.cargo/registry/cache + key: cargo-registry-${{ runner.os }}-${{ hashFiles('ext/rav1e/Cargo.lock') }}- + restore-keys: | + cargo-registry-${{ runner.os }}- - name: Build libavif (ninja) working-directory: ./build run: ninja diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e41df1c66..7877cc1eb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,12 +8,23 @@ if(POLICY CMP0092) cmake_policy(SET CMP0092 NEW) endif() +# Prevent warnings in CMake>=3.24 for ExternalProject_Add() +# see https://cmake.org/cmake/help/latest/policy/CMP0135.html +if(POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) # valid for DOWNLOAD_EXTRACT_TIMESTAMP option in CMake 3.24 and later +endif() + # The root directory of the avif source set(AVIF_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") # Specify search path for CMake modules to be loaded by include() and find_package() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") +include(ExternalProject) +include(FetchContent) +include(FindPkgConfig) +include(AvifExternalProjectUtils) + project(libavif LANGUAGES C VERSION 1.0.3) # Set C99 as the default @@ -106,6 +117,9 @@ option(AVIF_LOCAL_FUZZTEST "Build the Google FuzzTest framework by providing your own copy of the repo in ext/fuzztest (see Local Builds in README)" OFF ) +option(AVIF_LOCAL_LIBARGPARSE "Build libargparse locally as part of the CMake build process. Required to build avifgainmap util" + OFF +) option( AVIF_ENABLE_COMPLIANCE_WARDEN @@ -716,8 +730,8 @@ if(AVIF_BUILD_APPS) ) endif() if(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP) - include(LocalLibargparse) - if(TARGET libargparse) + if(AVIF_LOCAL_LIBARGPARSE) + include(LocalLibargparse) set(AVIF_ENABLE_AVIFGAINMAPUTIL TRUE) set(AVIFGAINMAPUTIL_SRCS @@ -743,6 +757,8 @@ if(AVIF_BUILD_APPS) target_include_directories(avifgainmaputil PRIVATE apps/avifgainmaputil/) target_link_libraries(avifgainmaputil libargparse avif_apps) # Don't add avifgainmaputil to installed apps for now. + else() + message(WARNING "AVIF_LOCAL_LIBARGPARSE is not enabled, not building avifgainmaputil") endif() endif() endif() diff --git a/appveyor.yml b/appveyor.yml index 1d1c6b6285..75e0646436 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,12 +19,6 @@ install: - nasm -v # Build all external libraries statically - cd ext - - aom.cmd - - dav1d.cmd - - libjpeg.cmd - - zlibpng.cmd - - set "CC=clang-cl" && set "CXX=clang-cl" - - libyuv.cmd - set "CC=" && set "CXX=" - cd .. # Configure with CMake diff --git a/cmake/Meson/crossfile-apple.meson.in b/cmake/Meson/crossfile-apple.meson.in new file mode 100644 index 0000000000..800d35b684 --- /dev/null +++ b/cmake/Meson/crossfile-apple.meson.in @@ -0,0 +1,16 @@ +[binaries] +c = ['clang'] +cpp = ['clang++'] +ar = ['ar'] +strip = ['strip'] +pkg-config = ['pkg-config'] + +[host_machine] +system = '@cross_system_name@' +cpu_family = '@cross_system_processor@' +cpu = '@cross_system_processor@' +endian = '@cross_system_endian@' + +[built-in options] +c_args = ['-arch', '@CMAKE_SYSTEM_PROCESSOR@', '-isysroot', '@CMAKE_OSX_SYSROOT@', '@cross_osx_deployment_target@' @cross_additional_cflags@] +c_link_args = ['-arch', '@CMAKE_SYSTEM_PROCESSOR@', '-isysroot', '@CMAKE_OSX_SYSROOT@', '@cross_osx_deployment_target@' @cross_additional_cflags@] diff --git a/cmake/Modules/AvifExternalProjectUtils.cmake b/cmake/Modules/AvifExternalProjectUtils.cmake new file mode 100644 index 0000000000..8d19e53b48 --- /dev/null +++ b/cmake/Modules/AvifExternalProjectUtils.cmake @@ -0,0 +1,13 @@ +macro(avif_fetchcontent_populate_cmake name) + if(NOT ${name}_POPULATED) + FetchContent_Populate(${name}) + + # Force static build + set(BUILD_SHARED_LIBS_ORIG ${BUILD_SHARED_LIBS}) + set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") + + add_subdirectory(${${name}_SOURCE_DIR} ${${name}_BINARY_DIR} EXCLUDE_FROM_ALL) + + set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_ORIG} CACHE BOOL "" FORCE) + endif() +endmacro() diff --git a/cmake/Modules/LocalAom.cmake b/cmake/Modules/LocalAom.cmake index 6d67775b60..d2f9c1faec 100644 --- a/cmake/Modules/LocalAom.cmake +++ b/cmake/Modules/LocalAom.cmake @@ -1,8 +1,133 @@ -set(LIB_FILENAME "${AVIF_SOURCE_DIR}/ext/aom/build.libavif/${CMAKE_STATIC_LIBRARY_PREFIX}aom${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: ${LIB_FILENAME} is missing, bailing out") +set(AVIF_LOCAL_AOM_GIT_TAG v3.7.1) +set(AVIF_LOCAL_AVM_GIT_TAG research-v5.0.0) + +if(AVIF_CODEC_AVM) + message(CHECK_START "Fetching avm") +else() + message(CHECK_START "Fetching aom") +endif() + +# aom sets its compile options by setting variables like CMAKE_C_FLAGS_RELEASE using +# CACHE FORCE, which effectively adds those flags to all targets. We stash and restore +# the original values and call avif_set_aom_compile_options to instead set the flags on all aom +# targets +function(avif_set_aom_compile_options target config) + string(REPLACE " " ";" AOM_C_FLAGS_LIST "${CMAKE_C_FLAGS_${config}}") + string(REPLACE " " ";" AOM_CXX_FLAGS_LIST "${CMAKE_CXX_FLAGS_${config}}") + foreach(flag ${AOM_C_FLAGS_LIST}) + target_compile_options(${target} PRIVATE $<$:${flag}>) + endforeach() + foreach(flag ${AOM_CXX_FLAGS_LIST}) + target_compile_options(${target} PRIVATE $<$:${flag}>) + endforeach() + + get_target_property(sources ${target} SOURCES) + foreach(src ${sources}) + if(src MATCHES "TARGET_OBJECTS:") + string(REGEX REPLACE "\\$" "\\1" source_target ${src}) + avif_set_aom_compile_options(${source_target} ${config}) + endif() + endforeach() +endfunction() + +if(AVIF_CODEC_AVM) + set(AOM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/avm") +else() + set(AOM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/aom") +endif() +if(ANDROID_ABI) + set(AOM_BINARY_DIR "${AOM_BINARY_DIR}/${ANDROID_ABI}") +endif() + +if(AVIF_CODEC_AVM) + FetchContent_Declare( + libaom + GIT_REPOSITORY "https://gitlab.com/AOMediaCodec/avm.git" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/avm" BINARY_DIR "${AOM_BINARY_DIR}" + GIT_TAG ${AVIF_LOCAL_AVM_GIT_TAG} + GIT_PROGRESS ON + GIT_SHALLOW ON + UPDATE_COMMAND "" + ) +else() + set(AOM_PATCH_COMMAND) + if(CMAKE_C_IMPLICIT_LINK_DIRECTORIES MATCHES "alpine-linux-musl") + find_package(Patch REQUIRED) + list(APPEND AOM_PATCH_COMMAND PATCH_COMMAND "${Patch_EXECUTABLE}" -p1 -i + ${CMAKE_CURRENT_LIST_DIR}/LocalAom/musl-fix-stack-size.patch + ) + endif() + FetchContent_Declare( + libaom URL "https://aomedia.googlesource.com/aom/+archive/${AVIF_LOCAL_AOM_GIT_TAG}.tar.gz" SOURCE_DIR + "${AVIF_SOURCE_DIR}/ext/aom" BINARY_DIR "${AOM_BINARY_DIR}" UPDATE_COMMAND "" ${AOM_PATCH_COMMAND} + ) +endif() + +set(CONFIG_PIC 1 CACHE INTERNAL "") +if(libyuv_FOUND) + set(CONFIG_LIBYUV 0 CACHE INTERNAL "") +else() + set(CONFIG_LIBYUV 1 CACHE INTERNAL "") endif() +set(CONFIG_WEBM_IO 0 CACHE INTERNAL "") +set(ENABLE_DOCS 0 CACHE INTERNAL "") +set(ENABLE_EXAMPLES 0 CACHE INTERNAL "") +set(ENABLE_TESTDATA 0 CACHE INTERNAL "") +set(ENABLE_TESTS 0 CACHE INTERNAL "") +set(ENABLE_TOOLS 0 CACHE INTERNAL "") +if(NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR) + set(CONFIG_RUNTIME_CPU_DETECT 0 CACHE INTERNAL "") +endif() +if(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64") + set(AOM_TARGET_CPU "arm64") +endif() + +if(NOT libaom_POPULATED) + # Guard against the project setting cmake variables that would affect the parent build + # See comment above for avif_set_aom_compile_options + foreach(_config_setting CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS) + foreach(_config_type DEBUG RELEASE MINSIZEREL RELWITHDEBINFO) + set(${_config_setting}_${_config_type}_ORIG ${${_config_setting}_${_config_type}}) + endforeach() + endforeach() + + avif_fetchcontent_populate_cmake(libaom) + + set(_aom_config RELEASE) + if(CMAKE_BUILD_TYPE) + string(TOUPPER ${CMAKE_BUILD_TYPE} _aom_config) + endif() + list(LENGTH CMAKE_CONFIGURATION_TYPES num_configs) + if(${num_configs} GREATER 0) + list(GET CMAKE_CONFIGURATION_TYPES 0 _aom_config_type) + string(TOUPPER ${_aom_config_type} _aom_config) + endif() + avif_set_aom_compile_options(aom ${_aom_config}) + + foreach(_config_setting CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS) + foreach(_config_type DEBUG RELEASE MINSIZEREL RELWITHDEBINFO) + set(${_config_setting}_${_config_type} ${${_config_setting}_${_config_type}_ORIG} CACHE STRING "" FORCE) + unset(${_config_setting}_${_config_type}_ORIG) + endforeach() + endforeach() + unset(_config_type) + unset(_config_setting) +endif() + +# If we have libyuv, we disable CONFIG_LIBYUV so that aom does not include the libyuv +# sources from its third-party vendor library. But we still want AOM to have libyuv, only +# linked against this project's target. Here we update the value in aom_config.h and add libyuv +# to AOM's link libraries +if(libyuv_FOUND) + file(READ ${AOM_BINARY_DIR}/config/aom_config.h AOM_CONFIG_H) + if("${AOM_CONFIG_H}" MATCHES "CONFIG_LIBYUV 0") + string(REPLACE "CONFIG_LIBYUV 0" "CONFIG_LIBYUV 1" AOM_CONFIG_H "${AOM_CONFIG_H}") + file(WRITE ${AOM_BINARY_DIR}/config/aom_config.h "${AOM_CONFIG_H}") + endif() + target_link_libraries(aom PRIVATE $) +endif() + +set_property(TARGET aom PROPERTY AVIF_LOCAL ON) +target_include_directories(aom INTERFACE "${libaom_SOURCE_DIR}" ${AOM_BINARY_DIR}) -add_library(aom STATIC IMPORTED GLOBAL) -set_target_properties(aom PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -target_include_directories(aom INTERFACE "${AVIF_SOURCE_DIR}/ext/aom") +message(CHECK_PASS "fetched") diff --git a/cmake/Modules/LocalAvm.cmake b/cmake/Modules/LocalAvm.cmake index a61d58bf75..f641d7ffaa 100644 --- a/cmake/Modules/LocalAvm.cmake +++ b/cmake/Modules/LocalAvm.cmake @@ -1,11 +1 @@ -# Building the avm repository generates files such as "libaom.a" because it is a fork of aom. -set(LIB_FILENAME "${AVIF_SOURCE_DIR}/ext/avm/build.libavif/${CMAKE_STATIC_LIBRARY_PREFIX}aom${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: ${LIB_FILENAME} (from avm) is missing, bailing out") -endif() - -add_library(aom STATIC IMPORTED GLOBAL) -set_target_properties(aom PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -target_include_directories(aom INTERFACE "${AVIF_SOURCE_DIR}/ext/avm") -# ext/avm/aom/aom_encoder.h includes config/aom_config.h which is generated by the local build of avm. -target_include_directories(aom INTERFACE "${AVIF_SOURCE_DIR}/ext/avm/build.libavif") +include(LocalAom) diff --git a/cmake/Modules/LocalDav1d.cmake b/cmake/Modules/LocalDav1d.cmake index 56bbeed966..eed5917d0b 100644 --- a/cmake/Modules/LocalDav1d.cmake +++ b/cmake/Modules/LocalDav1d.cmake @@ -1,25 +1,97 @@ -set(AVIF_DAV1D_BUILD_DIR "${AVIF_SOURCE_DIR}/ext/dav1d/build") -# If ${ANDROID_ABI} is set, look for the library under that subdirectory. -if(DEFINED ANDROID_ABI) - set(AVIF_DAV1D_BUILD_DIR "${AVIF_DAV1D_BUILD_DIR}/${ANDROID_ABI}") +if(NOT AVIF_LOCAL_DAV1D_TAG) + set(AVIF_LOCAL_DAV1D_TAG "1.2.1") endif() -set(LIB_FILENAME "${AVIF_DAV1D_BUILD_DIR}/src/libdav1d${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - if("${CMAKE_STATIC_LIBRARY_SUFFIX}" STREQUAL ".a") - message(FATAL_ERROR "libavif: ${LIB_FILENAME} is missing, bailing out") - else() - # On windows, meson will produce a libdav1d.a instead of the expected libdav1d.dll/.lib. - # See https://github.com/mesonbuild/meson/issues/8153. - set(LIB_FILENAME "${AVIF_SOURCE_DIR}/ext/dav1d/build/src/libdav1d.a") - if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: ${LIB_FILENAME} (or libdav1d${CMAKE_STATIC_LIBRARY_SUFFIX}) is missing, bailing out") +if(NOT AVIF_LOCAL_DAV1D_REPO) + set(AVIF_LOCAL_DAV1D_REPO "https://code.videolan.org/videolan/dav1d.git") +endif() + +function(avif_build_local_dav1d) + set(source_dir "${AVIF_SOURCE_DIR}/ext/dav1d") + set(binary_dir "${CMAKE_CURRENT_BINARY_DIR}/ext/dav1d") + + find_program(NINJA_EXECUTABLE NAMES ninja ninja-build REQUIRED) + find_program(MESON_EXECUTABLE meson REQUIRED) + + set(PATH $ENV{PATH}) + if(WIN32) + string(REPLACE ";" "\$" PATH "${PATH}") + endif() + if(ANDROID_TOOLCHAIN_ROOT) + set(PATH "${ANDROID_TOOLCHAIN_ROOT}/bin$,$,:>${PATH}") + endif() + + if(ANDROID) + list(APPEND CMAKE_PROGRAM_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin") + set(binary_dir "${binary_dir}/${ANDROID_ABI}") + + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a") + set(android_arch "arm") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + set(android_arch "aarch64") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set(android_arch "x86_64") + else() + set(android_arch "x86") + endif() + + set(CROSS_FILE "${source_dir}/package/crossfiles/${android_arch}-android.meson") + elseif(APPLE) + # If we are cross compiling generate the corresponding file to use with meson + if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR) + string(TOLOWER "${CMAKE_SYSTEM_NAME}" cross_system_name) + if(CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN") + set(cross_system_endian "big") + else() + set(cross_system_endian "little") + endif() + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(cross_system_processor "aarch64") + else() + set(cross_system_processor "${CMAKE_SYSTEM_PROCESSOR}") + endif() + if(CMAKE_OSX_DEPLOYMENT_TARGET) + set(cross_osx_deployment_target "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endif() + + set(CROSS_FILE "${PROJECT_BINARY_DIR}/crossfile-apple.meson") + configure_file("cmake/Meson/crossfile-apple.meson.in" "${CROSS_FILE}") endif() endif() -endif() -add_library(dav1d::dav1d STATIC IMPORTED) -set_target_properties(dav1d::dav1d PROPERTIES IMPORTED_LOCATION ${LIB_FILENAME} AVIF_LOCAL ON) -target_include_directories( - dav1d::dav1d INTERFACE "${AVIF_DAV1D_BUILD_DIR}" "${AVIF_DAV1D_BUILD_DIR}/include" "${AVIF_DAV1D_BUILD_DIR}/include/dav1d" - "${AVIF_SOURCE_DIR}/ext/dav1d/include" -) + if(CROSS_FILE) + set(EXTRA_ARGS "--cross-file=${CROSS_FILE}") + endif() + + set(install_prefix "${binary_dir}/install.libavif") + + file(MAKE_DIRECTORY ${install_prefix}/include) + + ExternalProject_Add( + dav1d + GIT_REPOSITORY https://code.videolan.org/videolan/dav1d.git + SOURCE_DIR "${source_dir}" + PREFIX "${binary_dir}" + INSTALL_DIR "${install_prefix}" + LIST_SEPARATOR | + GIT_TAG ${AVIF_LOCAL_DAV1D_TAG} + GIT_SHALLOW ON + UPDATE_COMMAND "" + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -E env "PATH=${PATH}" ${MESON_EXECUTABLE} setup --buildtype=release --default-library=static + --prefix= --libdir=lib -Denable_asm=true -Denable_tools=false -Denable_examples=false + -Denable_tests=false ${EXTRA_ARGS} + BUILD_COMMAND ${CMAKE_COMMAND} -E env "PATH=${PATH}" ${NINJA_EXECUTABLE} -C + INSTALL_COMMAND ${CMAKE_COMMAND} -E env "PATH=${PATH}" ${NINJA_EXECUTABLE} -C install + BUILD_BYPRODUCTS /lib/libdav1d.a + ) + + add_library(dav1d::dav1d STATIC IMPORTED) + set_target_properties(dav1d::dav1d PROPERTIES IMPORTED_LOCATION ${install_prefix}/lib/libdav1d.a AVIF_LOCAL ON) + target_include_directories(dav1d::dav1d INTERFACE "${install_prefix}/include") + target_link_directories(dav1d::dav1d INTERFACE ${install_prefix}/lib) + add_dependencies(dav1d::dav1d dav1d) + + set_target_properties(dav1d::dav1d PROPERTIES FOLDER "ext/dav1d") +endfunction() + +avif_build_local_dav1d() diff --git a/cmake/Modules/LocalGoogletest.cmake b/cmake/Modules/LocalGoogletest.cmake index c26f2db392..2bdf873c6f 100644 --- a/cmake/Modules/LocalGoogletest.cmake +++ b/cmake/Modules/LocalGoogletest.cmake @@ -1,28 +1,22 @@ -set(GTEST_INCLUDE_DIRS ${AVIF_SOURCE_DIR}/ext/googletest/googletest/include) -set(GTEST_LIB_FILENAME - ${AVIF_SOURCE_DIR}/ext/googletest/build/lib/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} -) -set(GTEST_MAIN_LIB_FILENAME - ${AVIF_SOURCE_DIR}/ext/googletest/build/lib/${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} +set(AVIF_LOCAL_GTEST_GIT_TAG v1.13.0) + +message(CHECK_START "Fetching googletest") +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG ${AVIF_LOCAL_GTEST_GIT_TAG} + GIT_SHALLOW ON ) -if(NOT EXISTS ${GTEST_INCLUDE_DIRS}/gtest/gtest.h) - message(FATAL_ERROR "googletest(AVIF_LOCAL_GTEST): ${GTEST_INCLUDE_DIRS}/gtest/gtest.h is missing, bailing out") -elseif(NOT EXISTS ${GTEST_LIB_FILENAME}) - message(FATAL_ERROR "googletest(AVIF_LOCAL_GTEST): ${GTEST_LIB_FILENAME} is missing, bailing out") -elseif(NOT EXISTS ${GTEST_MAIN_LIB_FILENAME}) - message(FATAL_ERROR "googletest(AVIF_LOCAL_GTEST): ${GTEST_MAIN_LIB_FILENAME} is missing, bailing out") -else() - message(STATUS "Found local ext/googletest") -endif() +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +set(BUILD_GMOCK ON CACHE BOOL "" FORCE) + +avif_fetchcontent_populate_cmake(googletest) +message(CHECK_PASS "fetched") + +set_target_properties(gtest gtest_main PROPERTIES AVIF_LOCAL ON) -add_library(GTest::gtest STATIC IMPORTED) -set_target_properties(GTest::gtest PROPERTIES IMPORTED_LOCATION "${GTEST_LIB_FILENAME}" AVIF_LOCAL ON) +add_library(GTest::gtest ALIAS gtest) +add_library(GTest::gtest_main ALIAS gtest_main) -if(TARGET Threads::Threads) - target_link_libraries(GTest::gtest INTERFACE Threads::Threads) -endif() -target_include_directories(GTest::gtest INTERFACE "${GTEST_INCLUDE_DIRS}") -add_library(GTest::gtest_main STATIC IMPORTED) -target_link_libraries(GTest::gtest_main INTERFACE GTest::gtest) -set_target_properties(GTest::gtest_main PROPERTIES IMPORTED_LOCATION "${GTEST_MAIN_LIB_FILENAME}" AVIF_LOCAL ON) +set(GTest_FOUND ON CACHE BOOL "") diff --git a/cmake/Modules/LocalJpeg.cmake b/cmake/Modules/LocalJpeg.cmake index 6dfb6f7b5c..f05381c355 100644 --- a/cmake/Modules/LocalJpeg.cmake +++ b/cmake/Modules/LocalJpeg.cmake @@ -1,4 +1,11 @@ -add_subdirectory(${AVIF_SOURCE_DIR}/ext/libjpeg EXCLUDE_FROM_ALL) +FetchContent_Declare( + libjpeg + GIT_REPOSITORY "https://github.com/joedrago/libjpeg.git" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/libjpeg" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/libjpeg" + GIT_SHALLOW ON + UPDATE_COMMAND "" +) +avif_fetchcontent_populate_cmake(libjpeg) set_property(TARGET jpeg PROPERTY AVIF_LOCAL ON) set(JPEG_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/libjpeg") diff --git a/cmake/Modules/LocalLibXml2.cmake b/cmake/Modules/LocalLibXml2.cmake index 598a0bd55e..f24334bd84 100644 --- a/cmake/Modules/LocalLibXml2.cmake +++ b/cmake/Modules/LocalLibXml2.cmake @@ -1,9 +1,25 @@ -set(LIB_FILENAME "${AVIF_SOURCE_DIR}/ext/libxml2/install.libavif/lib/${AVIF_LIBRARY_PREFIX}xml2${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: ${LIB_FILENAME} is missing, bailing out") +set(AVIF_LOCAL_LIBXML_GIT_TAG "v2.11.5") + +set(LIBXML2_WITH_PYTHON OFF CACHE INTERNAL "-") +set(LIBXML2_WITH_ZLIB OFF CACHE INTERNAL "-") +set(LIBXML2_WITH_LZMA OFF CACHE INTERNAL "-") +set(LIBXML2_WITH_ICONV OFF CACHE INTERNAL "-") +set(LIBXML2_WITH_TESTS OFF CACHE INTERNAL "-") +set(LIBXML2_WITH_PROGRAMS OFF CACHE INTERNAL "-") +set(LIBXML2_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/libxml2") +if(ANDROID_ABI) + set(LIBXML2_BINARY_DIR "${LIBXML2_BINARY_DIR}/${ANDROID_ABI}") endif() -add_library(LibXml2 STATIC IMPORTED GLOBAL) -set_target_properties(LibXml2 PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -target_include_directories(LibXml2 INTERFACE "${AVIF_SOURCE_DIR}/ext/libxml2/install.libavif/include/libxml2") -add_library(LibXml2::LibXml2 ALIAS LibXml2) +FetchContent_Declare( + libxml2 + GIT_REPOSITORY "https://gitlab.gnome.org/GNOME/libxml2.git" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/libxml2" BINARY_DIR "${LIBXML2_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBXML_GIT_TAG}" + GIT_SHALLOW ON + UPDATE_COMMAND "" +) + +avif_fetchcontent_populate_cmake(libxml2) + +set_property(TARGET LibXml2 PROPERTY AVIF_LOCAL ON) diff --git a/cmake/Modules/LocalLibargparse.cmake b/cmake/Modules/LocalLibargparse.cmake index 012aafe85d..39266dd512 100644 --- a/cmake/Modules/LocalLibargparse.cmake +++ b/cmake/Modules/LocalLibargparse.cmake @@ -1,10 +1,12 @@ -set(LIBARGPARSE_FILENAME - "${AVIF_SOURCE_DIR}/ext/libargparse/build/${CMAKE_STATIC_LIBRARY_PREFIX}argparse${CMAKE_STATIC_LIBRARY_SUFFIX}" +set(AVIF_LOCAL_LIBARGPARSE_GIT_TAG ee74d1b53bd680748af14e737378de57e2a0a954) + +FetchContent_Declare( + libargparse + GIT_REPOSITORY "https://github.com/kmurray/libargparse.git" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/libargparse" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/libargparse" + GIT_TAG ${AVIF_LOCAL_LIBARGPARSE_GIT_TAG} + UPDATE_COMMAND "" ) -if(EXISTS "${LIBARGPARSE_FILENAME}") - add_library(libargparse STATIC IMPORTED GLOBAL) - set_target_properties(libargparse PROPERTIES IMPORTED_LOCATION "${LIBARGPARSE_FILENAME}" AVIF_LOCAL ON) - target_include_directories(libargparse INTERFACE "${AVIF_SOURCE_DIR}/ext/libargparse/src") -else() - message(WARNING "${LIBARGPARSE_FILENAME} is missing, not building avifgainmaputil, please run ext/libargparse.cmd") -endif() +avif_fetchcontent_populate_cmake(libargparse) + +set_target_properties(libargparse PROPERTIES FOLDER "ext/libargparse") diff --git a/cmake/Modules/LocalLibgav1.cmake b/cmake/Modules/LocalLibgav1.cmake index c383497ec7..290e8d681c 100644 --- a/cmake/Modules/LocalLibgav1.cmake +++ b/cmake/Modules/LocalLibgav1.cmake @@ -1,14 +1,25 @@ -set(AVIF_LIBGAV1_BUILD_DIR "${AVIF_SOURCE_DIR}/ext/libgav1/build") -# If ${ANDROID_ABI} is set, look for the library under that subdirectory. -if(DEFINED ANDROID_ABI) - set(AVIF_LIBGAV1_BUILD_DIR "${AVIF_LIBGAV1_BUILD_DIR}/${ANDROID_ABI}") -endif() -set(LIB_FILENAME "${AVIF_LIBGAV1_BUILD_DIR}/libgav1${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: ${LIB_FILENAME} is missing, bailing out") +set(AVIF_LOCAL_LIBGAV1_GIT_TAG "v0.18.0") + +set(LIBGAV1_THREADPOOL_USE_STD_MUTEX 1 CACHE INTERNAL "") +set(LIBGAV1_ENABLE_EXAMPLES OFF CACHE INTERNAL "") +set(LIBGAV1_ENABLE_TESTS OFF CACHE INTERNAL "") +set(LIBGAV1_MAX_BITDEPTH 12 CACHE INTERNAL "") + +set(LIBGAV1_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/libgav1") +if(ANDROID_ABI) + set(LIBGAV1_BINARY_DIR "${LIBGAV1_BINARY_DIR}/${ANDROID_ABI}") endif() -add_library(libgav1_static STATIC IMPORTED GLOBAL) -set_target_properties(libgav1_static PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -target_include_directories(libgav1_static INTERFACE "${AVIF_SOURCE_DIR}/ext/libgav1/src") +FetchContent_Declare( + libgav1 + GIT_REPOSITORY "https://chromium.googlesource.com/codecs/libgav1" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/libgav1" BINARY_DIR "${LIBGAV1_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBGAV1_GIT_TAG}" + GIT_SHALLOW ON + UPDATE_COMMAND "" +) + +avif_fetchcontent_populate_cmake(libgav1) + +set_property(TARGET libgav1_static PROPERTY AVIF_LOCAL ON FOLDER "ext/libgav1") add_library(libgav1::libgav1 ALIAS libgav1_static) diff --git a/cmake/Modules/LocalLibsharpyuv.cmake b/cmake/Modules/LocalLibsharpyuv.cmake index 73aacac275..8b174fe780 100644 --- a/cmake/Modules/LocalLibsharpyuv.cmake +++ b/cmake/Modules/LocalLibsharpyuv.cmake @@ -1,10 +1,37 @@ -set(LIB_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/ext/libwebp/build/libsharpyuv${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif(AVIF_LIBSHARPYUV=LOCAL): ${LIB_FILENAME} is missing, bailing out") +set(AVIF_LOCAL_LIBSHARPYUV_GIT_TAG v1.3.2) + +set(WEBP_BUILD_ANIM_UTILS OFF CACHE BOOL "") +set(WEBP_BUILD_CWEBP OFF CACHE BOOL "") +set(WEBP_BUILD_DWEBP OFF CACHE BOOL "") +set(WEBP_BUILD_GIF2WEBP OFF CACHE BOOL "") +set(WEBP_BUILD_IMG2WEBP OFF CACHE BOOL "") +set(WEBP_BUILD_VWEBP OFF CACHE BOOL "") +set(WEBP_BUILD_WEBPINFO OFF CACHE BOOL "") +set(WEBP_BUILD_LIBWEBPMUX OFF CACHE BOOL "") +set(WEBP_BUILD_WEBPMUX OFF CACHE BOOL "") +set(WEBP_BUILD_EXTRAS OFF CACHE BOOL "") + +set(LIBSHARPYUV_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/libwebp") +if(ANDROID_ABI) + set(LIBSHARPYUV_BINARY_DIR "${LIBSHARPYUV_BINARY_DIR}/${ANDROID_ABI}") endif() +FetchContent_Declare( + libwebp + GIT_REPOSITORY "https://chromium.googlesource.com/webm/libwebp" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/libwebp" BINARY_DIR "${LIBSHARPYUV_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBSHARPYUV_GIT_TAG}" + GIT_SHALLOW ON + UPDATE_COMMAND "" +) + +avif_fetchcontent_populate_cmake(libwebp) + +set_property(TARGET sharpyuv PROPERTY POSITION_INDEPENDENT_CODE ON) +set_property(TARGET sharpyuv PROPERTY AVIF_LOCAL ON) +set_property(TARGET sharpyuv PROPERTY FOLDER "ext/libwebp") -add_library(sharpyuv::sharpyuv STATIC IMPORTED GLOBAL) -set_target_properties(sharpyuv::sharpyuv PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -target_include_directories(sharpyuv::sharpyuv INTERFACE "${AVIF_SOURCE_DIR}/ext/libwebp") +target_include_directories( + sharpyuv INTERFACE $ $ +) -set(libsharpyuv_FOUND ON) +add_library(sharpyuv::sharpyuv ALIAS sharpyuv) diff --git a/cmake/Modules/LocalLibyuv.cmake b/cmake/Modules/LocalLibyuv.cmake index 5ef11c7d02..6a2d0af0b0 100644 --- a/cmake/Modules/LocalLibyuv.cmake +++ b/cmake/Modules/LocalLibyuv.cmake @@ -1,22 +1,32 @@ -set(AVIF_LIBYUV_BUILD_DIR "${AVIF_SOURCE_DIR}/ext/libyuv/build") - -# If ${ANDROID_ABI} is set, look for the library under that subdirectory. -if(DEFINED ANDROID_ABI) - set(AVIF_LIBYUV_BUILD_DIR "${AVIF_LIBYUV_BUILD_DIR}/${ANDROID_ABI}") +if(NOT DEFINED AVIF_LOCAL_LIBYUV_REPO) + set(AVIF_LOCAL_LIBYUV_REPO "https://chromium.googlesource.com/libyuv/libyuv") +endif() +if(NOT DEFINED AVIF_LOCAL_LIBYUV_TAG) + set(AVIF_LOCAL_LIBYUV_TAG "464c51a0353c71f08fe45f683d6a97a638d47833") endif() -set(LIB_FILENAME "${AVIF_LIBYUV_BUILD_DIR}/${AVIF_LIBRARY_PREFIX}yuv${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif(AVIF_LIBYUV=LOCAL): ${LIB_FILENAME} is missing, bailing out") +set(LIBYUV_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/libyuv") +if(ANDROID_ABI) + set(LIBYUV_BINARY_DIR "${LIBYUV_BINARY_DIR}/${ANDROID_ABI}") endif() +FetchContent_Declare( + libyuv + GIT_REPOSITORY "${AVIF_LOCAL_LIBYUV_REPO}" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/libyuv" BINARY_DIR "${LIBYUV_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBYUV_TAG}" + UPDATE_COMMAND "" +) + +avif_fetchcontent_populate_cmake(libyuv) + +set_property(TARGET yuv PROPERTY POSITION_INDEPENDENT_CODE ON) +set_target_properties(yuv PROPERTIES AVIF_LOCAL ON FOLDER "ext/libyuv") -message(STATUS "libavif: local libyuv found; libyuv-based fast paths enabled.") +add_library(yuv::yuv ALIAS yuv) set(LIBYUV_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/libyuv/include") -add_library(yuv::yuv STATIC IMPORTED GLOBAL) -set_target_properties(yuv::yuv PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -target_include_directories(yuv::yuv INTERFACE "${LIBYUV_INCLUDE_DIR}") +target_include_directories(yuv INTERFACE ${LIBYUV_INCLUDE_DIR}) set(libyuv_FOUND ON) diff --git a/cmake/Modules/LocalRav1e.cmake b/cmake/Modules/LocalRav1e.cmake index 642934d926..7c5e3940a3 100644 --- a/cmake/Modules/LocalRav1e.cmake +++ b/cmake/Modules/LocalRav1e.cmake @@ -1,8 +1,90 @@ -set(LIB_FILENAME "${AVIF_SOURCE_DIR}/ext/rav1e/build.libavif/usr/lib/${AVIF_LIBRARY_PREFIX}rav1e${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: compiled rav1e library is missing (in ext/rav1e/build.libavif/usr/lib), bailing out") +set(AVIF_LOCAL_RAV1E_GIT_TAG v0.6.6) + +set(AVIF_LOCAL_CORROSION_GIT_TAG v0.4.4) +set(AVIF_LOCAL_CARGOC_GIT_TAG v0.9.27) + +find_program(CARGO_CINSTALL cargo-cinstall HINTS "$ENV{HOME}/.cargo/bin") + +if(CARGO_CINSTALL) + add_executable(cargo-cinstall IMPORTED GLOBAL) + set_property(TARGET cargo-cinstall PROPERTY IMPORTED_LOCATION ${CARGO_CINSTALL}) +endif() + +FetchContent_Declare( + Corrosion + GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git + GIT_TAG ${AVIF_LOCAL_CORROSION_GIT_TAG} + GIT_SHALLOW ON +) + +if(APPLE) + if(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(Rust_CARGO_TARGET "aarch64-apple-darwin") + endif() +endif() + +FetchContent_MakeAvailable(Corrosion) + +if(NOT TARGET cargo-cinstall) + FetchContent_Declare( + cargoc + GIT_REPOSITORY https://github.com/lu-zero/cargo-c.git + GIT_TAG "${AVIF_LOCAL_CARGOC_GIT_TAG}" + GIT_SHALLOW ON + ) + FetchContent_MakeAvailable(cargoc) + + corrosion_import_crate( + MANIFEST_PATH ${cargoc_SOURCE_DIR}/Cargo.toml PROFILE release IMPORTED_CRATES MYVAR_IMPORTED_CRATES FEATURES + vendored-openssl + ) + + set(CARGO_CINSTALL $) +endif() + +FetchContent_Declare( + rav1e + GIT_REPOSITORY https://github.com/xiph/rav1e.git + GIT_TAG "${AVIF_LOCAL_RAV1E_GIT_TAG}" + GIT_SHALLOW ON +) +FetchContent_MakeAvailable(rav1e) + +set(RAV1E_LIBRARY_FILE + ${CMAKE_CURRENT_BINARY_DIR}/ext/rav1e/usr/lib/${CMAKE_STATIC_LIBRARY_PREFIX}rav1e${CMAKE_STATIC_LIBRARY_SUFFIX} +) +set(RAV1E_ENVVARS) +if(CMAKE_C_IMPLICIT_LINK_DIRECTORIES MATCHES "alpine-linux-musl") + list(APPEND RAV1E_ENVVARS "RUSTFLAGS=-C link-args=-Wl,-z,stack-size=2097152 -C target-feature=-crt-static") +endif() +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_SYSROOT) + list(APPEND RAV1E_ENVVARS "SDKROOT=${CMAKE_OSX_SYSROOT}") +endif() +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_DEPLOYMENT_TARGET) + list(APPEND RAV1E_ENVVARS "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") +endif() + +add_custom_target( + rav1e + COMMAND ${CMAKE_COMMAND} -E env ${RAV1E_ENVVARS} ${CARGO_CINSTALL} cinstall -v --release --library-type=staticlib + --prefix=/usr --target ${Rust_CARGO_TARGET_CACHED} --destdir ${CMAKE_CURRENT_BINARY_DIR}/ext/rav1e + DEPENDS cargo-cinstall + BYPRODUCTS ${RAV1E_LIBRARY_FILE} + USES_TERMINAL + WORKING_DIRECTORY ${rav1e_SOURCE_DIR} +) +set(RAV1E_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/rav1e/usr/include/rav1e") +file(MAKE_DIRECTORY ${RAV1E_INCLUDE_DIR}) +set(RAV1E_FOUND ON) + +set(RAV1E_LIBRARIES ${Rust_CARGO_TARGET_LINK_NATIVE_LIBS}) +if(WIN32) + # Remove msvcrt from RAV1E_LIBRARIES since it's linked by default + list(REMOVE_ITEM RAV1E_LIBRARIES "msvcrt.lib" "-lmsvcrt") endif() add_library(rav1e::rav1e STATIC IMPORTED) -set_target_properties(rav1e::rav1e PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" IMPORTED_SONAME rav1e AVIF_LOCAL ON) -target_include_directories(rav1e::rav1e INTERFACE "${AVIF_SOURCE_DIR}/ext/rav1e/build.libavif/usr/include/rav1e") +add_dependencies(rav1e::rav1e rav1e) +target_link_libraries(rav1e::rav1e INTERFACE "${RAV1E_LIBRARIES}") +set_target_properties(rav1e::rav1e PROPERTIES IMPORTED_LOCATION "${RAV1E_LIBRARY_FILE}" AVIF_LOCAL ON FOLDER "ext/rav1e") +target_include_directories(rav1e::rav1e INTERFACE "${RAV1E_INCLUDE_DIR}") diff --git a/cmake/Modules/LocalSvt.cmake b/cmake/Modules/LocalSvt.cmake index 1edc3a68d4..82b5193e8d 100644 --- a/cmake/Modules/LocalSvt.cmake +++ b/cmake/Modules/LocalSvt.cmake @@ -1,8 +1,67 @@ -set(LIB_FILENAME "${AVIF_SOURCE_DIR}/ext/SVT-AV1/Bin/Release/${AVIF_LIBRARY_PREFIX}SvtAv1Enc${CMAKE_STATIC_LIBRARY_SUFFIX}") -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: compiled svt library is missing (in ext/SVT-AV1/Bin/Release), bailing out") +set(AVIF_LOCAL_SVT_GIT_TAG "v1.7.0") + +set(SVT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/SVT-AV1") +if(ANDROID_ABI) + set(SVT_BINARY_DIR "${SVT_BINARY_DIR}/${ANDROID_ABI}") +endif() + +# Workaround https://gitlab.kitware.com/cmake/cmake/-/issues/25042 by enabling ASM before ASM_NASM +if(NOT CMAKE_ASM_COMPILER) + include(CheckLanguage) + check_language(ASM) + if(CMAKE_ASM_COMPILER) + enable_language(ASM) + endif() +endif() +if(NOT CMAKE_ASM_NASM_COMPILER) + include(CheckLanguage) + check_language(ASM_NASM) + if(CMAKE_ASM_NASM_COMPILER) + enable_language(ASM_NASM) + endif() endif() -add_library(SvtAv1Enc STATIC IMPORTED GLOBAL) -set_target_properties(SvtAv1Enc PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -target_include_directories(SvtAv1Enc INTERFACE "${AVIF_SOURCE_DIR}/ext/SVT-AV1/include") +FetchContent_Declare( + svt + GIT_REPOSITORY "https://gitlab.com/AOMediaCodec/SVT-AV1.git" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/SVT-AV1" BINARY_DIR "${SVT_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_SVT_GIT_TAG}" + UPDATE_COMMAND "" + GIT_SHALLOW ON +) + +set(BUILD_DEC OFF CACHE BOOL "") +set(BUILD_APPS OFF CACHE BOOL "") +set(NATIVE OFF CACHE BOOL "") + +set(CMAKE_BUILD_TYPE_ORIG ${CMAKE_BUILD_TYPE}) +set(CMAKE_BUILD_TYPE Release CACHE INTERNAL "") + +avif_fetchcontent_populate_cmake(svt) + +set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE_ORIG} CACHE STRING "" FORCE) + +set(SVT_INCLUDE_DIR ${svt_BINARY_DIR}/include) +file(MAKE_DIRECTORY ${SVT_INCLUDE_DIR}/svt-av1) + +file(GLOB _svt_header_files ${svt_SOURCE_DIR}/Source/API/*.h) + +set(_svt_header_byproducts) + +foreach(_svt_header_file ${_svt_header_files}) + get_filename_component(_svt_header_name "${_svt_header_file}" NAME) + set(_svt_header_output ${SVT_INCLUDE_DIR}/svt-av1/${_svt_header_name}) + add_custom_command( + OUTPUT ${_svt_header_output} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_svt_header_file} ${_svt_header_output} + DEPENDS ${_svt_header_file} + VERBATIM + ) + list(APPEND _svt_header_byproducts ${_svt_header_output}) +endforeach() + +add_custom_target(_svt_install_headers DEPENDS ${_svt_header_byproducts}) +add_dependencies(SvtAv1Enc _svt_install_headers) +set_target_properties(SvtAv1Enc PROPERTIES AVIF_LOCAL ON FOLDER "ext/SVT-AV1") + +target_include_directories(SvtAv1Enc INTERFACE ${SVT_INCLUDE_DIR}) diff --git a/cmake/Modules/LocalZlibpng.cmake b/cmake/Modules/LocalZlibpng.cmake index 4e7b39f3c2..7d7908ee34 100644 --- a/cmake/Modules/LocalZlibpng.cmake +++ b/cmake/Modules/LocalZlibpng.cmake @@ -1,6 +1,15 @@ -# --------------------------------------------------------------------------------------- -# This insanity is for people embedding libavif or making fully static or Windows builds. -# Any proper unix environment should ignore these entire following blocks. +set(AVIF_LOCAL_ZLIB_GIT_TAG v1.3) +set(AVIF_LOCAL_LIBPNG_GIT_TAG v1.6.40) + +set(ZLIB_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/zlib") +FetchContent_Declare( + zlib + GIT_REPOSITORY "https://github.com/madler/zlib.git" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/zlib" BINARY_DIR "${ZLIB_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_ZLIB_GIT_TAG}" + GIT_SHALLOW ON + UPDATE_COMMAND "" +) # Put the value of ZLIB_INCLUDE_DIR in the cache. This works around cmake behavior that has been updated by # cmake policy CMP0102 in cmake 3.17. Remove the CACHE workaround when we require cmake 3.17 or later. See # https://gitlab.kitware.com/cmake/cmake/-/issues/21343. @@ -9,13 +18,15 @@ set(ZLIB_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/zlib" CACHE PATH "zlib include dir" # zlib/CMakeLists.txt bug fixed by https://github.com/madler/zlib/pull/818. include_directories(SYSTEM $) -add_subdirectory(ext/zlib EXCLUDE_FROM_ALL) +if(NOT zlib_POPULATED) + avif_fetchcontent_populate_cmake(zlib) -# Re-enable example and example64 targets, as these are used by tests -if(AVIF_BUILD_TESTS) - set_property(TARGET example PROPERTY EXCLUDE_FROM_ALL FALSE) - if(TARGET example64) - set_property(TARGET example64 PROPERTY EXCLUDE_FROM_ALL FALSE) + # Re-enable example and example64 targets, as these are used by tests + if(AVIF_BUILD_TESTS) + set_property(TARGET example PROPERTY EXCLUDE_FROM_ALL FALSE) + if(TARGET example64) + set_property(TARGET example64 PROPERTY EXCLUDE_FROM_ALL FALSE) + endif() endif() endif() @@ -25,7 +36,7 @@ target_include_directories(zlibstatic INTERFACE $) +include_directories("${ZLIB_BINARY_DIR}") set(CMAKE_DEBUG_POSTFIX "") add_library(ZLIB::ZLIB ALIAS zlibstatic) @@ -38,10 +49,24 @@ set(PNG_SHARED OFF CACHE BOOL "") set(PNG_TESTS OFF CACHE BOOL "") set(PNG_EXECUTABLES OFF CACHE BOOL "") -add_subdirectory("${AVIF_SOURCE_DIR}/ext/libpng" EXCLUDE_FROM_ALL) +set(LIBPNG_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext/libpng") +if(ANDROID_ABI) + set(LIBPNG_BINARY_DIR "${LIBPNG_BINARY_DIR}/${ANDROID_ABI}") +endif() + +FetchContent_Declare( + libpng + GIT_REPOSITORY "https://github.com/glennrp/libpng.git" + SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/libpng" BINARY_DIR "${LIBPNG_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBPNG_GIT_TAG}" + GIT_SHALLOW ON + UPDATE_COMMAND "" +) + +avif_fetchcontent_populate_cmake(libpng) set(PNG_PNG_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/libpng") -include_directories($) +include_directories("${LIBPNG_BINARY_DIR}") set(ANDROID ${PREV_ANDROID}) set_target_properties(png_static zlibstatic PROPERTIES AVIF_LOCAL ON) diff --git a/tests/oss-fuzz/build.sh b/tests/oss-fuzz/build.sh index 1c58ae7843..91f5b123bb 100755 --- a/tests/oss-fuzz/build.sh +++ b/tests/oss-fuzz/build.sh @@ -43,15 +43,11 @@ export CFLAGS="" export CXXFLAGS="" # fuzz flags are problematic with meson (hence no dav1d) and no point in fuzzing fuzztest. -cd ext && bash dav1d.cmd && bash fuzztest.cmd && cd .. +cd ext && bash fuzztest.cmd && cd .. export CFLAGS=$ORIG_CFLAGS export CXXFLAGS=$ORIG_CXXFLAGS -# build dependencies -cd ext && bash aom.cmd && bash libjpeg.cmd && bash libsharpyuv.cmd && \ - bash libyuv.cmd && bash zlibpng.cmd && cd .. - # build libavif mkdir build cd build @@ -74,45 +70,7 @@ ninja # build decode fuzzer $CXX $CXXFLAGS -std=c++11 -I../include \ ../tests/oss-fuzz/avif_decode_fuzzer.cc -o $OUT/avif_decode_fuzzer \ - $LIB_FUZZING_ENGINE libavif.a ../ext/dav1d/build/src/libdav1d.a \ - ../ext/libyuv/build/libyuv.a ../ext/aom/build.libavif/libaom.a - -# Restrict fuzztest tests to the only compatible fuzz engine: libfuzzer. -if [ "$FUZZING_ENGINE" == "libfuzzer" ] -then - # build fuzztests - # The following is taken from https://github.com/google/oss-fuzz/blob/31ac7244748ea7390015455fb034b1f4eda039d9/infra/base-images/base-builder/compile_fuzztests.sh#L59 - # Iterate the fuzz binaries and list each fuzz entrypoint in the binary. For - # each entrypoint create a wrapper script that calls into the binaries the - # given entrypoint as argument. - # The scripts will be named: - # {binary_name}@{fuzztest_entrypoint} - FUZZ_TEST_BINARIES_OUT_PATHS=`ls ./tests/avif_fuzztest_*` - echo "Fuzz binaries: $FUZZ_TEST_BINARIES_OUT_PATHS" - for fuzz_main_file in $FUZZ_TEST_BINARIES_OUT_PATHS; do - FUZZ_TESTS=$($fuzz_main_file --list_fuzz_tests | cut -d ' ' -f 4) - cp -f ${fuzz_main_file} $OUT/ - fuzz_basename=$(basename $fuzz_main_file) - chmod -x $OUT/$fuzz_basename - for fuzz_entrypoint in $FUZZ_TESTS; do - TARGET_FUZZER="${fuzz_basename}@$fuzz_entrypoint" - # Write executer script - echo "#!/bin/sh -# LLVMFuzzerTestOneInput for fuzzer detection. -this_dir=\$(dirname \"\$0\") -export TEST_DATA_DIRS=\$this_dir/corpus -chmod +x \$this_dir/$fuzz_basename -\$this_dir/$fuzz_basename --fuzz=$fuzz_entrypoint -- \$@ -chmod -x \$this_dir/$fuzz_basename" > $OUT/$TARGET_FUZZER - chmod +x $OUT/$TARGET_FUZZER - done - done -fi - -# copy seed corpus for fuzztest tests -mkdir $OUT/corpus -unzip $SRC/avif_decode_seed_corpus.zip -d $OUT/corpus -cp $SRC/libavif/tests/data/* $OUT/corpus + $LIB_FUZZING_ENGINE libavif.a -# create a bigger seed corpus for avif_decode_fuzzer -zip -j $OUT/avif_decode_fuzzer_seed_corpus.zip $OUT/corpus/* +# copy seed corpus +cp $SRC/avif_decode_seed_corpus.zip $OUT/