xref: /aosp_15_r20/external/libpng/CMakeLists.txt (revision a67afe4df73cf47866eedc69947994b8ff839aba)
1
2# CMakeLists.txt - CMake lists for libpng
3#
4# Copyright (c) 2018-2024 Cosmin Truta.
5# Copyright (c) 2007-2018 Glenn Randers-Pehrson.
6# Originally written by Christian Ehrlicher, 2007.
7#
8# Use, modification and distribution are subject to
9# the same licensing terms and conditions as libpng.
10# Please see the copyright notice in png.h or visit
11# http://libpng.org/pub/png/src/libpng-LICENSE.txt
12#
13# For copyright and licensing purposes, please see
14# the accompanying file scripts/cmake/AUTHORS.md
15#
16# SPDX-License-Identifier: libpng-2.0
17
18cmake_minimum_required(VERSION 3.6)
19
20set(PNGLIB_MAJOR 1)
21set(PNGLIB_MINOR 6)
22set(PNGLIB_REVISION 44)
23set(PNGLIB_SUBREVISION 0)
24#set(PNGLIB_SUBREVISION "git")
25set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_REVISION})
26set(PNGLIB_ABI_VERSION ${PNGLIB_MAJOR}${PNGLIB_MINOR})
27set(PNGLIB_SHARED_VERSION ${PNGLIB_ABI_VERSION}.${PNGLIB_REVISION}.${PNGLIB_SUBREVISION})
28
29project(libpng
30        VERSION ${PNGLIB_VERSION}
31        LANGUAGES C ASM)
32
33if(POLICY CMP0074)
34  # Allow find_package() to use the ZLIB_ROOT variable, if available.
35  cmake_policy(SET CMP0074 NEW)
36endif()
37
38include(CheckCSourceCompiles)
39include(GNUInstallDirs)
40
41# Allow the users to specify an application-specific API prefix for libpng
42# vendoring purposes. A standard libpng build should have no such prefix.
43set(PNG_PREFIX ""
44    CACHE STRING "Prefix to prepend to the API function names")
45
46# Allow the users to override the postfix appended to debug library file names.
47# Previously, we used to set CMAKE_DEBUG_POSTFIX globally. That variable should
48# not be cached, however, because doing so would affect all projects processed
49# after libpng, in unexpected and undesirable ways.
50set(PNG_DEBUG_POSTFIX "d"
51    CACHE STRING "Postfix to append to library file names under the Debug configuration")
52
53# Allow the users to import their own extra configuration settings.
54set(DFA_XTRA ""
55    CACHE FILEPATH "File containing extra configuration settings")
56
57# Allow the users to switch on/off various library build types.
58option(PNG_SHARED "Build libpng as a shared library" ON)
59option(PNG_STATIC "Build libpng as a static library" ON)
60if(APPLE)
61  option(PNG_FRAMEWORK "Build libpng as a framework bundle" ON)
62endif()
63
64# Allow the users to switch on/off the auxiliary build and test artifacts.
65# These artifacts are NOT part of libpng proper, and are subject to change
66# at any time.
67option(PNG_TESTS "Build the libpng tests" ON)
68
69# Same as above, but for the third-party tools.
70# Although these tools are targetted at development environments only,
71# the users are allowed to override the option to build by default.
72if (ANDROID OR IOS)
73  option(PNG_TOOLS "Build the libpng tools" OFF)
74else()
75  option(PNG_TOOLS "Build the libpng tools" ON)
76endif()
77
78# Maintain backwards compatibility with the deprecated option PNG_EXECUTABLES.
79option(PNG_EXECUTABLES "[Deprecated; please use PNG_TOOLS]" ON)
80if(NOT PNG_EXECUTABLES)
81  message(DEPRECATION "The option PNG_EXECUTABLES has been deprecated in favour of PNG_TOOLS")
82  if(PNG_TOOLS)
83    message(AUTHOR_WARNING
84            "Setting PNG_TOOLS to ${PNG_EXECUTABLES}, to stay compatible with PNG_EXECUTABLES")
85    set(PNG_TOOLS "${PNG_EXECUTABLES}")
86  endif()
87endif()
88
89# Allow the users to configure various compilation options.
90option(PNG_DEBUG "Enable debug output" OFF)
91option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON)
92
93# Initialize and show the target architecture variable PNG_TARGET_ARCHITECTURE.
94#
95# NOTE:
96# On macOS, CMake sets CMAKE_SYSTEM_PROCESSOR to either "x86_64" or "arm64",
97# based upon the OS architecture, not the target architecture. As such, we need
98# to check CMAKE_OSX_ARCHITECTURES to identify which hardware-specific flags to
99# enable. Note that this will fail if you attempt to build a universal binary
100# in a single CMake invocation.
101if (APPLE AND CMAKE_OSX_ARCHITECTURES)
102  string(TOLOWER "${CMAKE_OSX_ARCHITECTURES}" PNG_TARGET_ARCHITECTURE)
103else()
104  string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" PNG_TARGET_ARCHITECTURE)
105endif()
106message(STATUS "Building for target architecture: ${PNG_TARGET_ARCHITECTURE}")
107
108# Allow the users to specify a custom location of zlib.
109# This option is deprecated, and no longer needed with CMake 3.12 and newer.
110# Under the CMake policy CMP0074, if zlib is being built alongside libpng as a
111# subproject, its location can be passed on to CMake via the ZLIB_ROOT variable.
112option(PNG_BUILD_ZLIB "Custom zlib location, else find_package is used" OFF)
113if(NOT PNG_BUILD_ZLIB)
114  find_package(ZLIB REQUIRED)
115elseif(POLICY CMP0074)
116  if("x${ZLIB_ROOT}" STREQUAL "x")
117    message(DEPRECATION
118            "The option PNG_BUILD_ZLIB has been deprecated; please use ZLIB_ROOT instead")
119  else()
120    message(SEND_ERROR
121            "The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} and "
122            "the variable ZLIB_ROOT=\"${ZLIB_ROOT}\" are mutually exclusive")
123  endif()
124endif()
125
126if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU AND NOT EMSCRIPTEN)
127  find_library(M_LIBRARY m)
128  if(M_LIBRARY)
129    set(M_LIBRARY m)
130  else()
131    set(M_LIBRARY "")
132  endif()
133else()
134  # libm is not available or not needed.
135endif()
136
137if(PNG_HARDWARE_OPTIMIZATIONS)
138
139# Set definitions and sources for ARM.
140if(PNG_TARGET_ARCHITECTURE MATCHES "^(arm|aarch)")
141  if(PNG_TARGET_ARCHITECTURE MATCHES "^(arm64|aarch64)")
142    set(PNG_ARM_NEON_POSSIBLE_VALUES on off)
143    set(PNG_ARM_NEON "on"
144        CACHE STRING "Enable ARM NEON optimizations: on|off; on is default")
145  else()
146    set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
147    set(PNG_ARM_NEON "off"
148        CACHE STRING "Enable ARM NEON optimizations: check|on|off; off is default")
149  endif()
150  set_property(CACHE PNG_ARM_NEON
151               PROPERTY STRINGS ${PNG_ARM_NEON_POSSIBLE_VALUES})
152  list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index)
153  if(index EQUAL -1)
154    message(FATAL_ERROR "PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]")
155  elseif(NOT PNG_ARM_NEON STREQUAL "off")
156    set(libpng_arm_sources
157        arm/arm_init.c
158        arm/filter_neon_intrinsics.c
159        arm/palette_neon_intrinsics.c)
160    if(PNG_ARM_NEON STREQUAL "on")
161      add_definitions(-DPNG_ARM_NEON_OPT=2)
162    elseif(PNG_ARM_NEON STREQUAL "check")
163      add_definitions(-DPNG_ARM_NEON_CHECK_SUPPORTED)
164    endif()
165  else()
166    add_definitions(-DPNG_ARM_NEON_OPT=0)
167  endif()
168endif()
169
170# Set definitions and sources for PowerPC.
171if(PNG_TARGET_ARCHITECTURE MATCHES "^(powerpc|ppc64)")
172  set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
173  set(PNG_POWERPC_VSX "on"
174      CACHE STRING "Enable POWERPC VSX optimizations: on|off; on is default")
175  set_property(CACHE PNG_POWERPC_VSX
176               PROPERTY STRINGS ${PNG_POWERPC_VSX_POSSIBLE_VALUES})
177  list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index)
178  if(index EQUAL -1)
179    message(FATAL_ERROR "PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]")
180  elseif(NOT PNG_POWERPC_VSX STREQUAL "off")
181    set(libpng_powerpc_sources
182        powerpc/powerpc_init.c
183        powerpc/filter_vsx_intrinsics.c)
184    if(PNG_POWERPC_VSX STREQUAL "on")
185      add_definitions(-DPNG_POWERPC_VSX_OPT=2)
186    endif()
187  else()
188    add_definitions(-DPNG_POWERPC_VSX_OPT=0)
189  endif()
190endif()
191
192# Set definitions and sources for Intel.
193if(PNG_TARGET_ARCHITECTURE MATCHES "^(i[3-6]86|x86|amd64)")
194  set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
195  set(PNG_INTEL_SSE "on"
196      CACHE STRING "Enable INTEL_SSE optimizations: on|off; on is default")
197  set_property(CACHE PNG_INTEL_SSE
198               PROPERTY STRINGS ${PNG_INTEL_SSE_POSSIBLE_VALUES})
199  list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index)
200  if(index EQUAL -1)
201    message(FATAL_ERROR "PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]")
202  elseif(NOT PNG_INTEL_SSE STREQUAL "off")
203    set(libpng_intel_sources
204        intel/intel_init.c
205        intel/filter_sse2_intrinsics.c)
206    if(PNG_INTEL_SSE STREQUAL "on")
207      add_definitions(-DPNG_INTEL_SSE_OPT=1)
208    endif()
209  else()
210    add_definitions(-DPNG_INTEL_SSE_OPT=0)
211  endif()
212endif()
213
214# Set definitions and sources for MIPS.
215if(PNG_TARGET_ARCHITECTURE MATCHES "^(mipsel|mips64el)")
216  set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
217  set(PNG_MIPS_MSA "on"
218      CACHE STRING "Enable MIPS_MSA optimizations: on|off; on is default")
219  set_property(CACHE PNG_MIPS_MSA
220               PROPERTY STRINGS ${PNG_MIPS_MSA_POSSIBLE_VALUES})
221  list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index_msa)
222  if(index_msa EQUAL -1)
223    message(FATAL_ERROR "PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]")
224  endif()
225
226  set(PNG_MIPS_MMI_POSSIBLE_VALUES on off)
227  set(PNG_MIPS_MMI "on"
228      CACHE STRING "Enable MIPS_MMI optimizations: on|off; on is default")
229  set_property(CACHE PNG_MIPS_MMI
230               PROPERTY STRINGS ${PNG_MIPS_MMI_POSSIBLE_VALUES})
231  list(FIND PNG_MIPS_MMI_POSSIBLE_VALUES ${PNG_MIPS_MMI} index_mmi)
232  if(index_mmi EQUAL -1)
233    message(FATAL_ERROR "PNG_MIPS_MMI must be one of [${PNG_MIPS_MMI_POSSIBLE_VALUES}]")
234  endif()
235
236  if(PNG_MIPS_MSA STREQUAL "on" AND PNG_MIPS_MMI STREQUAL "on")
237    set(libpng_mips_sources
238        mips/mips_init.c
239        mips/filter_msa_intrinsics.c
240        mips/filter_mmi_inline_assembly.c)
241    add_definitions(-DPNG_MIPS_MSA_OPT=2)
242    add_definitions(-DPNG_MIPS_MMI_OPT=1)
243  elseif(PNG_MIPS_MSA STREQUAL "on")
244    set(libpng_mips_sources
245        mips/mips_init.c
246        mips/filter_msa_intrinsics.c)
247    add_definitions(-DPNG_MIPS_MSA_OPT=2)
248    add_definitions(-DPNG_MIPS_MMI_OPT=0)
249  elseif(PNG_MIPS_MMI STREQUAL "on")
250    set(libpng_mips_sources
251        mips/mips_init.c
252        mips/filter_mmi_inline_assembly.c)
253    add_definitions(-DPNG_MIPS_MSA_OPT=0)
254    add_definitions(-DPNG_MIPS_MMI_OPT=1)
255    else()
256    add_definitions(-DPNG_MIPS_MSA_OPT=0)
257    add_definitions(-DPNG_MIPS_MMI_OPT=0)
258    endif()
259endif()
260
261# Set definitions and sources for LoongArch.
262if(PNG_TARGET_ARCHITECTURE MATCHES "^(loongarch)")
263  include(CheckCCompilerFlag)
264  set(PNG_LOONGARCH_LSX_POSSIBLE_VALUES on off)
265  set(PNG_LOONGARCH_LSX "on"
266      CACHE STRING "Enable LOONGARCH_LSX optimizations: on|off; on is default")
267  set_property(CACHE PNG_LOONGARCH_LSX
268               PROPERTY STRINGS ${PNG_LOONGARCH_LSX_POSSIBLE_VALUES})
269  list(FIND PNG_LOONGARCH_LSX_POSSIBLE_VALUES ${PNG_LOONGARCH_LSX} index)
270  if(index EQUAL -1)
271    message(FATAL_ERROR "PNG_LOONGARCH_LSX must be one of [${PNG_LOONGARCH_LSX_POSSIBLE_VALUES}]")
272  elseif(NOT PNG_LOONGARCH_LSX STREQUAL "off")
273    CHECK_C_COMPILER_FLAG("-mlsx" COMPILER_SUPPORTS_LSX)
274    if(COMPILER_SUPPORTS_LSX)
275      set(libpng_loongarch_sources
276          loongarch/loongarch_lsx_init.c
277          loongarch/filter_lsx_intrinsics.c)
278      set_source_files_properties(${libpng_loongarch_sources}
279                                  PROPERTIES
280                                  COMPILE_FLAGS "-mlsx")
281      add_definitions(-DPNG_LOONGARCH_LSX_OPT=1)
282    else()
283      message(FATAL_ERROR "Compiler does not support -mlsx option")
284    endif()
285  else()
286    add_definitions(-DPNG_LOONGARCH_LSX_OPT=0)
287  endif()
288endif()
289
290else(PNG_HARDWARE_OPTIMIZATIONS)
291
292# Set definitions and sources for ARM.
293if(PNG_TARGET_ARCHITECTURE MATCHES "^(arm|aarch)")
294  add_definitions(-DPNG_ARM_NEON_OPT=0)
295endif()
296
297# Set definitions and sources for PowerPC.
298if(PNG_TARGET_ARCHITECTURE MATCHES "^(powerpc|ppc64)")
299  add_definitions(-DPNG_POWERPC_VSX_OPT=0)
300endif()
301
302# Set definitions and sources for Intel.
303if(PNG_TARGET_ARCHITECTURE MATCHES "^(i[3-6]86|x86|amd64)")
304  add_definitions(-DPNG_INTEL_SSE_OPT=0)
305endif()
306
307# Set definitions and sources for MIPS.
308if(PNG_TARGET_ARCHITECTURE MATCHES "^(mipsel|mips64el)")
309  add_definitions(-DPNG_MIPS_MSA_OPT=0)
310endif()
311
312# Set definitions and sources for LoongArch.
313if(PNG_TARGET_ARCHITECTURE MATCHES "^(loongarch)")
314  add_definitions(-DPNG_LOONGARCH_LSX_OPT=0)
315endif()
316
317endif(PNG_HARDWARE_OPTIMIZATIONS)
318
319option(ld-version-script "Enable linker version script" ON)
320if(ld-version-script AND NOT ANDROID AND NOT APPLE)
321  # Check if LD supports linker scripts.
322  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" "
323VERS_1 { global: sym1; local: *; };
324VERS_2 { global: sym2; main; } VERS_1;
325")
326  set(_SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
327  if(NOT CMAKE_HOST_SOLARIS)
328    # Avoid using CMAKE_SHARED_LIBRARY_C_FLAGS in version script checks on
329    # Solaris, because of an incompatibility with the Solaris link editor.
330    list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
331  endif()
332  list(APPEND CMAKE_REQUIRED_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'")
333  check_c_source_compiles("
334void sym1(void) {}
335void sym2(void) {}
336int main(void) { return 0; }
337" HAVE_LD_VERSION_SCRIPT)
338  if(NOT HAVE_LD_VERSION_SCRIPT)
339    set(CMAKE_REQUIRED_FLAGS ${_SAVED_CMAKE_REQUIRED_FLAGS})
340    if(NOT CMAKE_HOST_SOLARIS)
341      # Again, avoid using CMAKE_SHARED_LIBRARY_C_FLAGS in version script
342      # checks on Solaris.
343      list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
344    endif()
345    list(APPEND CMAKE_REQUIRED_FLAGS "-Wl,-M -Wl,${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
346    check_c_source_compiles("
347void sym1(void) {}
348void sym2(void) {}
349int main(void) { return 0; }
350" HAVE_SOLARIS_LD_VERSION_SCRIPT)
351  endif()
352  set(CMAKE_REQUIRED_FLAGS ${_SAVED_CMAKE_REQUIRED_FLAGS})
353  file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
354endif()
355
356# Find an AWK language processor.
357# Start with specific AWK implementations like gawk and nawk, which are
358# known to work with our scripts, then fall back to the system awk.
359find_program(AWK NAMES gawk nawk awk)
360if(AWK)
361  message(STATUS "Found AWK program: ${AWK}")
362else()
363  message(STATUS "Could not find an AWK-compatible program")
364endif()
365
366if(NOT AWK OR ANDROID OR IOS)
367  # No awk available to generate sources; use pre-built pnglibconf.h
368  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
369                 ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
370  add_custom_target(png_genfiles)
371else()
372  # Copy the awk scripts, converting their line endings to Unix (LF)
373  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk
374                 ${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk
375                 @ONLY
376                 NEWLINE_STYLE LF)
377  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk
378                 ${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk
379                 @ONLY
380                 NEWLINE_STYLE LF)
381  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/dfn.awk
382                 ${CMAKE_CURRENT_BINARY_DIR}/scripts/dfn.awk
383                 @ONLY
384                 NEWLINE_STYLE LF)
385
386  # Generate .chk from .out with awk:
387  # generate_chk(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
388  function(generate_chk)
389    set(options)
390    set(oneValueArgs INPUT OUTPUT)
391    set(multiValueArgs DEPENDS)
392    cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
393    if(NOT _GC_INPUT)
394      message(FATAL_ERROR "generate_chk: Missing INPUT argument")
395    endif()
396    if(NOT _GC_OUTPUT)
397      message(FATAL_ERROR "generate_chk: Missing OUTPUT argument")
398    endif()
399
400    add_custom_command(OUTPUT "${_GC_OUTPUT}"
401                       COMMAND "${CMAKE_COMMAND}"
402                               "-DINPUT=${_GC_INPUT}"
403                               "-DOUTPUT=${_GC_OUTPUT}"
404                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake"
405                       DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS}
406                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
407  endfunction()
408
409  # Generate .out from .c with awk
410  # generate_out(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
411  function(generate_out)
412    set(options)
413    set(oneValueArgs INPUT OUTPUT)
414    set(multiValueArgs DEPENDS)
415    cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
416    if(NOT _GO_INPUT)
417      message(FATAL_ERROR "generate_out: Missing INPUT argument")
418    endif()
419    if(NOT _GO_OUTPUT)
420      message(FATAL_ERROR "generate_out: Missing OUTPUT argument")
421    endif()
422
423    add_custom_command(OUTPUT "${_GO_OUTPUT}"
424                       COMMAND "${CMAKE_COMMAND}"
425                               "-DINPUT=${_GO_INPUT}"
426                               "-DOUTPUT=${_GO_OUTPUT}"
427                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake"
428                       DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS}
429                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
430  endfunction()
431
432  # Generate specific source file with awk
433  # generate_source(OUTPUT outputfile [DEPENDS dep1 [dep2...]])
434  function(generate_source)
435    set(options)
436    set(oneValueArgs OUTPUT)
437    set(multiValueArgs DEPENDS)
438    cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
439    if(NOT _GSO_OUTPUT)
440      message(FATAL_ERROR "generate_source: Missing OUTPUT argument")
441    endif()
442
443    add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}"
444                       COMMAND "${CMAKE_COMMAND}"
445                               "-DOUTPUT=${_GSO_OUTPUT}"
446                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake"
447                       DEPENDS ${_GSO_DEPENDS}
448                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
449  endfunction()
450
451  # Copy file
452  # generate_copy(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
453  function(generate_copy)
454    set(options)
455    set(oneValueArgs INPUT OUTPUT)
456    set(multiValueArgs DEPENDS)
457    cmake_parse_arguments(_GCO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
458    if(NOT _GCO_INPUT)
459      message(FATAL_ERROR "generate_copy: Missing INPUT argument")
460    endif()
461    if(NOT _GCO_OUTPUT)
462      message(FATAL_ERROR "generate_copy: Missing OUTPUT argument")
463    endif()
464
465    add_custom_command(OUTPUT "${_GCO_OUTPUT}"
466                       COMMAND "${CMAKE_COMMAND}"
467                               -E remove "${_GCO_OUTPUT}"
468                       COMMAND "${CMAKE_COMMAND}"
469                               -E copy "${_GCO_INPUT}" "${_GCO_OUTPUT}"
470                       DEPENDS "${source}" ${_GCO_DEPENDS})
471  endfunction()
472
473  # Generate scripts/pnglibconf.h
474  generate_source(OUTPUT "scripts/pnglibconf.c"
475                  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
476                          "${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk"
477                          "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
478  add_custom_target(png_scripts_pnglibconf_c
479                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c")
480
481  # Generate pnglibconf.c
482  generate_source(OUTPUT "pnglibconf.c"
483                  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
484                          "${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk"
485                          "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
486  add_custom_target(pnglibconf_c
487                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c")
488
489  if(PNG_PREFIX)
490    set(PNGLIBCONF_H_EXTRA_DEPENDS
491        "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
492        "${CMAKE_CURRENT_SOURCE_DIR}/scripts/macro.lst")
493    set(PNGPREFIX_H_EXTRA_DEPENDS
494        "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out")
495  endif()
496
497  generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
498               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
499               DEPENDS pnglibconf_c)
500  add_custom_target(pnglibconf_out
501                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
502
503  # Generate pnglibconf.h
504  generate_source(OUTPUT "pnglibconf.h"
505                  DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out
506                          ${PNGLIBCONF_H_EXTRA_DEPENDS})
507  add_custom_target(pnglibconf_h
508                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
509
510  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c"
511               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
512               DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h)
513  add_custom_target(png_scripts_intprefix_out
514                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out")
515
516  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c"
517               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
518               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
519                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
520                       "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out)
521  add_custom_target(png_scripts_prefix_out
522                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out")
523
524  # Generate pngprefix.h
525  generate_source(OUTPUT "pngprefix.h"
526                  DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS})
527  add_custom_target(pngprefix_h
528                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
529
530  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c"
531               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
532               DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h)
533  add_custom_target(png_scripts_sym_out
534                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out")
535
536  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c"
537               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
538               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
539                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
540                       "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt")
541  add_custom_target(png_scripts_symbols_out
542                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out")
543
544  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c"
545               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
546               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
547                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
548                       "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h)
549  add_custom_target(png_scripts_vers_out
550                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
551
552  generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
553               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
554               DEPENDS png_scripts_symbols_out
555                       "${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk"
556                       "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def")
557
558  add_custom_target(png_scripts_symbols_chk
559                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk")
560
561  generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
562                OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym"
563                DEPENDS png_scripts_sym_out)
564  generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
565                OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
566                DEPENDS png_scripts_vers_out)
567
568  add_custom_target(png_genvers
569                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
570  add_custom_target(png_gensym
571                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
572
573  add_custom_target(png_genprebuilt
574                    COMMAND "${CMAKE_COMMAND}"
575                            "-DOUTPUT=scripts/pnglibconf.h.prebuilt"
576                            -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake"
577                    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
578
579  # A single target handles generation of all generated files.
580  add_custom_target(png_genfiles
581                    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym" png_gensym
582                            "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers" png_genvers
583                            "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" pnglibconf_c
584                            "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h
585                            "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out
586                            "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h" pngprefix_h
587                            "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" png_scripts_intprefix_out
588                            "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c" png_scripts_pnglibconf_c
589                            "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" png_scripts_prefix_out
590                            "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" png_scripts_sym_out
591                            "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" png_scripts_symbols_chk
592                            "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" png_scripts_symbols_out
593                            "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" png_scripts_vers_out)
594endif(NOT AWK OR ANDROID OR IOS)
595
596# List the source code files.
597set(libpng_public_hdrs
598    png.h
599    pngconf.h
600    "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
601)
602set(libpng_private_hdrs
603    pngpriv.h
604    pngdebug.h
605    pnginfo.h
606    pngstruct.h
607)
608if(AWK AND NOT ANDROID AND NOT IOS)
609  list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
610endif()
611set(libpng_sources
612    ${libpng_public_hdrs}
613    ${libpng_private_hdrs}
614    png.c
615    pngerror.c
616    pngget.c
617    pngmem.c
618    pngpread.c
619    pngread.c
620    pngrio.c
621    pngrtran.c
622    pngrutil.c
623    pngset.c
624    pngtrans.c
625    pngwio.c
626    pngwrite.c
627    pngwtran.c
628    pngwutil.c
629    ${libpng_arm_sources}
630    ${libpng_intel_sources}
631    ${libpng_mips_sources}
632    ${libpng_powerpc_sources}
633    ${libpng_loongarch_sources}
634)
635set(pngtest_sources
636    pngtest.c
637)
638set(pngvalid_sources
639    contrib/libtests/pngvalid.c
640)
641set(pngstest_sources
642    contrib/libtests/pngstest.c
643)
644set(pngunknown_sources
645    contrib/libtests/pngunknown.c
646)
647set(pngimage_sources
648    contrib/libtests/pngimage.c
649)
650set(pngfix_sources
651    contrib/tools/pngfix.c
652)
653set(png_fix_itxt_sources
654    contrib/tools/png-fix-itxt.c
655)
656
657if(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID MATCHES "Clang")))
658  add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
659  add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
660endif()
661
662if(PNG_DEBUG)
663  add_definitions(-DPNG_DEBUG)
664endif()
665
666# Now build our targets.
667
668# Initialize the list of libpng library targets.
669set(PNG_LIBRARY_TARGETS "")
670
671# Initialize the libpng library file names.
672if(UNIX
673   OR (WIN32 AND NOT CMAKE_SHARED_LIBRARY_PREFIX STREQUAL "")
674   OR (WIN32 AND NOT CMAKE_STATIC_LIBRARY_PREFIX STREQUAL ""))
675  # We are on a Unix or Unix-like toolchain like the GNU toolchain on Windows.
676  # Library file names are expected to have an implicit prefix such as "lib".
677  # Let CMake prepend and append its usual prefixes and suffixes by default.
678  set(PNG_SHARED_OUTPUT_NAME "png${PNGLIB_ABI_VERSION}")
679  set(PNG_STATIC_OUTPUT_NAME "png${PNGLIB_ABI_VERSION}")
680else()
681  # We are, most likely, on a Windows toolchain like MSVC, Clang on Windows,
682  # Borland/Embarcadero, etc. We need to specify the "libpng" name explicitly.
683  # We also need to use a custom suffix, in order to distinguish between the
684  # shared import library name and the static library name.
685  set(PNG_SHARED_OUTPUT_NAME "libpng${PNGLIB_ABI_VERSION}")
686  set(PNG_STATIC_OUTPUT_NAME "libpng${PNGLIB_ABI_VERSION}_static")
687endif()
688
689if(PNG_SHARED)
690  add_library(png_shared SHARED ${libpng_sources})
691  add_dependencies(png_shared png_genfiles)
692  list(APPEND PNG_LIBRARY_TARGETS png_shared)
693  set_target_properties(png_shared PROPERTIES
694                        OUTPUT_NAME "${PNG_SHARED_OUTPUT_NAME}"
695                        DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}"
696                        VERSION "${PNGLIB_SHARED_VERSION}"
697                        SOVERSION "${PNGLIB_ABI_VERSION}")
698  if(UNIX AND AWK)
699    if(HAVE_LD_VERSION_SCRIPT)
700      set_target_properties(png_shared PROPERTIES
701                            LINK_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
702    elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT)
703      set_target_properties(png_shared PROPERTIES
704                            LINK_FLAGS "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
705    endif()
706  endif()
707  if(APPLE)
708    # Avoid CMake's implicit compile definition "png_shared_EXPORTS".
709    set_target_properties(png_shared PROPERTIES DEFINE_SYMBOL "")
710  elseif(WIN32)
711    # Use the explicit compile definition "PNG_BUILD_DLL" for Windows DLLs.
712    set_target_properties(png_shared PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
713  endif()
714  target_include_directories(png_shared
715                             PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
716  target_include_directories(png_shared
717                             PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
718  target_include_directories(png_shared SYSTEM
719                             INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>)
720  target_link_libraries(png_shared PUBLIC ZLIB::ZLIB ${M_LIBRARY})
721endif()
722
723if(PNG_STATIC)
724  add_library(png_static STATIC ${libpng_sources})
725  add_dependencies(png_static png_genfiles)
726  list(APPEND PNG_LIBRARY_TARGETS png_static)
727  set_target_properties(png_static PROPERTIES
728                        OUTPUT_NAME "${PNG_STATIC_OUTPUT_NAME}"
729                        DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}")
730  target_include_directories(png_static
731                             PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
732  target_include_directories(png_static
733                             PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
734  target_include_directories(png_static SYSTEM
735                             INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>)
736  target_link_libraries(png_static PUBLIC ZLIB::ZLIB ${M_LIBRARY})
737endif()
738
739if(PNG_FRAMEWORK AND NOT APPLE)
740  message(AUTHOR_WARNING
741          "Setting PNG_FRAMEWORK to OFF, as it only applies to Apple systems")
742  set(PNG_FRAMEWORK OFF)
743endif()
744
745if(PNG_FRAMEWORK)
746  add_library(png_framework SHARED ${libpng_sources})
747  add_dependencies(png_framework png_genfiles)
748  list(APPEND PNG_LIBRARY_TARGETS png_framework)
749  set_target_properties(png_framework PROPERTIES
750                        FRAMEWORK TRUE
751                        FRAMEWORK_VERSION "${PNGLIB_VERSION}"
752                        MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PNGLIB_MAJOR}.${PNGLIB_MINOR}"
753                        MACOSX_FRAMEWORK_BUNDLE_VERSION "${PNGLIB_VERSION}"
754                        MACOSX_FRAMEWORK_IDENTIFIER "org.libpng.libpng"
755                        XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
756                        PUBLIC_HEADER "${libpng_public_hdrs}"
757                        OUTPUT_NAME "png"
758                        DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}")
759  # Avoid CMake's implicit compile definition "-Dpng_framework_EXPORTS".
760  set_target_properties(png_framework PROPERTIES DEFINE_SYMBOL "")
761  target_include_directories(png_framework
762                             PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
763  target_include_directories(png_framework
764                             PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
765  target_include_directories(png_framework SYSTEM
766                             INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>)
767  target_link_libraries(png_framework PUBLIC ZLIB::ZLIB ${M_LIBRARY})
768endif()
769
770if(NOT PNG_LIBRARY_TARGETS)
771  message(SEND_ERROR "No library variant selected to build. "
772                     "Please enable at least one of the following options: "
773                     "PNG_SHARED, PNG_STATIC, PNG_FRAMEWORK")
774endif()
775
776if(PNG_TESTS AND PNG_SHARED)
777  enable_testing()
778
779  function(png_add_test)
780    set(options)
781    set(oneValueArgs NAME COMMAND)
782    set(multiValueArgs OPTIONS FILES)
783    cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
784    if(NOT _PAT_NAME)
785      message(FATAL_ERROR "png_add_test: Missing NAME argument")
786    endif()
787    if(NOT _PAT_COMMAND)
788      message(FATAL_ERROR "png_add_test: Missing COMMAND argument")
789    endif()
790
791    set(TEST_OPTIONS "${_PAT_OPTIONS}")
792    set(TEST_FILES "${_PAT_FILES}")
793
794    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/test.cmake.in"
795                   "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake"
796                   @ONLY)
797    add_test(NAME "${_PAT_NAME}"
798             COMMAND "${CMAKE_COMMAND}"
799                     "-DLIBPNG=$<TARGET_FILE:png_shared>"
800                     "-DTEST_COMMAND=$<TARGET_FILE:${_PAT_COMMAND}>"
801                     -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
802  endfunction()
803
804  # Find test PNG files by globbing, but sort lists to ensure
805  # consistency between different filesystems.
806  file(GLOB PNGSUITE_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/*.png")
807  list(SORT PNGSUITE_PNGS)
808  file(GLOB TEST_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/*.png")
809  list(SORT TEST_PNGS)
810
811  set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png")
812
813  add_executable(pngtest ${pngtest_sources})
814  target_link_libraries(pngtest PRIVATE png_shared)
815
816  png_add_test(NAME pngtest
817               COMMAND pngtest
818               FILES "${PNGTEST_PNG}")
819
820  add_executable(pngvalid ${pngvalid_sources})
821  target_link_libraries(pngvalid PRIVATE png_shared)
822
823  png_add_test(NAME pngvalid-gamma-16-to-8
824               COMMAND pngvalid
825               OPTIONS --gamma-16-to-8)
826  png_add_test(NAME pngvalid-gamma-alpha-mode
827               COMMAND pngvalid
828               OPTIONS --gamma-alpha-mode)
829  png_add_test(NAME pngvalid-gamma-background
830               COMMAND pngvalid
831               OPTIONS --gamma-background)
832  png_add_test(NAME pngvalid-gamma-expand16-alpha-mode
833               COMMAND pngvalid
834               OPTIONS --gamma-alpha-mode --expand16)
835  png_add_test(NAME pngvalid-gamma-expand16-background
836               COMMAND pngvalid
837               OPTIONS --gamma-background --expand16)
838  png_add_test(NAME pngvalid-gamma-expand16-transform
839               COMMAND pngvalid
840               OPTIONS --gamma-transform --expand16)
841  png_add_test(NAME pngvalid-gamma-sbit
842               COMMAND pngvalid
843               OPTIONS --gamma-sbit)
844  png_add_test(NAME pngvalid-gamma-threshold
845               COMMAND pngvalid
846               OPTIONS --gamma-threshold)
847  png_add_test(NAME pngvalid-gamma-transform
848               COMMAND pngvalid
849               OPTIONS --gamma-transform)
850  png_add_test(NAME pngvalid-progressive-interlace-standard
851               COMMAND pngvalid
852               OPTIONS --standard --progressive-read --interlace)
853  png_add_test(NAME pngvalid-progressive-size
854               COMMAND pngvalid
855               OPTIONS --size --progressive-read)
856  png_add_test(NAME pngvalid-progressive-standard
857               COMMAND pngvalid
858               OPTIONS --standard --progressive-read)
859  png_add_test(NAME pngvalid-standard
860               COMMAND pngvalid
861               OPTIONS --standard)
862  png_add_test(NAME pngvalid-transform
863               COMMAND pngvalid
864               OPTIONS --transform)
865
866  add_executable(pngstest ${pngstest_sources})
867  target_link_libraries(pngstest PRIVATE png_shared)
868
869  foreach(gamma_type 1.8 linear none sRGB)
870    foreach(alpha_type none alpha)
871      set(PNGSTEST_FILES)
872      foreach(test_png ${TEST_PNGS})
873        string(REGEX MATCH "-linear[-.]" TEST_PNG_LINEAR "${test_png}")
874        string(REGEX MATCH "-sRGB[-.]" TEST_PNG_SRGB "${test_png}")
875        string(REGEX MATCH "-1.8[-.]" TEST_PNG_G18 "${test_png}")
876        string(REGEX MATCH "-alpha-" TEST_PNG_ALPHA "${test_png}")
877
878        set(TEST_PNG_VALID TRUE)
879
880        if(TEST_PNG_ALPHA)
881          if(NOT alpha_type STREQUAL "alpha")
882            set(TEST_PNG_VALID FALSE)
883          endif()
884        else()
885          if(alpha_type STREQUAL "alpha")
886            set(TEST_PNG_VALID FALSE)
887          endif()
888        endif()
889
890        if(TEST_PNG_LINEAR)
891          if(NOT gamma_type STREQUAL "linear")
892            set(TEST_PNG_VALID FALSE)
893          endif()
894        elseif(TEST_PNG_SRGB)
895          if(NOT gamma_type STREQUAL "sRGB")
896            set(TEST_PNG_VALID FALSE)
897          endif()
898        elseif(TEST_PNG_G18)
899          if(NOT gamma_type STREQUAL "1.8")
900            set(TEST_PNG_VALID FALSE)
901          endif()
902        else()
903          if(NOT gamma_type STREQUAL "none")
904            set(TEST_PNG_VALID FALSE)
905          endif()
906        endif()
907
908        if(TEST_PNG_VALID)
909          list(APPEND PNGSTEST_FILES "${test_png}")
910        endif()
911      endforeach()
912      # Should already be sorted, but sort anyway to be certain.
913      list(SORT PNGSTEST_FILES)
914      png_add_test(NAME pngstest-${gamma_type}-${alpha_type}
915                   COMMAND pngstest
916                   OPTIONS --tmpfile "${gamma_type}-${alpha_type}-" --log
917                   FILES ${PNGSTEST_FILES})
918    endforeach()
919  endforeach()
920
921  add_executable(pngunknown ${pngunknown_sources})
922  target_link_libraries(pngunknown PRIVATE png_shared)
923
924  png_add_test(NAME pngunknown-discard
925               COMMAND pngunknown
926               OPTIONS --strict default=discard
927               FILES "${PNGTEST_PNG}")
928  png_add_test(NAME pngunknown-IDAT
929               COMMAND pngunknown
930               OPTIONS --strict default=discard IDAT=save
931               FILES "${PNGTEST_PNG}")
932  png_add_test(NAME pngunknown-if-safe
933               COMMAND pngunknown
934               OPTIONS --strict default=if-safe
935               FILES "${PNGTEST_PNG}")
936  png_add_test(NAME pngunknown-sAPI
937               COMMAND pngunknown
938               OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save
939               FILES "${PNGTEST_PNG}")
940  png_add_test(NAME pngunknown-save
941               COMMAND pngunknown
942               OPTIONS --strict default=save
943               FILES "${PNGTEST_PNG}")
944  png_add_test(NAME pngunknown-sTER
945               COMMAND pngunknown
946               OPTIONS --strict sTER=if-safe
947               FILES "${PNGTEST_PNG}")
948  png_add_test(NAME pngunknown-vpAg
949               COMMAND pngunknown
950               OPTIONS --strict vpAg=if-safe
951               FILES "${PNGTEST_PNG}")
952
953  add_executable(pngimage ${pngimage_sources})
954  target_link_libraries(pngimage PRIVATE png_shared)
955
956  png_add_test(NAME pngimage-quick
957               COMMAND pngimage
958               OPTIONS --list-combos --log
959               FILES ${PNGSUITE_PNGS})
960  png_add_test(NAME pngimage-full
961               COMMAND pngimage
962               OPTIONS --exhaustive --list-combos --log
963               FILES ${PNGSUITE_PNGS})
964endif()
965
966if(PNG_SHARED AND PNG_TOOLS)
967  add_executable(pngfix ${pngfix_sources})
968  target_link_libraries(pngfix PRIVATE png_shared)
969  set(PNG_BIN_TARGETS pngfix)
970
971  add_executable(png-fix-itxt ${png_fix_itxt_sources})
972  target_link_libraries(png-fix-itxt PRIVATE ZLIB::ZLIB ${M_LIBRARY})
973  list(APPEND PNG_BIN_TARGETS png-fix-itxt)
974endif()
975
976# Create a symlink from src to dest (if possible), or, alternatively,
977# copy src to dest if different.
978function(create_symlink DEST_FILE)
979  cmake_parse_arguments(_SYM "" "FILE;TARGET" "" ${ARGN})
980  if(NOT _SYM_FILE AND NOT _SYM_TARGET)
981    message(FATAL_ERROR "create_symlink: Missing FILE or TARGET argument")
982  endif()
983  if(_SYM_FILE AND _SYM_TARGET)
984    message(FATAL_ERROR "create_symlink: "
985                        "The arguments FILE (${_SYM_FILE}) and TARGET (${_SYM_TARGET}) "
986                        "are mutually-exclusive")
987  endif()
988
989  if(_SYM_FILE)
990    # If we don't need to symlink something that's coming from a build target,
991    # we can go ahead and symlink/copy at configure time.
992    if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
993      execute_process(COMMAND "${CMAKE_COMMAND}"
994                              -E copy_if_different
995                              ${_SYM_FILE} ${DEST_FILE}
996                      WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
997    else()
998      execute_process(COMMAND "${CMAKE_COMMAND}"
999                              -E create_symlink
1000                              ${_SYM_FILE} ${DEST_FILE}
1001                      WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
1002    endif()
1003  endif()
1004
1005  if(_SYM_TARGET)
1006    # We need to use generator expressions, which can be a bit tricky.
1007    # For simplicity, make the symlink a POST_BUILD step, and use the TARGET
1008    # signature of add_custom_command.
1009    if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
1010      add_custom_command(TARGET ${_SYM_TARGET}
1011                         POST_BUILD
1012                         COMMAND "${CMAKE_COMMAND}"
1013                                 -E copy_if_different
1014                                 $<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/$<TARGET_LINKER_FILE_NAME:${_SYM_TARGET}>
1015                                 $<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/${DEST_FILE})
1016    else()
1017      add_custom_command(TARGET ${_SYM_TARGET}
1018                         POST_BUILD
1019                         COMMAND "${CMAKE_COMMAND}"
1020                                 -E create_symlink
1021                                 $<TARGET_LINKER_FILE_NAME:${_SYM_TARGET}>
1022                                 $<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/${DEST_FILE})
1023    endif()
1024  endif()
1025endfunction()
1026
1027# Create source generation scripts.
1028configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genchk.cmake.in
1029               ${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake
1030               @ONLY)
1031configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genout.cmake.in
1032               ${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake
1033               @ONLY)
1034configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/gensrc.cmake.in
1035               ${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake
1036               @ONLY)
1037
1038# libpng is a library so default to 'lib'
1039if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
1040  set(CMAKE_INSTALL_LIBDIR lib)
1041endif()
1042
1043# Create pkgconfig files.
1044# We use the same files like ./configure, so we have to set its vars.
1045# Only do this on Windows for Cygwin - the files don't make much sense
1046# outside of a UNIX look-alike.
1047if(NOT WIN32 OR CYGWIN OR MINGW)
1048  set(prefix      ${CMAKE_INSTALL_PREFIX})
1049  set(exec_prefix ${CMAKE_INSTALL_PREFIX})
1050  set(libdir      ${CMAKE_INSTALL_FULL_LIBDIR})
1051  set(includedir  ${CMAKE_INSTALL_FULL_INCLUDEDIR})
1052  set(LIBS        "-lz -lm")
1053  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
1054                 ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc
1055                 @ONLY)
1056  create_symlink(libpng.pc FILE libpng${PNGLIB_ABI_VERSION}.pc)
1057  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in
1058                 ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config
1059                 @ONLY)
1060  create_symlink(libpng-config FILE libpng${PNGLIB_ABI_VERSION}-config)
1061endif()
1062
1063# Install.
1064if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
1065  install(TARGETS ${PNG_LIBRARY_TARGETS}
1066          EXPORT libpng
1067          RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
1068          LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
1069          ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
1070          FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
1071
1072  if(PNG_SHARED)
1073    # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
1074    if(NOT WIN32 OR CYGWIN OR MINGW)
1075      create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png_shared)
1076      install(FILES $<TARGET_LINKER_FILE_DIR:png_shared>/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}
1077              DESTINATION ${CMAKE_INSTALL_LIBDIR})
1078    endif()
1079  endif()
1080
1081  if(PNG_STATIC)
1082    if(NOT WIN32 OR CYGWIN OR MINGW)
1083      create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static)
1084      install(FILES $<TARGET_LINKER_FILE_DIR:png_static>/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}
1085              DESTINATION ${CMAKE_INSTALL_LIBDIR})
1086    endif()
1087  endif()
1088endif()
1089
1090if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
1091  install(FILES ${libpng_public_hdrs}
1092          DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
1093  install(FILES ${libpng_public_hdrs}
1094          DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION})
1095endif()
1096if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL)
1097  if(NOT WIN32 OR CYGWIN OR MINGW)
1098    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
1099            DESTINATION ${CMAKE_INSTALL_BINDIR})
1100    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config
1101            DESTINATION ${CMAKE_INSTALL_BINDIR})
1102  endif()
1103endif()
1104
1105if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL)
1106  install(TARGETS ${PNG_BIN_TARGETS}
1107          RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
1108endif()
1109
1110if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL)
1111  # Install the man pages.
1112  install(FILES libpng.3 libpngpf.3
1113          DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
1114  install(FILES png.5
1115          DESTINATION ${CMAKE_INSTALL_MANDIR}/man5)
1116  # Install the pkg-config files.
1117  if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
1118    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
1119            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
1120    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
1121            DESTINATION ${CMAKE_INSTALL_BINDIR})
1122    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc
1123            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
1124    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config
1125            DESTINATION ${CMAKE_INSTALL_BINDIR})
1126  endif()
1127endif()
1128
1129# Create an export file that CMake users can include() to import our targets.
1130if(NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL)
1131  install(EXPORT libpng
1132          DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpng
1133          FILE libpng${PNGLIB_ABI_VERSION}.cmake)
1134endif()
1135
1136# Create a CMake Config File that can be used via find_package(PNG CONFIG)
1137if(NOT SKIP_INSTALL_CONFIG_FILE AND NOT SKIP_INSTALL_ALL)
1138  install(TARGETS ${PNG_LIBRARY_TARGETS}
1139          EXPORT PNGTargets
1140          RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
1141          LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
1142          ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
1143          FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
1144
1145  include(CMakePackageConfigHelpers)
1146  write_basic_package_version_file(PNGConfigVersion.cmake
1147                                   VERSION ${PNGLIB_VERSION}
1148                                   COMPATIBILITY SameMinorVersion)
1149
1150  install(EXPORT PNGTargets
1151          FILE PNGTargets.cmake
1152          NAMESPACE PNG::
1153          DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PNG)
1154
1155  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGConfig.cmake
1156                ${CMAKE_CURRENT_BINARY_DIR}/PNGConfigVersion.cmake
1157          DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PNG)
1158endif()
1159
1160# TODO: Create MSVC import lib for MinGW-compiled shared lib.
1161# pexports libpng.dll > libpng.def
1162# lib /def:libpng.def /machine:x86
1163