libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

CMakeLists.txt (19812B)


      1 # Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 #
      3 # Use of this source code is governed by a BSD-style
      4 # license that can be found in the LICENSE file.
      5 
      6 # Ubuntu focal ships with cmake 3.16.
      7 cmake_minimum_required(VERSION 3.16...3.27)
      8 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
      9 
     10 project(LIBJXL LANGUAGES C CXX)
     11 
     12 # TODO(sboukortt): remove once oss-fuzz passes -DBUILD_SHARED_LIBS=OFF
     13 if(JPEGXL_ENABLE_FUZZERS)
     14   message(INFO "Fuzzer build detected, building static libs")
     15   set(BUILD_SHARED_LIBS OFF)
     16 endif()
     17 
     18 message(STATUS "CMAKE_SYSTEM_PROCESSOR is ${CMAKE_SYSTEM_PROCESSOR}")
     19 include(CheckCXXCompilerFlag)
     20 check_cxx_compiler_flag("-fsanitize=fuzzer-no-link" CXX_FUZZERS_SUPPORTED)
     21 check_cxx_compiler_flag("-fmacro-prefix-map=OLD=NEW" CXX_MACRO_PREFIX_MAP)
     22 check_cxx_compiler_flag("-fno-rtti" CXX_NO_RTTI_SUPPORTED)
     23 
     24 # Enabled PIE binaries by default if supported.
     25 include(CheckPIESupported OPTIONAL RESULT_VARIABLE CHECK_PIE_SUPPORTED)
     26 if(CHECK_PIE_SUPPORTED)
     27   check_pie_supported(LANGUAGES CXX)
     28   if(CMAKE_CXX_LINK_PIE_SUPPORTED)
     29     set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
     30   endif()
     31 endif()
     32 
     33 if(PROVISION_DEPENDENCIES)
     34   # Run script to provision dependencies.
     35   find_program (BASH_PROGRAM bash)
     36   if(BASH_PROGRAM)
     37     execute_process(
     38       COMMAND ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/deps.sh
     39       RESULT_VARIABLE PROVISION_DEPENDENCIES_RESULT)
     40   endif()
     41   if(NOT PROVISION_DEPENDENCIES_RESULT EQUAL "0")
     42     message(FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/deps.sh failed with ${PROVISION_DEPENDENCIES_RESULT}")
     43   endif()
     44 endif()
     45 
     46 ### Project build options:
     47 if(CXX_FUZZERS_SUPPORTED)
     48   # Enabled by default except on arm64, Windows and Apple builds.
     49   set(ENABLE_FUZZERS_DEFAULT true)
     50 endif()
     51 find_package(PkgConfig)
     52 if(NOT APPLE AND NOT WIN32 AND NOT HAIKU AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
     53   pkg_check_modules(TCMallocMinimalVersionCheck QUIET IMPORTED_TARGET
     54       libtcmalloc_minimal)
     55   if(TCMallocMinimalVersionCheck_FOUND AND
     56      NOT TCMallocMinimalVersionCheck_VERSION VERSION_EQUAL 2.8.0)
     57     # Enabled by default except on Windows and Apple builds for
     58     # tcmalloc != 2.8.0. tcmalloc 2.8.1 already has a fix for this issue.
     59     set(ENABLE_TCMALLOC_DEFAULT true)
     60   else()
     61     message(STATUS
     62         "tcmalloc version ${TCMallocMinimalVersionCheck_VERSION} -- "
     63         "tcmalloc 2.8.0 disabled due to "
     64         "https://github.com/gperftools/gperftools/issues/1204")
     65   endif()
     66 endif()
     67 
     68 check_cxx_source_compiles(
     69    "int main() {
     70       #if !defined(HWY_DISABLED_TARGETS)
     71       static_assert(false, \"HWY_DISABLED_TARGETS is not defined\");
     72       #endif
     73       return 0;
     74     }"
     75   JXL_HWY_DISABLED_TARGETS_FORCED
     76 )
     77 
     78 if((SANITIZER STREQUAL "msan") OR EMSCRIPTEN)
     79   set(BUNDLE_LIBPNG_DEFAULT YES)
     80 else()
     81   set(BUNDLE_LIBPNG_DEFAULT NO)
     82 endif()
     83 
     84 
     85 if(EXISTS "${PROJECT_SOURCE_DIR}/third_party/libjpeg-turbo/jconfig.h.in")
     86   set(ENABLE_JPEGLI_DEFAULT YES)
     87 else()
     88   set(ENABLE_JPEGLI_DEFAULT NO)
     89 endif()
     90 
     91 # Standard cmake naming for building shared libraries.
     92 get_property(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
     93 option(BUILD_SHARED_LIBS "Build shared libraries instead of static ones" ${SHARED_LIBS_SUPPORTED})
     94 
     95 set(JPEGXL_ENABLE_FUZZERS ${ENABLE_FUZZERS_DEFAULT} CACHE BOOL
     96     "Build JPEGXL fuzzer targets.")
     97 set(JPEGXL_ENABLE_DEVTOOLS false CACHE BOOL
     98     "Build JPEGXL developer tools.")
     99 set(JPEGXL_ENABLE_TOOLS true CACHE BOOL
    100     "Build JPEGXL user tools: cjxl and djxl.")
    101 set(JPEGXL_ENABLE_JPEGLI ${ENABLE_JPEGLI_DEFAULT} CACHE BOOL
    102     "Build jpegli library.")
    103 set(JPEGXL_ENABLE_JPEGLI_LIBJPEG true CACHE BOOL
    104     "Build libjpeg.so shared library based on jpegli.")
    105 set(JPEGXL_INSTALL_JPEGLI_LIBJPEG false CACHE BOOL
    106     "Install jpegli version of libjpeg.so system-wide.")
    107 set(JPEGLI_LIBJPEG_LIBRARY_VERSION "62.3.0" CACHE STRING
    108     "Library version of the libjpeg.so shared library that we build.")
    109 set(JPEGLI_LIBJPEG_LIBRARY_SOVERSION "62" CACHE STRING
    110     "Library so-version of the libjpeg.so shared library that we build.")
    111 set(JPEGXL_ENABLE_DOXYGEN true CACHE BOOL
    112     "Generate C API documentation using Doxygen.")
    113 set(JPEGXL_ENABLE_MANPAGES true CACHE BOOL
    114     "Build and install man pages for the command-line tools.")
    115 set(JPEGXL_ENABLE_BENCHMARK true CACHE BOOL
    116     "Build JPEGXL benchmark tools.")
    117 set(JPEGXL_ENABLE_EXAMPLES true CACHE BOOL
    118     "Build JPEGXL library usage examples.")
    119 set(JPEGXL_BUNDLE_LIBPNG ${BUNDLE_LIBPNG_DEFAULT} CACHE BOOL
    120     "Build libpng from source and link it statically.")
    121 set(JPEGXL_ENABLE_JNI true CACHE BOOL
    122     "Build JPEGXL JNI Java wrapper, if Java dependencies are installed.")
    123 set(JPEGXL_ENABLE_SJPEG true CACHE BOOL
    124     "Build JPEGXL with support for encoding with sjpeg.")
    125 set(JPEGXL_ENABLE_OPENEXR true CACHE BOOL
    126     "Build JPEGXL with support for OpenEXR if available.")
    127 set(JPEGXL_ENABLE_SKCMS true CACHE BOOL
    128     "Build with skcms instead of lcms2.")
    129 set(JPEGXL_ENABLE_VIEWERS false CACHE BOOL
    130     "Build JPEGXL viewer tools for evaluation.")
    131 set(JPEGXL_ENABLE_TCMALLOC ${ENABLE_TCMALLOC_DEFAULT} CACHE BOOL
    132     "Build JPEGXL using gperftools (tcmalloc) allocator.")
    133 set(JPEGXL_ENABLE_PLUGINS false CACHE BOOL
    134     "Build third-party plugins to support JPEG XL in other applications.")
    135 set(JPEGXL_ENABLE_COVERAGE false CACHE BOOL
    136     "Enable code coverage tracking for libjxl. This also enables debug and disables optimizations.")
    137 set(JPEGXL_ENABLE_SIZELESS_VECTORS false CACHE BOOL
    138     "Builds in support for SVE/RVV vectorization")
    139 set(JPEGXL_ENABLE_TRANSCODE_JPEG true CACHE BOOL
    140     "Builds in support for decoding transcoded JXL files back to JPEG,\
    141  disabling it makes the decoder reject JXL_DEC_JPEG_RECONSTRUCTION events,\
    142  (default enabled)")
    143 set(JPEGXL_ENABLE_BOXES true CACHE BOOL
    144     "Builds in support for decoding boxes in JXL files,\
    145  disabling it makes the decoder reject JXL_DEC_BOX events,\
    146  (default enabled)")
    147 set(JPEGXL_STATIC false CACHE BOOL
    148     "Build tools as static binaries.")
    149 set(JPEGXL_WARNINGS_AS_ERRORS false CACHE BOOL
    150     "Treat warnings as errors during compilation.")
    151 set(JPEGXL_DEP_LICENSE_DIR "" CACHE STRING
    152     "Directory where to search for system dependencies \"copyright\" files.")
    153 set(JPEGXL_FORCE_NEON false CACHE BOOL
    154     "Set flags to enable NEON in arm if not enabled by your toolchain.")
    155 set(JPEGXL_TEST_TOOLS false CACHE BOOL
    156     "Run scripts that test the encoding / decoding tools.")
    157 set(JPEGXL_ENABLE_AVX512 false CACHE BOOL
    158     "Build with AVX512 support (faster on CPUs that support it, but larger binary size).")
    159 set(JPEGXL_ENABLE_AVX512_SPR false CACHE BOOL
    160     "Build with AVX-512FP16 support (faster on CPUs that support it, but larger binary size).")
    161 set(JPEGXL_ENABLE_AVX512_ZEN4 false CACHE BOOL
    162 "Build with Zen4-optimized AVX512 support (faster on CPUs that support it, but larger binary size).")
    163 set(JPEGXL_ENABLE_WASM_TRHEADS true CACHE BOOL
    164     "Builds WASM modules with threads support")
    165 
    166 # Force system dependencies.
    167 set(JPEGXL_FORCE_SYSTEM_BROTLI false CACHE BOOL
    168     "Force using system installed brotli instead of third_party/brotli source.")
    169 set(JPEGXL_FORCE_SYSTEM_GTEST false CACHE BOOL
    170     "Force using system installed googletest (gtest/gmock) instead of third_party/googletest source.")
    171 set(JPEGXL_FORCE_SYSTEM_LCMS2 false CACHE BOOL
    172     "Force using system installed lcms2 instead of third_party/lcms source.")
    173 set(JPEGXL_FORCE_SYSTEM_HWY false CACHE BOOL
    174     "Force using system installed highway (libhwy-dev) instead of third_party/highway source.")
    175 
    176 # Check minimum compiler versions. Older compilers are not supported and fail
    177 # with hard to understand errors.
    178 if (NOT CMAKE_C_COMPILER_ID STREQUAL CMAKE_CXX_COMPILER_ID)
    179   message(FATAL_ERROR "Different C/C++ compilers set: "
    180           "${CMAKE_C_COMPILER_ID} vs ${CMAKE_CXX_COMPILER_ID}")
    181 endif()
    182 
    183 message(STATUS
    184     "Compiled IDs C:${CMAKE_C_COMPILER_ID}, C++:${CMAKE_CXX_COMPILER_ID}")
    185 
    186 set(JXL_HWY_INCLUDE_DIRS "$<BUILD_INTERFACE:$<TARGET_PROPERTY:$<IF:$<TARGET_EXISTS:hwy::hwy>,hwy::hwy,hwy>,INTERFACE_INCLUDE_DIRECTORIES>>")
    187 # Always disable SSSE3 since it is rare to have SSSE3 but not SSE4
    188 set(HWY_DISABLED_TARGETS "HWY_SSSE3")
    189 if (NOT JPEGXL_ENABLE_AVX512)
    190   message(STATUS "Disabled AVX512 (set JPEGXL_ENABLE_AVX512 to enable it)")
    191   set(HWY_DISABLED_TARGETS "${HWY_DISABLED_TARGETS}|HWY_AVX3")
    192   add_definitions(-DFJXL_ENABLE_AVX512=0)
    193 endif()
    194 if (NOT JPEGXL_ENABLE_AVX512_SPR)
    195   message(STATUS "Disabled AVX512_SPR (set JPEGXL_ENABLE_AVX512_SPR to enable it)")
    196   set(HWY_DISABLED_TARGETS "${HWY_DISABLED_TARGETS}|HWY_AVX3_SPR")
    197 endif()
    198 if (NOT JPEGXL_ENABLE_AVX512_ZEN4)
    199   message(STATUS "Disabled AVX512_ZEN4 (set JPEGXL_ENABLE_AVX512_ZEN4 to enable it)")
    200   set(HWY_DISABLED_TARGETS "${HWY_DISABLED_TARGETS}|HWY_AVX3_ZEN4")
    201 endif()
    202 
    203 
    204 
    205 # CMAKE_EXPORT_COMPILE_COMMANDS is used to generate the compilation database
    206 # used by clang-tidy.
    207 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
    208 
    209 if(JPEGXL_STATIC)
    210   set(BUILD_SHARED_LIBS 0)
    211   # Clang developers say that in case to use "static" we have to build stdlib
    212   # ourselves; for real use case we don't care about stdlib, as it is "granted",
    213   # so just linking all other libraries is fine.
    214   if (NOT MSVC AND NOT APPLE)
    215     set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
    216     set(CMAKE_EXE_LINKER_FLAGS
    217         "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")
    218   endif()
    219 endif()  # JPEGXL_STATIC
    220 
    221 # Threads
    222 set(THREADS_PREFER_PTHREAD_FLAG YES)
    223 find_package(Threads REQUIRED)
    224 
    225 # These settings are important to drive check_cxx_source_compiles
    226 # See CMP0067 (min cmake version is 3.10 anyway)
    227 set(CMAKE_CXX_STANDARD 11)
    228 set(CMAKE_CXX_EXTENSIONS OFF)
    229 set(CMAKE_CXX_STANDARD_REQUIRED YES)
    230 
    231 # Atomics
    232 find_package(Atomics REQUIRED)
    233 
    234 if(JPEGXL_STATIC)
    235   if (MINGW)
    236     # In MINGW libstdc++ uses pthreads directly. When building statically a
    237     # program (regardless of whether the source code uses pthread or not) the
    238     # toolchain will add stdc++ and pthread to the linking step but stdc++ will
    239     # be linked statically while pthread will be linked dynamically.
    240     # To avoid this and have pthread statically linked with need to pass it in
    241     # the command line with "-Wl,-Bstatic -lpthread -Wl,-Bdynamic" but the
    242     # linker will discard it if not used by anything else up to that point in
    243     # the linker command line. If the program or any dependency don't use
    244     # pthread directly -lpthread is discarded and libstdc++ (added by the
    245     # toolchain later) will then use the dynamic version. For this we also need
    246     # to pass -lstdc++ explicitly before -lpthread. For pure C programs -lstdc++
    247     # will be discarded anyway.
    248     # This adds these flags as dependencies for *all* targets. Adding this to
    249     # CMAKE_EXE_LINKER_FLAGS instead would cause them to be included before any
    250     # object files and therefore discarded. This should be set in the
    251     # INTERFACE_LINK_LIBRARIES of Threads::Threads but some third_part targets
    252     # don't depend on it.
    253     link_libraries(-Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic)
    254   elseif(CMAKE_USE_PTHREADS_INIT)
    255     # "whole-archive" is not supported on OSX.
    256     if (NOT APPLE)
    257       # Set pthreads as a whole-archive, otherwise weak symbols in the static
    258       # libraries will discard pthreads symbols leading to segmentation fault at
    259       # runtime.
    260       message(STATUS "Using -lpthread as --whole-archive")
    261       set_target_properties(Threads::Threads PROPERTIES
    262         INTERFACE_LINK_LIBRARIES
    263             "-Wl,--whole-archive;-lpthread;-Wl,--no-whole-archive")
    264     endif()
    265   endif()
    266 endif()  # JPEGXL_STATIC
    267 
    268 if (EMSCRIPTEN AND JPEGXL_ENABLE_WASM_TRHEADS)
    269   set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
    270   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
    271   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
    272 endif()
    273 
    274 if (CXX_MACRO_PREFIX_MAP)
    275   add_compile_options(-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.)
    276 endif()
    277 
    278 if (CXX_NO_RTTI_SUPPORTED)
    279   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
    280 endif()
    281 
    282 # Internal flags for coverage builds:
    283 set(JPEGXL_COVERAGE_FLAGS)
    284 set(JPEGXL_COVERAGE_LINK_FLAGS)
    285 
    286 if (MSVC)
    287   # TODO(janwas): add flags
    288   add_definitions(-D_CRT_SECURE_NO_WARNINGS)
    289 else ()
    290   # Global compiler flags for all targets here and in subdirectories.
    291   add_definitions(
    292     # Avoid changing the binary based on the current time and date.
    293     -D__DATE__="redacted"
    294     -D__TIMESTAMP__="redacted"
    295     -D__TIME__="redacted"
    296   )
    297 
    298   # TODO(eustas): JXL currently compiles, but does not pass tests...
    299   if (NOT JXL_HWY_DISABLED_TARGETS_FORCED)
    300     if (NOT JPEGXL_ENABLE_SIZELESS_VECTORS)
    301       set(HWY_DISABLED_TARGETS "${HWY_DISABLED_TARGETS}|HWY_SVE|HWY_SVE2|HWY_SVE_256|HWY_SVE2_128|HWY_RVV")
    302     endif()
    303     add_definitions(-DHWY_DISABLED_TARGETS=\(${HWY_DISABLED_TARGETS}\))
    304   endif()
    305 
    306   # Machine flags.
    307   add_compile_options(-funwind-tables)
    308   if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    309     add_compile_options("SHELL:-Xclang -mrelax-all")
    310   endif()
    311   if (CXX_CONSTRUCTOR_ALIASES_SUPPORTED)
    312     add_compile_options("SHELL:-Xclang -mconstructor-aliases")
    313   endif()
    314 
    315   if(WIN32)
    316     # Not supported by clang-cl, but frame pointers are default on Windows
    317   else()
    318     add_compile_options(-fno-omit-frame-pointer)
    319   endif()
    320 
    321   # CPU flags - remove once we have NEON dynamic dispatch
    322 
    323   # TODO(janwas): this also matches M1, but only ARMv7 is intended/needed.
    324   if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
    325     if(JPEGXL_FORCE_NEON)
    326       # GCC requires these flags, otherwise __ARM_NEON is undefined.
    327       add_compile_options(-mfpu=neon-vfpv4 -mfloat-abi=hard)
    328     endif()
    329   endif()
    330 
    331   add_compile_options(
    332     # Ignore this to allow redefining __DATE__ and others.
    333     -Wno-builtin-macro-redefined
    334 
    335     # Global warning settings.
    336     -Wall
    337   )
    338 
    339   if (JPEGXL_WARNINGS_AS_ERRORS)
    340     add_compile_options(-Werror)
    341   endif ()
    342 
    343   if(JPEGXL_ENABLE_COVERAGE)
    344     set(JPEGXL_COVERAGE_FLAGS
    345         -g -O0 -fprofile-arcs -ftest-coverage
    346         -DJXL_ENABLE_ASSERT=0 -DJXL_ENABLE_CHECK=0
    347     )
    348     set(JPEGXL_COVERAGE_LINK_FLAGS
    349         --coverage
    350     )
    351   endif()  # JPEGXL_ENABLE_COVERAGE
    352 endif ()  # !MSVC
    353 
    354 include(GNUInstallDirs)
    355 
    356 # Separately build/configure testing frameworks and other third_party libraries
    357 # to allow disabling tests in those libraries.
    358 include(third_party/testing.cmake)
    359 add_subdirectory(third_party)
    360 # Copy the JXL license file to the output build directory.
    361 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
    362                ${PROJECT_BINARY_DIR}/LICENSE.jpeg-xl COPYONLY)
    363 
    364 # Enable tests regardless of where they are defined.
    365 enable_testing()
    366 include(CTest)
    367 # Specify default location of `testdata`:
    368 if(NOT DEFINED JPEGXL_TEST_DATA_PATH)
    369   set(JPEGXL_TEST_DATA_PATH "${PROJECT_SOURCE_DIR}/testdata")
    370 endif()
    371 
    372 # Libraries.
    373 add_subdirectory(lib)
    374 
    375 if(BUILD_TESTING)
    376   # Script to run tests over the source code in bash.
    377   find_program (BASH_PROGRAM bash)
    378   if(BASH_PROGRAM)
    379     add_test(
    380       NAME bash_test
    381       COMMAND ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/bash_test.sh)
    382   endif()
    383 endif() # BUILD_TESTING
    384 
    385 # Documentation generated by Doxygen
    386 if(JPEGXL_ENABLE_DOXYGEN)
    387   find_package(Doxygen)
    388   if(DOXYGEN_FOUND)
    389     set(DOXYGEN_GENERATE_HTML "YES")
    390     set(DOXYGEN_GENERATE_XML "YES")
    391     set(DOXYGEN_STRIP_FROM_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/include")
    392     if(JPEGXL_WARNINGS_AS_ERRORS)
    393       set(DOXYGEN_WARN_AS_ERROR "YES")
    394     endif()
    395     set(DOXYGEN_QUIET "YES")
    396     doxygen_add_docs(doc
    397       "${CMAKE_CURRENT_SOURCE_DIR}/lib/include"
    398       "${CMAKE_CURRENT_SOURCE_DIR}/doc/api.txt"
    399       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
    400       COMMENT "Generating C API documentation")
    401 
    402     # Add sphinx doc build step for readthedocs.io (requires doxygen too).
    403     find_program(SPHINX_BUILD_PROGRAM sphinx-build)
    404     if(SPHINX_BUILD_PROGRAM)
    405       add_custom_command(
    406         OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rtd/nonexistent"
    407         COMMENT "Generating readthedocs.io output on ${CMAKE_CURRENT_BINARY_DIR}/rtd"
    408         COMMAND ${SPHINX_BUILD_PROGRAM} -q -W -b html -j auto
    409           ${CMAKE_SOURCE_DIR}/doc/sphinx
    410           ${CMAKE_CURRENT_BINARY_DIR}/rtd
    411         DEPENDS doc
    412       )
    413       # This command runs the documentation generation every time since the output
    414       # target file doesn't exist.
    415       add_custom_target(rtd-html
    416         DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rtd/nonexistent
    417       )
    418     else() # SPHINX_BUILD_PROGRAM\
    419       message(WARNING "sphinx-build not found, skipping rtd documentation")
    420     endif() # SPHINX_BUILD_PROGRAM
    421 
    422   else()
    423     # Create a "doc" target for compatibility since "doc" is not otherwise added to
    424     # the build when doxygen is not installed.
    425     add_custom_target(doc false
    426       COMMENT "Error: Can't generate doc since Doxygen not installed.")
    427   endif() # DOXYGEN_FOUND
    428 endif() # JPEGXL_ENABLE_DOXYGEN
    429 
    430 if(JPEGXL_ENABLE_MANPAGES)
    431   find_program(ASCIIDOC a2x)
    432   if(ASCIIDOC)
    433     file(STRINGS "${ASCIIDOC}" ASCIIDOC_SHEBANG LIMIT_COUNT 1)
    434     if(ASCIIDOC_SHEBANG MATCHES "/sh|/bash" OR MINGW)
    435       set(ASCIIDOC_PY_FOUND ON)
    436       # Run the program directly and set ASCIIDOC as empty.
    437       set(ASCIIDOC_PY "${ASCIIDOC}")
    438       set(ASCIIDOC "")
    439     elseif(ASCIIDOC_SHEBANG MATCHES "python2")
    440       find_package(Python2 COMPONENTS Interpreter)
    441       set(ASCIIDOC_PY_FOUND "${Python2_Interpreter_FOUND}")
    442       set(ASCIIDOC_PY Python2::Interpreter)
    443     elseif(ASCIIDOC_SHEBANG MATCHES "python3")
    444       find_package(Python3 COMPONENTS Interpreter)
    445       set(ASCIIDOC_PY_FOUND "${Python3_Interpreter_FOUND}")
    446       set(ASCIIDOC_PY Python3::Interpreter)
    447     else()
    448       find_package(Python COMPONENTS Interpreter QUIET)
    449       if(NOT Python_Interpreter_FOUND)
    450         find_program(ASCIIDOC_PY python)
    451         if(ASCIIDOC_PY)
    452           set(ASCIIDOC_PY_FOUND ON)
    453         endif()
    454       else()
    455         set(ASCIIDOC_PY_FOUND "${Python_Interpreter_FOUND}")
    456         set(ASCIIDOC_PY Python::Interpreter)
    457       endif()
    458     endif()
    459 
    460     if (ASCIIDOC_PY_FOUND)
    461       set(MANPAGE_FILES "")
    462       set(MANPAGES "")
    463       foreach(PAGE IN ITEMS cjxl djxl)
    464         # Invoking the Python interpreter ourselves instead of running the a2x binary
    465         # directly is necessary on MSYS2, otherwise it is run through cmd.exe which
    466         # does not recognize it.
    467         add_custom_command(
    468           OUTPUT "${PAGE}.1"
    469           COMMAND "${ASCIIDOC_PY}"
    470           ARGS ${ASCIIDOC}
    471             --format manpage --destination-dir="${CMAKE_CURRENT_BINARY_DIR}"
    472             "${CMAKE_CURRENT_SOURCE_DIR}/doc/man/${PAGE}.txt"
    473           MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/doc/man/${PAGE}.txt")
    474         list(APPEND MANPAGE_FILES "${CMAKE_CURRENT_BINARY_DIR}/${PAGE}.1")
    475         list(APPEND MANPAGES "${PAGE}.1")
    476       endforeach()
    477       add_custom_target(manpages ALL DEPENDS ${MANPAGES})
    478       install(FILES ${MANPAGE_FILES} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
    479     endif()  # ASCIIDOC_PY_FOUND
    480   else()
    481     message(WARNING "asciidoc was not found, the man pages will not be installed.")
    482   endif()  # ASCIIDOC
    483 endif()  # JPEGXL_ENABLE_MANPAGES
    484 
    485 # Example usage code.
    486 if (JPEGXL_ENABLE_EXAMPLES)
    487   include(examples/examples.cmake)
    488 endif ()
    489 
    490 # Plugins for third-party software
    491 if (JPEGXL_ENABLE_PLUGINS)
    492   add_subdirectory(plugins)
    493 endif ()
    494 
    495 # Binary tools
    496 add_subdirectory(tools)
    497 
    498 
    499 macro(list_test_targets out dir)
    500   get_property(dir_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
    501   foreach(target ${dir_targets})
    502     if (target MATCHES ".*_test")
    503       list(APPEND ${out} ${target})
    504     endif()
    505   endforeach()
    506   get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
    507   foreach(subdir ${subdirectories})
    508     list_test_targets(${out} ${subdir})
    509   endforeach()
    510 endmacro()
    511 
    512 set(all_tests_list)
    513 list_test_targets(all_tests_list ${CMAKE_CURRENT_SOURCE_DIR})
    514 
    515 if(all_tests_list)
    516   add_custom_target(all_tests)
    517   add_dependencies(all_tests ${all_tests_list})
    518 endif()