| # Copyright 2019 Joe Drago. All rights reserved. |
| # SPDX-License-Identifier: BSD-2-Clause |
| |
| cmake_minimum_required(VERSION 3.13) |
| |
| # New in CMake version 3.15. MSVC warning flags are not in CMAKE_<LANG>_FLAGS by default. |
| if(POLICY CMP0092) |
| cmake_policy(SET CMP0092 NEW) |
| endif() |
| |
| # 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") |
| |
| project(libavif LANGUAGES C VERSION 1.0.1) |
| |
| # Set C99 as the default |
| set(CMAKE_C_STANDARD 99) |
| |
| # SOVERSION scheme: MAJOR.MINOR.PATCH |
| # If there was an incompatible interface change: |
| # Increment MAJOR. Set MINOR and PATCH to 0 |
| # If there was a compatible interface change: |
| # Increment MINOR. Set PATCH to 0 |
| # If the source code was changed, but there were no interface changes: |
| # Increment PATCH. |
| set(LIBRARY_VERSION_MAJOR 16) |
| set(LIBRARY_VERSION_MINOR 0) |
| set(LIBRARY_VERSION_PATCH 1) |
| set(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") |
| set(LIBRARY_SOVERSION ${LIBRARY_VERSION_MAJOR}) |
| |
| option(BUILD_SHARED_LIBS "Build shared avif library" ON) |
| |
| option(AVIF_ENABLE_WERROR "Treat all compiler warnings as errors" ON) |
| |
| option(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R "Enable experimental YCgCo-R matrix code" OFF) |
| |
| option(AVIF_CODEC_AOM "Use the AOM codec for encoding/decoding (see AVIF_CODEC_AOM_DECODE/AVIF_CODEC_AOM_ENCODE)" OFF) |
| option(AVIF_CODEC_DAV1D "Use the dav1d codec for decoding" OFF) |
| option(AVIF_CODEC_LIBGAV1 "Use the libgav1 codec for decoding" OFF) |
| option(AVIF_CODEC_RAV1E "Use the rav1e codec for encoding" OFF) |
| option(AVIF_CODEC_SVT "Use the SVT-AV1 codec for encoding" OFF) |
| option(AVIF_CODEC_AVM "Use the AVM (AV2) codec for encoding/decoding (EXPERIMENTAL)" OFF) |
| |
| # These options allow libavif to only link against / use libaom's encoder or decoder, instead of being forced to use both |
| option(AVIF_CODEC_AOM_DECODE "if AVIF_CODEC_AOM is on, use/offer libaom's decoder" ON) |
| option(AVIF_CODEC_AOM_ENCODE "if AVIF_CODEC_AOM is on, use/offer libaom's encoder" ON) |
| |
| option(AVIF_LOCAL_AOM "Build the AOM codec by providing your own copy of the repo in ext/aom (see Local Builds in README)" OFF) |
| option(AVIF_LOCAL_DAV1D "Build the dav1d codec by providing your own copy of the repo in ext/dav1d (see Local Builds in README)" |
| OFF |
| ) |
| option(AVIF_LOCAL_LIBGAV1 |
| "Build the libgav1 codec by providing your own copy of the repo in ext/libgav1 (see Local Builds in README)" OFF |
| ) |
| option(AVIF_LOCAL_RAV1E "Build the rav1e codec by providing your own copy of the repo in ext/rav1e (see Local Builds in README)" |
| OFF |
| ) |
| option(AVIF_LOCAL_SVT |
| "Build the SVT-AV1 codec by providing your own copy of the repo in ext/SVT-AV1 (see Local Builds in README)" OFF |
| ) |
| option(AVIF_LOCAL_GTEST |
| "Build the GoogleTest framework by providing your own copy of the repo in ext/googletest (see Local Builds in README)" OFF |
| ) |
| option(AVIF_LOCAL_AVM "Build the AVM (AV2) codec by providing your own copy of the repo in ext/avm (see Local Builds in README)" |
| OFF |
| ) |
| |
| if(AVIF_LOCAL_LIBGAV1) |
| enable_language(CXX) |
| endif() |
| |
| if(APPLE) |
| set(XCRUN xcrun) |
| else() |
| set(XCRUN) |
| endif() |
| |
| if(BUILD_SHARED_LIBS) |
| set(AVIF_LIBRARY_PREFIX "${CMAKE_SHARED_LIBRARY_PREFIX}") |
| set(AVIF_LIBRARY_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}") |
| else() |
| set(AVIF_LIBRARY_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}") |
| set(AVIF_LIBRARY_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}") |
| endif() |
| |
| set(AVIF_PLATFORM_DEFINITIONS) |
| set(AVIF_PLATFORM_INCLUDES) |
| set(AVIF_PLATFORM_LIBRARIES) |
| |
| # --------------------------------------------------------------------------------------- |
| # This insanity is for people embedding libavif or making fully static or Windows builds. |
| # Any proper unix environment should ignore these entire following blocks. |
| option(AVIF_LOCAL_ZLIBPNG "Build zlib and libpng by providing your own copy inside the ext subdir." OFF) |
| if(AVIF_LOCAL_ZLIBPNG) |
| # 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 "${CMAKE_CURRENT_SOURCE_DIR}/ext/zlib" 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(${ZLIB_INCLUDE_DIR}) |
| add_subdirectory(ext/zlib) |
| # This include_directories() call and the previous include_directories() call provide the zlib |
| # include directories for add_subdirectory(ext/libpng). Because we set PNG_BUILD_ZLIB, |
| # libpng/CMakeLists.txt won't call find_package(ZLIB REQUIRED) and will see an empty |
| # ${ZLIB_INCLUDE_DIRS}. |
| include_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/zlib") |
| set(CMAKE_DEBUG_POSTFIX "") |
| |
| # 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 "${CMAKE_CURRENT_SOURCE_DIR}/ext/zlib" CACHE STRING "" FORCE) |
| set(PNG_SHARED ${BUILD_SHARED_LIBS} CACHE BOOL "") |
| set(PNG_TESTS OFF CACHE BOOL "") |
| add_subdirectory(ext/libpng) |
| set(PNG_PNG_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/libpng") |
| set(PNG_LIBRARY png_static) |
| include_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/libpng") |
| set(ANDROID ${PREV_ANDROID}) |
| |
| set(ZLIB_LIBRARY zlibstatic) |
| endif() |
| option(AVIF_LOCAL_JPEG "Build jpeg by providing your own copy inside the ext subdir." OFF) |
| if(AVIF_LOCAL_JPEG) |
| add_subdirectory(ext/libjpeg) |
| if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") |
| set(JPEG_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/libjpeg") |
| set(JPEG_LIBRARY jpeg) |
| else() |
| set(JPEG_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/libjpeg" PARENT_SCOPE) |
| set(JPEG_LIBRARY jpeg PARENT_SCOPE) |
| endif() |
| endif() |
| option(AVIF_LOCAL_LIBYUV "Build libyuv by providing your own copy inside the ext subdir." OFF) |
| if(AVIF_LOCAL_LIBYUV) |
| set(LIB_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/ext/libyuv/build/${AVIF_LIBRARY_PREFIX}yuv${AVIF_LIBRARY_SUFFIX}") |
| if(NOT EXISTS "${LIB_FILENAME}") |
| message(FATAL_ERROR "libavif(AVIF_LOCAL_LIBYUV): ${LIB_FILENAME} is missing, bailing out") |
| endif() |
| if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") |
| set(LIBYUV_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/libyuv/include") |
| set(LIBYUV_LIBRARY ${LIB_FILENAME}) |
| else() |
| set(LIBYUV_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/libyuv/include" PARENT_SCOPE) |
| set(LIBYUV_LIBRARY ${LIB_FILENAME} PARENT_SCOPE) |
| endif() |
| if(BUILD_SHARED_LIBS) |
| # Fix "libyuv.so: undefined reference to `jpeg_read_raw_data'" errors. |
| if(NOT AVIF_LOCAL_JPEG) |
| find_package(JPEG REQUIRED) |
| endif() |
| set(LIBYUV_LIBRARY ${LIBYUV_LIBRARY} ${JPEG_LIBRARY}) |
| endif() |
| set(libyuv_FOUND TRUE) |
| message(STATUS "libavif: local libyuv found; libyuv-based fast paths enabled.") |
| else(AVIF_LOCAL_LIBYUV) |
| find_package(libyuv QUIET) # not required |
| if(libyuv_FOUND) |
| # libyuv 1755 exposed all of the I*Matrix() functions, which libavif relies on. |
| # libyuv 1774 exposed ScalePlane_12 function, which libavif can use for some additional optimizations. |
| # libyuv 1813 added the I*ToARGBMatrixFilter() functions, which libavif can use with the bilinear filter. |
| if(NOT LIBYUV_VERSION) |
| message(STATUS "libavif: libyuv found, but version unknown; libyuv-based fast paths disabled.") |
| unset(libyuv_FOUND) |
| elseif(LIBYUV_VERSION LESS 1755) |
| message(STATUS "libavif: libyuv (${LIBYUV_VERSION}) found, but is too old; libyuv-based fast paths disabled.") |
| unset(libyuv_FOUND) |
| else() |
| message(STATUS "libavif: libyuv (${LIBYUV_VERSION}) found; libyuv-based fast paths enabled.") |
| if(LIBYUV_VERSION LESS 1813) |
| message(STATUS "libavif: some libyuv optimizations require at least version 1813 to work.") |
| endif() |
| endif() |
| else() |
| message(STATUS "libavif: libyuv not found; libyuv-based fast paths disabled.") |
| endif() |
| endif() |
| if(libyuv_FOUND) |
| set(AVIF_PLATFORM_DEFINITIONS ${AVIF_PLATFORM_DEFINITIONS} -DAVIF_LIBYUV_ENABLED=1) |
| set(AVIF_PLATFORM_INCLUDES ${AVIF_PLATFORM_INCLUDES} ${LIBYUV_INCLUDE_DIR}) |
| set(AVIF_PLATFORM_LIBRARIES ${AVIF_PLATFORM_LIBRARIES} ${LIBYUV_LIBRARY}) |
| endif(libyuv_FOUND) |
| option(AVIF_LOCAL_LIBSHARPYUV "Build libsharpyuv by providing your own copy inside the ext subdir." OFF) |
| if(AVIF_LOCAL_LIBSHARPYUV) |
| set(LIB_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/ext/libwebp/build/libsharpyuv${AVIF_LIBRARY_SUFFIX}") |
| if(NOT EXISTS "${LIB_FILENAME}") |
| message(FATAL_ERROR "libavif(AVIF_LOCAL_LIBSHARPYUV): ${LIB_FILENAME} is missing, bailing out") |
| endif() |
| if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") |
| set(LIBSHARPYUV_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/libwebp") |
| set(LIBSHARPYUV_LIBRARY ${LIB_FILENAME}) |
| else() |
| set(LIBSHARPYUV_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/libwebp" PARENT_SCOPE) |
| set(LIBSHARPYUV_LIBRARY ${LIB_FILENAME} PARENT_SCOPE) |
| endif() |
| set(libsharpyuv_FOUND TRUE) |
| else(AVIF_LOCAL_LIBSHARPYUV) |
| find_package(libsharpyuv QUIET) # not required |
| endif() |
| if(libsharpyuv_FOUND) |
| message(STATUS "libavif: libsharpyuv found; sharp rgb to yuv conversion enabled.") |
| set(AVIF_PLATFORM_DEFINITIONS ${AVIF_PLATFORM_DEFINITIONS} -DAVIF_LIBSHARPYUV_ENABLED=1) |
| set(AVIF_PLATFORM_INCLUDES ${AVIF_PLATFORM_INCLUDES} ${LIBSHARPYUV_INCLUDE_DIR}) |
| set(AVIF_PLATFORM_LIBRARIES ${AVIF_PLATFORM_LIBRARIES} ${LIBSHARPYUV_LIBRARY}) |
| else(libsharpyuv_FOUND) |
| message(STATUS "libavif: libsharpyuv not found") |
| endif(libsharpyuv_FOUND) |
| # --------------------------------------------------------------------------------------- |
| |
| # Enable all warnings |
| include(CheckCCompilerFlag) |
| if(CMAKE_C_COMPILER_ID MATCHES "Clang") |
| message(STATUS "libavif: Enabling warnings for Clang") |
| add_compile_options(-Wall -Wextra -Wshorten-64-to-32) |
| elseif(CMAKE_C_COMPILER_ID MATCHES "GNU") |
| message(STATUS "libavif: Enabling warnings for GCC") |
| add_compile_options(-Wall -Wextra) |
| elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") |
| message(STATUS "libavif: Enabling warnings for MSVC") |
| add_compile_options( |
| /W4 |
| /wd4324 # Disable: structure was padded due to alignment specifier |
| /wd4996 # Disable: potentially unsafe stdlib methods |
| # This tells MSVC to read source code as UTF-8 and assume console can only use ASCII (minimal safe). |
| # libavif uses ANSI API to print to console, which is not portable between systems using different |
| # languages and results in mojibake unless we only use codes shared by every code page: ASCII. |
| # A C4556 warning will be generated on violation. |
| # Commonly used /utf-8 flag assumes UTF-8 for both source and console, which is usually not the case. |
| # Warnings can be suppressed but there will still be random characters printed to the console. |
| /source-charset:utf-8 |
| /execution-charset:us-ascii |
| ) |
| else() |
| message(FATAL_ERROR "libavif: Unknown compiler, bailing out") |
| endif() |
| |
| if(AVIF_ENABLE_WERROR) |
| # Warnings as errors |
| if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "GNU") |
| add_compile_options(-Werror) |
| elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") |
| add_compile_options(/WX) |
| else() |
| message(FATAL_ERROR "libavif: Unknown compiler, bailing out") |
| endif() |
| endif() |
| |
| if(AVIF_ENABLE_COVERAGE) |
| if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "GNU") |
| message(STATUS "libavif: Enabling coverage for Clang") |
| add_compile_options(-fprofile-instr-generate -fcoverage-mapping -O0) |
| set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-fprofile-instr-generate -fcoverage-mapping") |
| else() |
| # TODO: Add support for other compilers |
| message(WARNING "libavif: Ignoring request for coverage (AVIF_ENABLE_COVERAGE); only clang is currently supported.") |
| endif() |
| endif() |
| |
| if(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R) |
| add_compile_definitions(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R) |
| endif() |
| |
| set(AVIF_SRCS |
| src/alpha.c |
| src/avif.c |
| src/colr.c |
| src/diag.c |
| src/exif.c |
| src/io.c |
| src/mem.c |
| src/obu.c |
| src/rawdata.c |
| src/read.c |
| src/reformat.c |
| src/reformat_libsharpyuv.c |
| src/reformat_libyuv.c |
| src/scale.c |
| src/stream.c |
| src/utils.c |
| src/write.c |
| ) |
| |
| # Only applicable to macOS. In GitHub CI's macos-latest os image, this prevents using the libpng |
| # and libjpeg headers from /Library/Frameworks/Mono.framework/Headers instead of |
| # /usr/local/include. |
| set(CMAKE_FIND_FRAMEWORK LAST) |
| |
| if(UNIX) |
| # Find out if we have threading available |
| set(CMAKE_THREAD_PREFER_PTHREADS ON) |
| set(THREADS_PREFER_PTHREAD_FLAG ON) |
| find_package(Threads) |
| set(AVIF_PLATFORM_LIBRARIES ${AVIF_PLATFORM_LIBRARIES} m Threads::Threads) |
| endif() |
| |
| set(AVIF_CODEC_DEFINITIONS) |
| set(AVIF_CODEC_INCLUDES) |
| set(AVIF_CODEC_LIBRARIES) |
| |
| if(AVIF_CODEC_DAV1D) |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_DAV1D=1) |
| set(AVIF_SRCS ${AVIF_SRCS} src/codec_dav1d.c) |
| |
| if(AVIF_LOCAL_DAV1D) |
| set(AVIF_DAV1D_BUILD_DIR "${CMAKE_CURRENT_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${AVIF_LIBRARY_SUFFIX}") |
| if(NOT EXISTS "${LIB_FILENAME}") |
| if("${AVIF_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 "${CMAKE_CURRENT_SOURCE_DIR}/ext/dav1d/build/src/libdav1d.a") |
| if(NOT EXISTS "${LIB_FILENAME}") |
| message(FATAL_ERROR "libavif: ${LIB_FILENAME} (or libdav1d${AVIF_LIBRARY_SUFFIX}) is missing, bailing out") |
| endif() |
| endif() |
| endif() |
| |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} "${AVIF_DAV1D_BUILD_DIR}" "${AVIF_DAV1D_BUILD_DIR}/include" |
| "${AVIF_DAV1D_BUILD_DIR}/include/dav1d" "${CMAKE_CURRENT_SOURCE_DIR}/ext/dav1d/include" |
| ) |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${LIB_FILENAME}) |
| else() |
| # Check to see if dav1d is independently being built by the outer CMake project |
| if(NOT TARGET dav1d) |
| find_package(dav1d REQUIRED) |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} ${DAV1D_INCLUDE_DIR}) |
| endif() |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${DAV1D_LIBRARY}) |
| endif() |
| |
| if(UNIX AND NOT APPLE) |
| set(AVIF_PLATFORM_LIBRARIES ${AVIF_PLATFORM_LIBRARIES} ${CMAKE_DL_LIBS}) # for dlsym |
| endif() |
| |
| message(STATUS "libavif: Codec enabled: dav1d (decode)") |
| endif() |
| |
| if(AVIF_CODEC_LIBGAV1) |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_LIBGAV1=1) |
| set(AVIF_SRCS ${AVIF_SRCS} src/codec_libgav1.c) |
| |
| if(AVIF_LOCAL_LIBGAV1) |
| set(AVIF_LIBGAV1_BUILD_DIR "${CMAKE_CURRENT_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${AVIF_LIBRARY_SUFFIX}") |
| if(NOT EXISTS "${LIB_FILENAME}") |
| message(FATAL_ERROR "libavif: ${LIB_FILENAME} is missing, bailing out") |
| endif() |
| |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/ext/libgav1/src") |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${LIB_FILENAME}) |
| else() |
| # Check to see if libgav1 is independently being built by the outer CMake project |
| if(NOT TARGET libgav1) |
| find_package(libgav1 REQUIRED) |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} ${LIBGAV1_INCLUDE_DIR}) |
| endif() |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${LIBGAV1_LIBRARY}) |
| endif() |
| |
| message(STATUS "libavif: Codec enabled: libgav1 (decode)") |
| endif() |
| |
| if(AVIF_CODEC_RAV1E) |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_RAV1E=1) |
| set(AVIF_SRCS ${AVIF_SRCS} src/codec_rav1e.c) |
| |
| if(AVIF_LOCAL_RAV1E) |
| set(LIB_FILENAME |
| "${CMAKE_CURRENT_SOURCE_DIR}/ext/rav1e/build.libavif/usr/lib/${AVIF_LIBRARY_PREFIX}rav1e${AVIF_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_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/ext/rav1e/build.libavif/usr/include/rav1e") |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${LIB_FILENAME}) |
| else() |
| # Check to see if rav1e is independently being built by the outer CMake project |
| if(NOT TARGET rav1e) |
| find_package(rav1e REQUIRED) |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} ${RAV1E_INCLUDE_DIR}) |
| endif() |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${RAV1E_LIBRARIES}) |
| endif() |
| |
| # Unfortunately, rav1e requires a few more libraries |
| if(WIN32) |
| set(AVIF_PLATFORM_LIBRARIES ${AVIF_PLATFORM_LIBRARIES} ws2_32.lib bcrypt.lib userenv.lib ntdll.lib) |
| elseif(UNIX AND NOT APPLE) |
| set(AVIF_PLATFORM_LIBRARIES ${AVIF_PLATFORM_LIBRARIES} ${CMAKE_DL_LIBS}) # for backtrace |
| endif() |
| |
| message(STATUS "libavif: Codec enabled: rav1e (encode)") |
| endif() |
| |
| if(AVIF_CODEC_SVT) |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_SVT=1) |
| set(AVIF_SRCS ${AVIF_SRCS} src/codec_svt.c) |
| |
| if(AVIF_LOCAL_SVT) |
| set(LIB_FILENAME |
| "${CMAKE_CURRENT_SOURCE_DIR}/ext/SVT-AV1/Bin/Release/${AVIF_LIBRARY_PREFIX}SvtAv1Enc${AVIF_LIBRARY_SUFFIX}" |
| ) |
| if(NOT EXISTS "${LIB_FILENAME}") |
| message(FATAL_ERROR "libavif: compiled svt library is missing (in ext/SVT-AV1/Bin/Release), bailing out") |
| endif() |
| |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/ext/SVT-AV1/include") |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${LIB_FILENAME}) |
| else() |
| # Check to see if svt is independently being built by the outer CMake project |
| if(NOT TARGET svt) |
| find_package(svt REQUIRED) |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} ${SVT_INCLUDE_DIR}) |
| endif() |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${SVT_LIBRARY}) |
| endif() |
| |
| message(STATUS "libavif: Codec enabled: svt (encode)") |
| endif() |
| |
| if(AVIF_CODEC_AOM) |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM=1) |
| if(AVIF_CODEC_AOM_ENCODE AND AVIF_CODEC_AOM_DECODE) |
| set(AVIF_CODEC_AOM_ENCODE_DECODE_CONFIG "encode/decode") |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM_ENCODE=1 -DAVIF_CODEC_AOM_DECODE=1) |
| elseif(AVIF_CODEC_AOM_ENCODE) |
| set(AVIF_CODEC_AOM_ENCODE_DECODE_CONFIG "encode only") |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM_ENCODE=1) |
| elseif(AVIF_CODEC_AOM_DECODE) |
| set(AVIF_CODEC_AOM_ENCODE_DECODE_CONFIG "decode only") |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM_DECODE=1) |
| else() |
| message( |
| FATAL_ERROR |
| "libavif: AVIF_CODEC_AOM is on, but both AVIF_CODEC_AOM_ENCODE and AVIF_CODEC_AOM_DECODE are off. Disable AVIF_CODEC_AOM to disable both parts of the codec." |
| ) |
| endif() |
| set(AVIF_SRCS ${AVIF_SRCS} src/codec_aom.c) |
| if(AVIF_LOCAL_AOM) |
| set(LIB_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/ext/aom/build.libavif/${AVIF_LIBRARY_PREFIX}aom${AVIF_LIBRARY_SUFFIX}") |
| if(NOT EXISTS "${LIB_FILENAME}") |
| message(FATAL_ERROR "libavif: ${LIB_FILENAME} is missing, bailing out") |
| endif() |
| |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/ext/aom") |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${LIB_FILENAME}) |
| else() |
| # Check to see if aom is independently being built by the outer CMake project |
| if(NOT TARGET aom) |
| find_package(aom REQUIRED) |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} ${AOM_INCLUDE_DIR}) |
| endif() |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${AOM_LIBRARIES}) |
| endif() |
| |
| message(STATUS "libavif: Codec enabled: aom (${AVIF_CODEC_AOM_ENCODE_DECODE_CONFIG})") |
| endif() |
| |
| if(AVIF_CODEC_AVM) |
| message(WARNING "libavif: AV2 support with avm is experimental. Only use for testing.") |
| |
| # The avm repository is a fork of aom and inherited a lot of folders, files and build artifacts named the same way. |
| # Having both dependencies at the same time generates conflicts in includes, binary lookups etc. |
| if(AVIF_CODEC_AOM) |
| message(FATAL_ERROR "libavif: aom conflicts with avm, bailing out") |
| endif() |
| |
| set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AVM=1) |
| set(AVIF_SRCS ${AVIF_SRCS} src/codec_avm.c) |
| if(AVIF_LOCAL_AVM) |
| # Building the avm repository generates files such as "libaom.a" because it is a fork of aom. |
| set(LIB_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/ext/avm/build.libavif/${AVIF_LIBRARY_PREFIX}aom${AVIF_LIBRARY_SUFFIX}") |
| if(NOT EXISTS "${LIB_FILENAME}") |
| message(FATAL_ERROR "libavif: ${LIB_FILENAME} (from avm) is missing, bailing out") |
| endif() |
| |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/ext/avm") |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${LIB_FILENAME}) |
| |
| # ext/avm/aom/aom_encoder.h includes config/aom_config.h which is generated by the local build of avm. |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/ext/avm/build.libavif") |
| else() |
| # Check to see if avm is independently being built by the outer CMake project |
| if(NOT TARGET avm) |
| find_package(avm REQUIRED) |
| set(AVIF_CODEC_INCLUDES ${AVIF_CODEC_INCLUDES} ${AVM_INCLUDE_DIR}) |
| endif() |
| set(AVIF_CODEC_LIBRARIES ${AVIF_CODEC_LIBRARIES} ${AVM_LIBRARIES}) |
| endif() |
| |
| message(STATUS "libavif: Codec enabled: avm (encode/decode)") |
| endif() |
| |
| if(NOT AVIF_CODEC_AOM |
| AND NOT AVIF_CODEC_DAV1D |
| AND NOT AVIF_CODEC_LIBGAV1 |
| AND NOT AVIF_CODEC_AVM |
| ) |
| message(WARNING "libavif: No decoding library is enabled.") |
| endif() |
| |
| add_library(avif ${AVIF_SRCS}) |
| set_target_properties(avif PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION} C_VISIBILITY_PRESET hidden) |
| target_compile_definitions(avif PRIVATE ${AVIF_PLATFORM_DEFINITIONS} ${AVIF_CODEC_DEFINITIONS}) |
| target_link_libraries(avif PRIVATE ${AVIF_CODEC_LIBRARIES} ${AVIF_PLATFORM_LIBRARIES}) |
| target_include_directories( |
| avif PUBLIC $<BUILD_INTERFACE:${libavif_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> PRIVATE ${AVIF_PLATFORM_INCLUDES} |
| ${AVIF_CODEC_INCLUDES} |
| ) |
| set(AVIF_PKG_CONFIG_EXTRA_CFLAGS "") |
| if(BUILD_SHARED_LIBS) |
| target_compile_definitions(avif PUBLIC AVIF_DLL PRIVATE AVIF_BUILDING_SHARED_LIBS) |
| set(AVIF_PKG_CONFIG_EXTRA_CFLAGS " -DAVIF_DLL") |
| if(AVIF_LOCAL_LIBGAV1) |
| set_target_properties(avif PROPERTIES LINKER_LANGUAGE "CXX") |
| endif() |
| endif() |
| |
| # Give access to functions defined in internal.h when BUILD_SHARED_LIBS is ON, to tests for example. |
| # The avif_internal target should not be used by external code. |
| if(BUILD_SHARED_LIBS) |
| add_library(avif_internal STATIC ${AVIF_SRCS}) |
| # Copy most properties from the public avif library target. |
| target_compile_definitions(avif_internal PRIVATE "$<TARGET_PROPERTY:avif,COMPILE_DEFINITIONS>") |
| target_link_libraries(avif_internal PRIVATE "$<TARGET_PROPERTY:avif,LINK_LIBRARIES>") |
| target_include_directories( |
| avif_internal PUBLIC "$<TARGET_PROPERTY:avif,INTERFACE_INCLUDE_DIRECTORIES>" |
| PRIVATE "$<TARGET_PROPERTY:avif,INCLUDE_DIRECTORIES>" |
| ) |
| else() |
| add_library(avif_internal ALIAS avif) |
| endif() |
| |
| option(AVIF_BUILD_EXAMPLES "Build avif examples." OFF) |
| if(AVIF_BUILD_EXAMPLES) |
| set(AVIF_EXAMPLES avif_example_decode_memory avif_example_decode_file avif_example_decode_streaming avif_example_encode) |
| |
| foreach(EXAMPLE ${AVIF_EXAMPLES}) |
| add_executable(${EXAMPLE} examples/${EXAMPLE}.c) |
| if(AVIF_LOCAL_LIBGAV1) |
| set_target_properties(${EXAMPLE} PROPERTIES LINKER_LANGUAGE "CXX") |
| endif() |
| target_link_libraries(${EXAMPLE} avif ${AVIF_PLATFORM_LIBRARIES}) |
| endforeach() |
| endif() |
| |
| if(CMAKE_SKIP_INSTALL_RULES) |
| set(SKIP_INSTALL_ALL TRUE) |
| endif() |
| |
| if(NOT SKIP_INSTALL_ALL) |
| include(GNUInstallDirs) |
| endif() |
| |
| if(AVIF_CODEC_LIBRARIES MATCHES vmaf) |
| enable_language(CXX) |
| endif() |
| |
| option(AVIF_BUILD_APPS "Build avif apps." OFF) |
| option(AVIF_BUILD_TESTS "Build avif tests." OFF) |
| option(AVIF_ENABLE_GTEST |
| "Build avif C++ tests, which depend on GoogleTest. Requires GoogleTest. Has no effect unless AVIF_BUILD_TESTS is ON." ON |
| ) |
| |
| if(AVIF_BUILD_APPS OR (AVIF_BUILD_TESTS AND AVIF_ENABLE_GTEST)) |
| if(NOT AVIF_LOCAL_ZLIBPNG) |
| find_package(ZLIB REQUIRED) |
| find_package(PNG 1.6.32 REQUIRED) # 1.6.32 or above for png_get_eXIf_1()/png_set_eXIf_1() and iTXt (for XMP). |
| endif() |
| if(NOT AVIF_LOCAL_JPEG) |
| find_package(JPEG REQUIRED) |
| endif() |
| |
| add_library( |
| avif_apps STATIC apps/shared/avifexif.c apps/shared/avifjpeg.c apps/shared/avifpng.c apps/shared/avifutil.c |
| apps/shared/iccjpeg.c apps/shared/iccmaker.c apps/shared/y4m.c |
| ) |
| target_link_libraries(avif_apps avif ${AVIF_PLATFORM_LIBRARIES} ${PNG_LIBRARY} ${ZLIB_LIBRARY} ${JPEG_LIBRARY}) |
| # In GitHub CI's macos-latest os image, /usr/local/include has not only the headers of libpng |
| # and libjpeg but also the headers of an older version of libavif. Put the avif include |
| # directory before ${PNG_PNG_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} to prevent picking up old libavif |
| # headers from /usr/local/include. |
| target_include_directories( |
| avif_apps PRIVATE $<TARGET_PROPERTY:avif,INTERFACE_INCLUDE_DIRECTORIES> ${PNG_PNG_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} |
| INTERFACE apps/shared |
| ) |
| endif() |
| |
| if(AVIF_BUILD_APPS) |
| add_executable(avifenc apps/avifenc.c) |
| if(AVIF_LOCAL_LIBGAV1 OR AVIF_CODEC_LIBRARIES MATCHES vmaf) |
| set_target_properties(avifenc PROPERTIES LINKER_LANGUAGE "CXX") |
| endif() |
| target_link_libraries(avifenc avif_apps) |
| add_executable(avifdec apps/avifdec.c) |
| if(AVIF_LOCAL_LIBGAV1 OR AVIF_CODEC_LIBRARIES MATCHES vmaf) |
| set_target_properties(avifdec PROPERTIES LINKER_LANGUAGE "CXX") |
| endif() |
| target_link_libraries(avifdec avif_apps) |
| |
| if(NOT SKIP_INSTALL_APPS AND NOT SKIP_INSTALL_ALL) |
| install( |
| TARGETS avifenc avifdec |
| RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" |
| ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" |
| LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" |
| ) |
| endif() |
| endif() |
| |
| if(AVIF_BUILD_TESTS) |
| enable_testing() # Allow ctest to be called from top-level directory. |
| add_subdirectory(tests) |
| endif() |
| |
| option(AVIF_BUILD_MAN_PAGES "Build avif man pages." OFF) |
| if(AVIF_BUILD_MAN_PAGES) |
| if(AVIF_BUILD_APPS) |
| find_program(PANDOC_EXE pandoc) |
| if(PANDOC_EXE) |
| message(STATUS "libavif: Using pandoc: ${PANDOC_EXE}") |
| else() |
| message(FATAL_ERROR "libavif: Pandoc is missing, bailing out") |
| endif() |
| |
| set(MAN_PAGES avifenc.1 avifdec.1) |
| |
| foreach(MAN_PAGE ${MAN_PAGES}) |
| add_custom_command( |
| OUTPUT ${MAN_PAGE} |
| COMMAND ${PANDOC_EXE} -s -V "footer=libavif ${PROJECT_VERSION}" -f markdown -t man -o |
| "${CMAKE_CURRENT_BINARY_DIR}/${MAN_PAGE}" "${CMAKE_CURRENT_SOURCE_DIR}/doc/${MAN_PAGE}.md" |
| DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/doc/${MAN_PAGE}.md" |
| VERBATIM |
| ) |
| endforeach() |
| add_custom_target(man_pages ALL DEPENDS ${MAN_PAGES}) |
| |
| foreach(MAN_PAGE ${MAN_PAGES}) |
| install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MAN_PAGE}" DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") |
| endforeach() |
| else() |
| message(WARNING "libavif: No man pages are built (AVIF_BUILD_MAN_PAGES); AVIF_BUILD_APPS must be on.") |
| endif() |
| endif() |
| |
| if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) |
| install( |
| TARGETS avif |
| EXPORT ${PROJECT_NAME}-config |
| RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" |
| ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" |
| LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" |
| ) |
| |
| # Enable CMake configs in VCPKG mode |
| if(BUILD_SHARED_LIBS OR VCPKG_TARGET_TRIPLET) |
| install(EXPORT ${PROJECT_NAME}-config DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) |
| |
| include(CMakePackageConfigHelpers) |
| write_basic_package_version_file( |
| ${PROJECT_NAME}-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion |
| ) |
| install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake |
| DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} |
| ) |
| endif() |
| |
| # Handle both relative and absolute paths (e.g. NixOS) for a relocatable package |
| if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") |
| set(PC_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}") |
| else() |
| set(PC_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") |
| endif() |
| if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") |
| set(PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}") |
| else() |
| set(PC_LIBDIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") |
| endif() |
| configure_file(libavif.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libavif.pc @ONLY) |
| install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libavif.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) |
| endif() |
| if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) |
| install(FILES include/avif/avif.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/avif") |
| endif() |
| |
| # --------------------------------------------------------------------------------------- |
| # Win32 (Visual Studio) fixups |
| |
| macro(avif_set_folder_safe target folder) |
| if(TARGET ${target}) |
| set_target_properties(${target} PROPERTIES FOLDER ${folder}) |
| endif() |
| endmacro() |
| |
| macro(avif_exclude_safe target) |
| if(TARGET ${target}) |
| set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD True) |
| endif() |
| endmacro() |
| |
| if(WIN32) |
| set_property(GLOBAL PROPERTY USE_FOLDERS ON) |
| |
| avif_set_folder_safe(avif "ext/avif") |
| if(AVIF_BUILD_EXAMPLES) |
| foreach(EXAMPLE ${AVIF_EXAMPLES}) |
| avif_set_folder_safe(${EXAMPLE} "ext/avif/examples") |
| endforeach() |
| endif() |
| if(AVIF_LOCAL_ZLIBPNG) |
| avif_set_folder_safe(example "ext/zlibpng") |
| avif_set_folder_safe(genfiles "ext/zlibpng") |
| avif_set_folder_safe(minigzip "ext/zlibpng") |
| avif_set_folder_safe(png_static "ext/zlibpng") |
| avif_set_folder_safe(zlib "ext/zlibpng") |
| avif_set_folder_safe(zlibstatic "ext/zlibpng") |
| |
| # Don't bother building these targets |
| avif_exclude_safe(example) |
| avif_exclude_safe(genfiles) |
| avif_exclude_safe(minigzip) |
| endif() |
| if(AVIF_LOCAL_JPEG) |
| avif_set_folder_safe(jpeg "ext/libjpeg") |
| endif() |
| endif() |
| |
| add_subdirectory(contrib) |