diff --git a/.github/workflows/ci-android-emulator-tests.yml b/.github/workflows/ci-android-emulator-tests.yml index 99593716bb..dbfec722f3 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 95963f4eea..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@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - 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 48a6fa5247..e946b16a27 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@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 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-mingw.yml b/.github/workflows/ci-mingw.yml index aae454ab03..922baf647f 100644 --- a/.github/workflows/ci-mingw.yml +++ b/.github/workflows/ci-mingw.yml @@ -46,22 +46,8 @@ jobs: libyuv:p ninja:p zlib:p - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - with: - path: ext - key: ${{ matrix.sys }}-mingw-${{ hashFiles('ext/*.cmd') }} - name: Print cmake version run: cmake --version - - name: Build libsharpyuv - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./libsharpyuv.cmd - - name: Build GoogleTest - if: steps.cache-ext.outputs.cache-hit != 'true' - working-directory: ./ext - run: ./googletest.cmd - name: Prepare libavif (cmake) run: > diff --git a/.github/workflows/ci-unix-shared-installed.yml b/.github/workflows/ci-unix-shared-installed.yml index 13052aa4f4..9786770544 100644 --- a/.github/workflows/ci-unix-shared-installed.yml +++ b/.github/workflows/ci-unix-shared-installed.yml @@ -33,13 +33,6 @@ jobs: # TODO(yguyon): Install libyuv (not available with brew). if: runner.os == 'macOS' run: echo "CMAKE_AVIF_FLAGS=\"-DAVIF_LIBYUV=OFF\"" >> $GITHUB_ENV - - - name: Cache external dependencies - id: cache-ext - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - with: - path: ext - key: ${{ runner.os }}-shared-installed-${{ hashFiles('ext/*.cmd') }} - name: Setup cmake uses: jwlawson/actions-setup-cmake@d06b37b47cfd043ec794ffa3e40e0b6b5858a7ec # v1.14.2 with: @@ -62,11 +55,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 079b67e0e9..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@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - 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 4fe842672f..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@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - 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 8840751213..12e0c91de9 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@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - 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 @@ -104,12 +76,22 @@ jobs: -DAVIF_CODEC_RAV1E=LOCAL -DAVIF_CODEC_SVT=LOCAL -DAVIF_CODEC_LIBGAV1=LOCAL -DAVIF_LIBYUV=LOCAL -DAVIF_LIBSHARPYUV=LOCAL + -DAVIF_LOCAL_LIBARGPARSE=ON -DAVIF_BUILD_EXAMPLES=ON -DAVIF_BUILD_APPS=ON -DAVIF_BUILD_TESTS=ON -DAVIF_ENABLE_GTEST=ON -DAVIF_LOCAL_GTEST=ON -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') }}-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 91a71b81d9..31a4853dcb 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -48,7 +48,13 @@ jobs: uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 with: path: ext - key: ${{ runner.os }}-${{ hashFiles('ext/*.cmd') }}-alldeps + key: ${{ runner.os }}-${{ hashFiles('ext/aom.cmd', 'ext/libyuv.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 @@ -68,22 +74,6 @@ jobs: env: CC: clang-cl CXX: clang-cl - - 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 @@ -93,22 +83,6 @@ jobs: env: CC: clang-cl CXX: clang-cl - - 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: > @@ -126,6 +100,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 @@ -138,16 +120,16 @@ jobs: /DWIN32 /D_WINDOWS /MD /O2 /Ob2 -I.\apps\shared -I.\include -I.\third_party\iccjpeg -external:W0 - -external:I.\ext\libpng - -external:I.\ext\libjpeg-turbo - -external:I.\ext\libjpeg-turbo\build.libavif - -external:I.\ext\zlib - -external:I.\build\ext\libpng - -external:I.\build\ext\zlib + -external:I.\build\_deps\libpng-src + -external:I.\build\libjpeg\src\libjpeg + -external:I.\build\libjpeg\src\libjpeg-build + -external:I.\build\_deps\zlib-src + -external:I.\build\_deps\libpng + -external:I.\build\_deps\zlib /link - ext\libjpeg-turbo\build.libavif\jpeg-static.lib - build\ext\libpng\libpng16_static.lib - build\ext\zlib\zlibstatic.lib + build\libjpeg\src\libjpeg-build\jpeg-static.lib + build\_deps\libpng\libpng16_static.lib + build\_deps\zlib\zlibstatic.lib build\avif.lib ws2_32.lib ntdll.lib userenv.lib bcrypt.lib advapi32.lib /out:avifenc.exe diff --git a/CMakeLists.txt b/CMakeLists.txt index 30644e8a6b..8214ab18de 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.4) # 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 @@ -450,10 +464,13 @@ if(AVIF_CODEC_RAV1E_ENABLED) target_sources(avif_obj PRIVATE src/codec_rav1e.c) # Unfortunately, rav1e requires a few more libraries - if(WIN32) - target_link_libraries(rav1e::rav1e INTERFACE ntdll.lib userenv.lib ws2_32.lib bcrypt.lib) - elseif(UNIX AND NOT APPLE) - target_link_libraries(rav1e::rav1e INTERFACE ${CMAKE_DL_LIBS}) # for backtrace + # first check that RAV1E_LIBRARIES hasn't been populated by the LocalRav1e module + if(NOT RAV1E_LIBRARIES) + if(WIN32) + target_link_libraries(rav1e::rav1e INTERFACE ntdll.lib userenv.lib ws2_32.lib bcrypt.lib) + elseif(UNIX AND NOT APPLE) + target_link_libraries(rav1e::rav1e INTERFACE ${CMAKE_DL_LIBS}) # for backtrace + endif() endif() avif_target_link_library(rav1e::rav1e) @@ -716,8 +733,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 +760,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..714e30009e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,8 +23,6 @@ install: - 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..4a40b10412 100644 --- a/cmake/Modules/LocalAom.cmake +++ b/cmake/Modules/LocalAom.cmake @@ -1,8 +1,150 @@ -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.8.1) +set(AVIF_LOCAL_AVM_GIT_TAG research-v6.0.0) + +if(AVIF_CODEC_AVM) + # Building the avm repository generates files such as "libaom.a" because it is a fork of aom, + # so its build can be treated the same as aom + set(AOM_PACKAGE_NAME avm) + set(AOM_MESSAGE_PREFIX "libavif(AVIF_CODEC_AVM=LOCAL)") +else() + set(AOM_PACKAGE_NAME aom) + set(AOM_MESSAGE_PREFIX "libavif(AVIF_CODEC_AOM=LOCAL)") 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/aom") +set(AOM_EXT_SOURCE_DIR "${AVIF_SOURCE_DIR}/ext/${AOM_PACKAGE_NAME}") +set(LIB_FILENAME "${AVIF_SOURCE_DIR}/ext/aom/build.libavif/${CMAKE_STATIC_LIBRARY_PREFIX}aom${CMAKE_STATIC_LIBRARY_SUFFIX}") + +if(EXISTS "${LIB_FILENAME}") + message(STATUS "${AOM_MESSAGE_PREFIX}: compiled library found at ${LIB_FILENAME}") + add_library(aom STATIC IMPORTED GLOBAL) + set_target_properties(aom PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) + target_include_directories(aom INTERFACE "${AOM_EXT_SOURCE_DIR}") + if(AVIF_CODEC_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 "${AOM_EXT_SOURCE_DIR}/build.libavif") + endif() +else() + message(STATUS "${AOM_MESSAGE_PREFIX}: compiled library not found at ${LIB_FILENAME}, using FetchContent") + if(EXISTS "${AOM_EXT_SOURCE_DIR}") + message(STATUS "${AOM_MESSAGE_PREFIX}: ext/${AOM_PACKAGE_NAME} found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_AOM "${AOM_EXT_SOURCE_DIR}") + message(CHECK_START "${AOM_MESSAGE_PREFIX}: configuring ${AOM_PACKAGE_NAME}") + else() + message(CHECK_START "${AOM_MESSAGE_PREFIX}: fetching and configuring ${AOM_PACKAGE_NAME}") + 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() + + set(AOM_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${AOM_PACKAGE_NAME}-build") + + 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" + BINARY_DIR "${AOM_BINARY_DIR}" + GIT_TAG ${AVIF_LOCAL_AVM_GIT_TAG} + GIT_PROGRESS ON + GIT_SHALLOW ON + UPDATE_COMMAND "" + ) + else() + FetchContent_Declare( + libaom URL "https://aomedia.googlesource.com/aom/+archive/${AVIF_LOCAL_AOM_GIT_TAG}.tar.gz" BINARY_DIR + "${AOM_BINARY_DIR}" UPDATE_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}) + + message(CHECK_PASS "complete") +endif() 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..d516568682 100644 --- a/cmake/Modules/LocalDav1d.cmake +++ b/cmake/Modules/LocalDav1d.cmake @@ -1,25 +1,132 @@ +set(AVIF_LOCAL_DAV1D_TAG "1.4.0") + +function(avif_build_local_dav1d) + set(download_step_args) + if(EXISTS "${AVIF_SOURCE_DIR}/ext/dav1d") + message(STATUS "libavif(AVIF_CODEC_DAV1D=LOCAL): ext/dav1d found, using as SOURCE_DIR") + set(source_dir "${AVIF_SOURCE_DIR}/ext/dav1d") + else() + message(STATUS "libavif(AVIF_CODEC_DAV1D=LOCAL): ext/dav1d not found, fetching") + set(source_dir "${FETCHCONTENT_BASE_DIR}/dav1d-src") + list(APPEND download_step_args GIT_REPOSITORY https://code.videolan.org/videolan/dav1d.git GIT_TAG + ${AVIF_LOCAL_DAV1D_TAG} GIT_SHALLOW ON + ) + endif() + + 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") + + 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() + + if(CROSS_FILE) + set(EXTRA_ARGS "--cross-file=${CROSS_FILE}") + endif() + + set(build_dir "${FETCHCONTENT_BASE_DIR}/dav1d-build") + set(install_dir "${FETCHCONTENT_BASE_DIR}/dav1d-install") + + if(ANDROID_ABI) + set(build_dir "${build_dir}/${ANDROID_ABI}") + set(install_dir "${install_dir}/${ANDROID_ABI}") + endif() + file(MAKE_DIRECTORY ${install_dir}/include) + + ExternalProject_Add( + dav1d + ${download_step_args} + DOWNLOAD_DIR "${source_dir}" + LOG_DIR "${build_dir}" + STAMP_DIR "${build_dir}" + TMP_DIR "${build_dir}" + SOURCE_DIR "${source_dir}" + BINARY_DIR "${build_dir}" + INSTALL_DIR "${install_dir}" + LIST_SEPARATOR | + 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_dir}/lib/libdav1d.a AVIF_LOCAL ON) + target_include_directories(dav1d::dav1d INTERFACE "${install_dir}/include") + target_link_directories(dav1d::dav1d INTERFACE ${install_dir}/lib) + add_dependencies(dav1d::dav1d dav1d) +endfunction() + 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}") 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") - endif() - endif() +if(NOT EXISTS "${LIB_FILENAME}" AND NOT "${CMAKE_STATIC_LIBRARY_SUFFIX}" STREQUAL ".a") + # 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_DAV1D_BUILD_DIR}/src/libdav1d.a") endif() +if(EXISTS "${LIB_FILENAME}") + message(STATUS "libavif(AVIF_CODEC_DAV1D=LOCAL): compiled library found at ${LIB_FILENAME}") + 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" + ) +else() + message(STATUS "libavif(AVIF_CODEC_DAV1D=LOCAL): compiled library not found at ${LIB_FILENAME}; using ExternalProject") -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" -) + avif_build_local_dav1d() +endif() + +if(EXISTS "${AVIF_SOURCE_DIR}/ext/dav1d") + set_target_properties(dav1d::dav1d PROPERTIES FOLDER "ext/dav1d") +endif() diff --git a/cmake/Modules/LocalGoogletest.cmake b/cmake/Modules/LocalGoogletest.cmake index c26f2db392..4c17c72d5c 100644 --- a/cmake/Modules/LocalGoogletest.cmake +++ b/cmake/Modules/LocalGoogletest.cmake @@ -1,3 +1,6 @@ +set(AVIF_LOCAL_GTEST_GIT_TAG v1.14.0) + +set(GTest_FOUND ON CACHE BOOL "") 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} @@ -5,24 +8,45 @@ set(GTEST_LIB_FILENAME set(GTEST_MAIN_LIB_FILENAME ${AVIF_SOURCE_DIR}/ext/googletest/build/lib/${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} ) -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") +if(EXISTS ${GTEST_INCLUDE_DIRS}/gtest/gtest.h AND EXISTS ${GTEST_LIB_FILENAME} AND EXISTS ${GTEST_MAIN_LIB_FILENAME}) + message(STATUS "libavif(AVIF_LOCAL_GTEST): compiled library found in ext/googletest") + + add_library(GTest::gtest STATIC IMPORTED) + set_target_properties(GTest::gtest PROPERTIES IMPORTED_LOCATION "${GTEST_LIB_FILENAME}" AVIF_LOCAL ON) + + 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) else() - message(STATUS "Found local ext/googletest") -endif() + message(STATUS "libavif(AVIF_LOCAL_GTEST): compiled library not found in ext/googletest; using FetchContent") + if(EXISTS "${AVIF_SOURCE_DIR}/ext/googletest") + message(STATUS "libavif(AVIF_LOCAL_GTEST): ext/googletest found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_GOOGLETEST "${AVIF_SOURCE_DIR}/ext/googletest") + message(CHECK_START "libavif(AVIF_LOCAL_GTEST): configuring googletest") + else() + message(CHECK_START "libavif(AVIF_LOCAL_GTEST): fetching and configuring googletest") + endif() -add_library(GTest::gtest STATIC IMPORTED) -set_target_properties(GTest::gtest PROPERTIES IMPORTED_LOCATION "${GTEST_LIB_FILENAME}" AVIF_LOCAL ON) + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG ${AVIF_LOCAL_GTEST_GIT_TAG} + GIT_SHALLOW ON + ) + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + set(BUILD_GMOCK ON CACHE BOOL "" FORCE) -if(TARGET Threads::Threads) - target_link_libraries(GTest::gtest INTERFACE Threads::Threads) -endif() -target_include_directories(GTest::gtest INTERFACE "${GTEST_INCLUDE_DIRS}") + avif_fetchcontent_populate_cmake(googletest) + + set_target_properties(gtest gtest_main PROPERTIES AVIF_LOCAL ON) -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) + add_library(GTest::gtest ALIAS gtest) + add_library(GTest::gtest_main ALIAS gtest_main) + + message(CHECK_PASS "complete") +endif() diff --git a/cmake/Modules/LocalJpeg.cmake b/cmake/Modules/LocalJpeg.cmake index b91b0740e5..818337205b 100644 --- a/cmake/Modules/LocalJpeg.cmake +++ b/cmake/Modules/LocalJpeg.cmake @@ -1,16 +1,53 @@ +set(AVIF_LOCAL_JPEG_TAG "3.0.2") + +add_library(JPEG::JPEG STATIC IMPORTED GLOBAL) + set(LIB_DIR "${AVIF_SOURCE_DIR}/ext/libjpeg-turbo/build.libavif") if(MSVC) set(LIB_FILENAME "${LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}jpeg-static${CMAKE_STATIC_LIBRARY_SUFFIX}") else() set(LIB_FILENAME "${LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}jpeg${CMAKE_STATIC_LIBRARY_SUFFIX}") endif() -if(NOT EXISTS "${LIB_FILENAME}") - message(FATAL_ERROR "libavif: ${LIB_FILENAME} is missing, bailing out") +if(EXISTS "${LIB_FILENAME}") + message(STATUS "libavif(AVIF_LOCAL_JPEG): ${LIB_FILENAME} found, using for local JPEG") + set(JPEG_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/libjpeg-turbo") +else() + message(STATUS "libavif(AVIF_LOCAL_JPEG): ${LIB_FILENAME} not found, fetching") + set(LIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/libjpeg/src/libjpeg-build") + if(MSVC) + set(LIB_FILENAME "${LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}jpeg-static${CMAKE_STATIC_LIBRARY_SUFFIX}") + else() + set(LIB_FILENAME "${LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}jpeg${CMAKE_STATIC_LIBRARY_SUFFIX}") + endif() + + set(JPEG_INSTALL_DIR "${prefix}/libjpeg-install") + + ExternalProject_Add( + libjpeg + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libjpeg + GIT_REPOSITORY "https://github.com/libjpeg-turbo/libjpeg-turbo.git" + GIT_TAG "${AVIF_LOCAL_JPEG_TAG}" + LIST_SEPARATOR | + BUILD_COMMAND ${CMAKE_COMMAND} --build --config $ --target jpeg-static + CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} + -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} + -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} + -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} + -DENABLE_SHARED=OFF + -DENABLE_STATIC=ON + -DCMAKE_BUILD_TYPE=Release + -DWITH_TURBOJPEG=OFF + BUILD_BYPRODUCTS "${LIB_FILENAME}" + INSTALL_COMMAND "" + ) + add_dependencies(JPEG::JPEG libjpeg) + set(JPEG_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/libjpeg/src/libjpeg) endif() -add_library(JPEG::JPEG STATIC IMPORTED GLOBAL) set_target_properties(JPEG::JPEG PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}" AVIF_LOCAL ON) -set(JPEG_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/libjpeg-turbo") target_include_directories(JPEG::JPEG INTERFACE "${JPEG_INCLUDE_DIR}") # Also add the build directory path because it contains jconfig.h, diff --git a/cmake/Modules/LocalLibXml2.cmake b/cmake/Modules/LocalLibXml2.cmake index 598a0bd55e..97f9eee510 100644 --- a/cmake/Modules/LocalLibXml2.cmake +++ b/cmake/Modules/LocalLibXml2.cmake @@ -1,9 +1,46 @@ +set(AVIF_LOCAL_LIBXML_GIT_TAG "v2.11.5") + 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") -endif() +if(EXISTS "${LIB_FILENAME}") + message(STATUS "libavif(AVIF_LOCAL_LIBXML2): compiled library found at ${LIB_FILENAME}") + 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) +else() + message(STATUS "libavif(AVIF_LOCAL_LIBXML2): compiled library not found at ${LIB_FILENAME}; using FetchContent") + if(EXISTS "${AVIF_SOURCE_DIR}/ext/libxml2") + message(STATUS "libavif(AVIF_LOCAL_LIBXML2): ext/libxml2 found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_LIBXML2 "${AVIF_SOURCE_DIR}/ext/libxml2") + message(CHECK_START "libavif(AVIF_LOCAL_LIBXML2): configuring libxml2") + else() + message(CHECK_START "libavif(AVIF_LOCAL_LIBXML2): fetching and configuring libxml2") + endif() + + 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 "${FETCHCONTENT_BASE_DIR}/libxml2-build") + 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" + 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) + + message(CHECK_PASS "complete") +endif() diff --git a/cmake/Modules/LocalLibargparse.cmake b/cmake/Modules/LocalLibargparse.cmake index 012aafe85d..870b272c50 100644 --- a/cmake/Modules/LocalLibargparse.cmake +++ b/cmake/Modules/LocalLibargparse.cmake @@ -1,10 +1,35 @@ +set(AVIF_LOCAL_LIBARGPARSE_GIT_TAG ee74d1b53bd680748af14e737378de57e2a0a954) + set(LIBARGPARSE_FILENAME "${AVIF_SOURCE_DIR}/ext/libargparse/build/${CMAKE_STATIC_LIBRARY_PREFIX}argparse${CMAKE_STATIC_LIBRARY_SUFFIX}" ) + if(EXISTS "${LIBARGPARSE_FILENAME}") + message(STATUS "libavif(AVIF_LOCAL_LIBARGPARSE): compiled library found at ${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") + message(STATUS "libavif(AVIF_LOCAL_LIBARGPARSE): compiled library not found at ${LIBARGPARSE_FILENAME}; using FetchContent") + if(EXISTS "${AVIF_SOURCE_DIR}/ext/libargparse") + message(STATUS "libavif(AVIF_LOCAL_LIBARGPARSE): ext/libargparse found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_LIBARGPARSE "${AVIF_SOURCE_DIR}/ext/libargparse") + message(CHECK_START "libavif(AVIF_LOCAL_LIBARGPARSE): configuring libargparse") + else() + message(CHECK_START "libavif(AVIF_LOCAL_LIBARGPARSE): fetching and configuring libargparse") + endif() + + FetchContent_Declare( + libargparse + GIT_REPOSITORY "https://github.com/kmurray/libargparse.git" + GIT_TAG ${AVIF_LOCAL_LIBARGPARSE_GIT_TAG} + UPDATE_COMMAND "" + ) + avif_fetchcontent_populate_cmake(libargparse) + + message(CHECK_PASS "complete") +endif() + +if(EXISTS "${AVIF_SOURCE_DIR}/ext/libargparse") + set_target_properties(libargparse PROPERTIES FOLDER "ext/libargparse") endif() diff --git a/cmake/Modules/LocalLibgav1.cmake b/cmake/Modules/LocalLibgav1.cmake index c383497ec7..d5f9f7264e 100644 --- a/cmake/Modules/LocalLibgav1.cmake +++ b/cmake/Modules/LocalLibgav1.cmake @@ -1,14 +1,54 @@ +set(AVIF_LOCAL_LIBGAV1_GIT_TAG "v0.19.0") + 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") + +if(EXISTS "${LIB_FILENAME}") + message(STATUS "libavif(AVIF_CODEC_LIBGAV1=LOCAL): compiled library found at ${LIB_FILENAME}") + add_library(libgav1_static STATIC IMPORTED GLOBAL) + set_target_properties(libgav1_static PROPERTIES IMPORTED_LOCATION "${LIB_FILENAME}") + target_include_directories(libgav1_static INTERFACE "${AVIF_SOURCE_DIR}/ext/libgav1/src") +else() + message(STATUS "libavif(AVIF_CODEC_LIBGAV1=LOCAL): compiled library not found at ${LIB_FILENAME}; using FetchContent") + + if(EXISTS "${AVIF_SOURCE_DIR}/ext/libgav1") + message(STATUS "libavif(AVIF_CODEC_LIBGAV1=LOCAL): ext/libgav1 found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_LIBGAV1 "${AVIF_SOURCE_DIR}/ext/libgav1") + message(CHECK_START "libavif(AVIF_CODEC_LIBGAV1=LOCAL): configuring libgav1") + else() + message(CHECK_START "libavif(AVIF_CODEC_LIBGAV1=LOCAL): fetching and configuring libgav1") + endif() + + set(LIBGAV1_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/libgav1-build") + if(ANDROID_ABI) + set(LIBGAV1_BINARY_DIR "${LIBGAV1_BINARY_DIR}/${ANDROID_ABI}") + endif() + + 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 "") + + FetchContent_Declare( + libgav1 + GIT_REPOSITORY "https://chromium.googlesource.com/codecs/libgav1" + BINARY_DIR "${LIBGAV1_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBGAV1_GIT_TAG}" + GIT_SHALLOW ON + UPDATE_COMMAND "" + ) + + avif_fetchcontent_populate_cmake(libgav1) + message(CHECK_PASS "complete") 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") +set_property(TARGET libgav1_static PROPERTY AVIF_LOCAL ON) add_library(libgav1::libgav1 ALIAS libgav1_static) + +if(EXISTS "${AVIF_SOURCE_DIR}/ext/libgav1") + set_property(TARGET libgav1_static PROPERTY FOLDER "ext/libgav1") +endif() diff --git a/cmake/Modules/LocalLibsharpyuv.cmake b/cmake/Modules/LocalLibsharpyuv.cmake index 73aacac275..468f6be6e3 100644 --- a/cmake/Modules/LocalLibsharpyuv.cmake +++ b/cmake/Modules/LocalLibsharpyuv.cmake @@ -1,10 +1,62 @@ +set(AVIF_LOCAL_LIBSHARPYUV_GIT_TAG v1.3.2) + 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") -endif() +if(EXISTS "${LIB_FILENAME}") + message(STATUS "libavif(AVIF_LIBSHARPYUV=LOCAL): compiled library found at ${LIB_FILENAME}") + 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") + + set(libsharpyuv_FOUND ON) +else() + message(STATUS "libavif(AVIF_LIBSHARPYUV=LOCAL): compiled library not found at ${LIB_FILENAME}; using FetchContent") + + if(EXISTS "${AVIF_SOURCE_DIR}/ext/libwebp") + message(STATUS "libavif(AVIF_LIBSHARPYUV=LOCAL): ext/libwebp found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_LIBWEBP "${AVIF_SOURCE_DIR}/ext/libwebp") + message(CHECK_START "libavif(AVIF_LIBSHARPYUV=LOCAL): configuring libwebp") + else() + message(CHECK_START "libavif(AVIF_LIBSHARPYUV=LOCAL): fetching and configuring libwebp") + endif() + + 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 "${FETCHCONTENT_BASE_DIR}/libwebp") + if(ANDROID_ABI) + set(LIBSHARPYUV_BINARY_DIR "${LIBSHARPYUV_BINARY_DIR}/${ANDROID_ABI}") + endif() -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") + FetchContent_Declare( + libwebp + GIT_REPOSITORY "https://chromium.googlesource.com/webm/libwebp" + BINARY_DIR "${LIBSHARPYUV_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBSHARPYUV_GIT_TAG}" + GIT_SHALLOW ON + UPDATE_COMMAND "" + ) -set(libsharpyuv_FOUND ON) + avif_fetchcontent_populate_cmake(libwebp) + + set_property(TARGET sharpyuv PROPERTY POSITION_INDEPENDENT_CODE ON) + set_property(TARGET sharpyuv PROPERTY AVIF_LOCAL ON) + + target_include_directories( + sharpyuv INTERFACE $ $ + ) + + add_library(sharpyuv::sharpyuv ALIAS sharpyuv) + message(CHECK_PASS "complete") +endif() + +if(EXISTS "${AVIF_SOURCE_DIR}/ext/libwebp") + set_property(TARGET sharpyuv PROPERTY FOLDER "ext/libwebp") +endif() diff --git a/cmake/Modules/LocalLibyuv.cmake b/cmake/Modules/LocalLibyuv.cmake index 5ef11c7d02..829fb33558 100644 --- a/cmake/Modules/LocalLibyuv.cmake +++ b/cmake/Modules/LocalLibyuv.cmake @@ -1,22 +1,58 @@ -set(AVIF_LIBYUV_BUILD_DIR "${AVIF_SOURCE_DIR}/ext/libyuv/build") +set(AVIF_LOCAL_LIBYUV_TAG "a6a2ec654b1be1166b376476a7555c89eca0c275") +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}") 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") -endif() +if(EXISTS "${LIB_FILENAME}") + message(STATUS "libavif(AVIF_LIBYUV=LOCAL): compiled library found at ${LIB_FILENAME}") + 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}") + set_target_properties(yuv::yuv PROPERTIES FOLDER "ext/libyuv") +else() + message(STATUS "libavif(AVIF_LIBYUV=LOCAL): compiled library not found at ${LIB_FILENAME}; using FetchContent") + if(EXISTS "${AVIF_SOURCE_DIR}/ext/libyuv") + message(STATUS "libavif(AVIF_LIBYUV=LOCAL): ext/libyuv found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_LIBYUV "${AVIF_SOURCE_DIR}/ext/libyuv") + message(CHECK_START "libavif(AVIF_LIBYUV=LOCAL): configuring libyuv") + else() + message(CHECK_START "libavif(AVIF_LIBYUV=LOCAL): fetching and configuring libyuv") + endif() + + set(LIBYUV_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/libyuv-build") + if(ANDROID_ABI) + set(LIBYUV_BINARY_DIR "${LIBYUV_BINARY_DIR}/${ANDROID_ABI}") + endif() + FetchContent_Declare( + libyuv + GIT_REPOSITORY "https://chromium.googlesource.com/libyuv/libyuv" + BINARY_DIR "${LIBYUV_BINARY_DIR}" + GIT_TAG "${AVIF_LOCAL_LIBYUV_TAG}" + UPDATE_COMMAND "" + ) -message(STATUS "libavif: local libyuv found; libyuv-based fast paths enabled.") + avif_fetchcontent_populate_cmake(libyuv) -set(LIBYUV_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/libyuv/include") + set_target_properties(yuv PROPERTIES AVIF_LOCAL ON POSITION_INDEPENDENT_CODE ON) -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}") + add_library(yuv::yuv ALIAS yuv) + + set(LIBYUV_INCLUDE_DIR "${libyuv_SOURCE_DIR}/include") + + target_include_directories(yuv INTERFACE ${LIBYUV_INCLUDE_DIR}) + + if(EXISTS "${AVIF_SOURCE_DIR}/ext/libyuv") + set_target_properties(yuv PROPERTIES FOLDER "ext/libyuv") + endif() + + message(CHECK_PASS "complete") +endif() set(libyuv_FOUND ON) diff --git a/cmake/Modules/LocalRav1e.cmake b/cmake/Modules/LocalRav1e.cmake index 642934d926..97dbea8a89 100644 --- a/cmake/Modules/LocalRav1e.cmake +++ b/cmake/Modules/LocalRav1e.cmake @@ -1,8 +1,113 @@ -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") -endif() +set(AVIF_LOCAL_RAV1E_GIT_TAG v0.7.0) +set(AVIF_LOCAL_CORROSION_GIT_TAG v0.4.4) +set(AVIF_LOCAL_CARGOC_GIT_TAG v0.9.27) + +set(RAV1E_LIB_FILENAME + "${AVIF_SOURCE_DIR}/ext/rav1e/build.libavif/usr/lib/${AVIF_LIBRARY_PREFIX}rav1e${CMAKE_STATIC_LIBRARY_SUFFIX}" +) + +if(EXISTS "${RAV1E_LIB_FILENAME}") + message(STATUS "libavif(AVIF_CODEC_RAV1E=LOCAL): compiled rav1e library found at ${RAV1E_LIB_FILENAME}") + add_library(rav1e::rav1e STATIC IMPORTED) + set_target_properties(rav1e::rav1e PROPERTIES IMPORTED_LOCATION "${RAV1E_LIB_FILENAME}" IMPORTED_SONAME rav1e AVIF_LOCAL ON) + target_include_directories(rav1e::rav1e INTERFACE "${AVIF_SOURCE_DIR}/ext/rav1e/build.libavif/usr/include/rav1e") +else() + message( + STATUS "libavif(AVIF_CODEC_RAV1E=LOCAL): compiled rav1e library not found at ${RAV1E_LIB_FILENAME}; using FetchContent" + ) + if(EXISTS "${AVIF_SOURCE_DIR}/ext/rav1e") + message(STATUS "libavif(AVIF_CODEC_RAV1E=LOCAL): ext/rav1e found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_RAV1E "${AVIF_SOURCE_DIR}/ext/rav1e") + message(CHECK_START "libavif(AVIF_CODEC_RAV1E=LOCAL): configuring rav1e") + else() + message(CHECK_START "libavif(AVIF_CODEC_RAV1E=LOCAL): fetching and configuring rav1e") + endif() + + 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) -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") + 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_LIB_FILENAME + ${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_LIB_FILENAME} + 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) + add_dependencies(rav1e::rav1e rav1e) + target_link_libraries(rav1e::rav1e INTERFACE "${RAV1E_LIBRARIES}") + set_target_properties(rav1e::rav1e PROPERTIES IMPORTED_LOCATION "${RAV1E_LIB_FILENAME}" AVIF_LOCAL ON FOLDER "ext/rav1e") + target_include_directories(rav1e::rav1e INTERFACE "${RAV1E_INCLUDE_DIR}") + + message(CHECK_PASS "complete") +endif() diff --git a/cmake/Modules/LocalSvt.cmake b/cmake/Modules/LocalSvt.cmake index 1edc3a68d4..c41534cfda 100644 --- a/cmake/Modules/LocalSvt.cmake +++ b/cmake/Modules/LocalSvt.cmake @@ -1,8 +1,95 @@ +set(AVIF_LOCAL_SVT_GIT_TAG "v1.7.0") + 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") + +if(EXISTS "${LIB_FILENAME}") + message(STATUS "libavif(AVIF_CODEC_SVT=LOCAL): compiled library found at ${LIB_FILENAME}") + 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") +else() + message(STATUS "libavif(AVIF_CODEC_SVT=LOCAL): compiled library not found at ${LIB_FILENAME}; using FetchContent") + if(EXISTS "${AVIF_SOURCE_DIR}/ext/SVT-AV1") + message(STATUS "libavif(AVIF_CODEC_SVT=LOCAL): ext/SVT-AV1 found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_SVT "${AVIF_SOURCE_DIR}/ext/SVT-AV1") + message(CHECK_START "libavif(AVIF_CODEC_SVT=LOCAL): configuring SVT-AV1") + else() + message(CHECK_START "libavif(AVIF_CODEC_SVT=LOCAL): fetching and configuring SVT-AV1") + endif() + + set(SVT_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/svt-build") + 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() + + FetchContent_Declare( + svt + GIT_REPOSITORY "https://gitlab.com/AOMediaCodec/SVT-AV1.git" + 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 "") + + set(CMAKE_OUTPUT_DIRECTORY_ORIG "${CMAKE_OUTPUT_DIRECTORY}") + set(CMAKE_OUTPUT_DIRECTORY "${SVT_BINARY_DIR}" CACHE INTERNAL "") + + avif_fetchcontent_populate_cmake(svt) + + set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE_ORIG} CACHE STRING "" FORCE) + set(CMAKE_OUTPUT_DIRECTORY ${CMAKE_OUTPUT_DIRECTORY_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) + + target_include_directories(SvtAv1Enc INTERFACE ${SVT_INCLUDE_DIR}) + + message(CHECK_PASS "complete") 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") +if(EXISTS "${AVIF_SOURCE_DIR}/ext/SVT-AV1") + set_target_properties(SvtAv1Enc PROPERTIES FOLDER "ext/SVT-AV1") +endif() diff --git a/cmake/Modules/LocalZlibpng.cmake b/cmake/Modules/LocalZlibpng.cmake index 4e7b39f3c2..cc7076faec 100644 --- a/cmake/Modules/LocalZlibpng.cmake +++ b/cmake/Modules/LocalZlibpng.cmake @@ -1,21 +1,46 @@ -# --------------------------------------------------------------------------------------- -# 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) + +if(EXISTS "${AVIF_SOURCE_DIR}/ext/zlib") + message(STATUS "libavif(AVIF_ZLIBPNG=LOCAL): ext/zlib found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_ZLIB "${AVIF_SOURCE_DIR}/ext/zlib") + message(CHECK_START "libavif(AVIF_ZLIBPNG=LOCAL): configuring zlib") +else() + message(CHECK_START "libavif(AVIF_ZLIBPNG=LOCAL): fetching and configuring zlib") +endif() + +set(ZLIB_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/zlib-src") +set(ZLIB_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/zlib") +if(ANDROID_ABI) + set(ZLIB_BINARY_DIR "${ZLIB_BINARY_DIR}/${ANDROID_ABI}") +endif() + +FetchContent_Declare( + zlib + GIT_REPOSITORY "https://github.com/madler/zlib.git" + SOURCE_DIR "${ZLIB_SOURCE_DIR}" 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. -set(ZLIB_INCLUDE_DIR "${AVIF_SOURCE_DIR}/ext/zlib" CACHE PATH "zlib include dir") +set(ZLIB_INCLUDE_DIR "${ZLIB_SOURCE_DIR}" CACHE PATH "zlib include dir") # This include_directories() call must be before add_subdirectory(ext/zlib) to work around the # 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,24 +50,50 @@ target_include_directories(zlibstatic INTERFACE $) +include_directories("${zlib_BINARY_DIR}") set(CMAKE_DEBUG_POSTFIX "") add_library(ZLIB::ZLIB ALIAS zlibstatic) +message(CHECK_PASS "complete") + +if(EXISTS "${AVIF_SOURCE_DIR}/ext/libpng") + message(STATUS "libavif(AVIF_ZLIBPNG=LOCAL): ext/libpng found; using as FetchContent SOURCE_DIR") + set(FETCHCONTENT_SOURCE_DIR_LIBPNG "${AVIF_SOURCE_DIR}/ext/libpng") + message(CHECK_START "libavif(AVIF_ZLIBPNG=LOCAL): configuring libpng") +else() + message(CHECK_START "libavif(AVIF_ZLIBPNG=LOCAL): fetching and configuring libpng") +endif() + # This is the only way I could avoid libpng going crazy if it found awk.exe, seems benign otherwise set(PREV_ANDROID ${ANDROID}) set(ANDROID TRUE) -set(PNG_BUILD_ZLIB "${AVIF_SOURCE_DIR}/ext/zlib" CACHE STRING "" FORCE) +set(PNG_BUILD_ZLIB "${zlib_SOURCE_DIR}" CACHE STRING "" FORCE) 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 "${FETCHCONTENT_BASE_DIR}/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" + 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($) +set(PNG_PNG_INCLUDE_DIR "${libpng_SOURCE_DIR}") +include_directories("${libpng_BINARY_DIR}") set(ANDROID ${PREV_ANDROID}) set_target_properties(png_static zlibstatic PROPERTIES AVIF_LOCAL ON) add_library(PNG::PNG ALIAS png_static) + +message(CHECK_PASS "complete")