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