• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# CMakeLists.txt
2
3# Copyright (c) 2018-2019 Cosmin Truta
4# Copyright (c) 2007,2009-2018 Glenn Randers-Pehrson
5# Written by Christian Ehrlicher, 2007
6# Revised by Roger Lowman, 2009-2010
7# Revised by Clifford Yapp, 2011-2012,2017
8# Revised by Roger Leigh, 2016
9# Revised by Andreas Franek, 2016
10# Revised by Sam Serrels, 2017
11# Revised by Vadim Barkov, 2017
12# Revised by Vicky Pfau, 2018
13# Revised by Cameron Cawley, 2018
14# Revised by Cosmin Truta, 2018
15# Revised by Kyle Bentley, 2018
16
17# This code is released under the libpng license.
18# For conditions of distribution and use, see the disclaimer
19# and license in png.h
20
21cmake_minimum_required(VERSION 3.1)
22cmake_policy(VERSION 3.1)
23
24project(libpng C ASM)
25enable_testing()
26
27set(PNGLIB_MAJOR 1)
28set(PNGLIB_MINOR 6)
29set(PNGLIB_RELEASE 38)
30set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
31set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
32
33include(GNUInstallDirs)
34
35# needed packages
36
37# Allow users to specify location of Zlib.
38# Useful if zlib is being built alongside this as a sub-project.
39option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" OFF)
40
41if(NOT PNG_BUILD_ZLIB)
42  find_package(ZLIB REQUIRED)
43  include_directories(${ZLIB_INCLUDE_DIR})
44endif()
45
46if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
47  find_library(M_LIBRARY m)
48else()
49  # libm is not needed and/or not available
50  set(M_LIBRARY "")
51endif()
52
53# COMMAND LINE OPTIONS
54option(PNG_SHARED "Build shared lib" ON)
55option(PNG_STATIC "Build static lib" ON)
56option(PNG_TESTS  "Build libpng tests" ON)
57
58# Many more configuration options could be added here
59option(PNG_FRAMEWORK "Build OS X framework" OFF)
60option(PNG_DEBUG "Build with debug output" OFF)
61option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON)
62
63set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names")
64set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings")
65
66if(PNG_HARDWARE_OPTIMIZATIONS)
67
68# set definitions and sources for arm
69if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
70  CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
71  set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
72  set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations:
73     check: (default) use internal checking code;
74     off: disable the optimizations;
75     on: turn on unconditionally.")
76  set_property(CACHE PNG_ARM_NEON PROPERTY STRINGS
77     ${PNG_ARM_NEON_POSSIBLE_VALUES})
78  list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index)
79  if(index EQUAL -1)
80    message(FATAL_ERROR
81            "PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]")
82  elseif(NOT ${PNG_ARM_NEON} STREQUAL "off")
83    set(libpng_arm_sources
84      arm/arm_init.c
85      arm/filter_neon.S
86      arm/filter_neon_intrinsics.c
87      arm/palette_neon_intrinsics.c)
88
89    if(${PNG_ARM_NEON} STREQUAL "on")
90      add_definitions(-DPNG_ARM_NEON_OPT=2)
91    elseif(${PNG_ARM_NEON} STREQUAL "check")
92      add_definitions(-DPNG_ARM_NEON_CHECK_SUPPORTED)
93    endif()
94  else()
95    add_definitions(-DPNG_ARM_NEON_OPT=0)
96  endif()
97endif()
98
99# set definitions and sources for powerpc
100if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
101   CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
102  set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
103  set(PNG_POWERPC_VSX "on" CACHE STRING "Enable POWERPC VSX optimizations:
104     off: disable the optimizations.")
105  set_property(CACHE PNG_POWERPC_VSX PROPERTY STRINGS
106     ${PNG_POWERPC_VSX_POSSIBLE_VALUES})
107  list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index)
108  if(index EQUAL -1)
109    message(FATAL_ERROR
110            "PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]")
111  elseif(NOT ${PNG_POWERPC_VSX} STREQUAL "off")
112    set(libpng_powerpc_sources
113      powerpc/powerpc_init.c
114      powerpc/filter_vsx_intrinsics.c)
115    if(${PNG_POWERPC_VSX} STREQUAL "on")
116      add_definitions(-DPNG_POWERPC_VSX_OPT=2)
117    endif()
118  else()
119    add_definitions(-DPNG_POWERPC_VSX_OPT=0)
120  endif()
121endif()
122
123# set definitions and sources for intel
124if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
125   CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
126  set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
127  set(PNG_INTEL_SSE "on" CACHE STRING "Enable INTEL_SSE optimizations:
128     off: disable the optimizations")
129  set_property(CACHE PNG_INTEL_SSE PROPERTY STRINGS
130     ${PNG_INTEL_SSE_POSSIBLE_VALUES})
131  list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index)
132  if(index EQUAL -1)
133    message(FATAL_ERROR
134            "PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]")
135  elseif(NOT ${PNG_INTEL_SSE} STREQUAL "off")
136    set(libpng_intel_sources
137      intel/intel_init.c
138      intel/filter_sse2_intrinsics.c)
139    if(${PNG_INTEL_SSE} STREQUAL "on")
140      add_definitions(-DPNG_INTEL_SSE_OPT=1)
141    endif()
142  else()
143    add_definitions(-DPNG_INTEL_SSE_OPT=0)
144  endif()
145endif()
146
147# set definitions and sources for MIPS
148if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
149   CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
150  set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
151  set(PNG_MIPS_MSA "on" CACHE STRING "Enable MIPS_MSA optimizations:
152     off: disable the optimizations")
153  set_property(CACHE PNG_MIPS_MSA PROPERTY STRINGS
154     ${PNG_MIPS_MSA_POSSIBLE_VALUES})
155  list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index)
156  if(index EQUAL -1)
157    message(FATAL_ERROR
158            "PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]")
159  elseif(NOT ${PNG_MIPS_MSA} STREQUAL "off")
160    set(libpng_mips_sources
161      mips/mips_init.c
162      mips/filter_msa_intrinsics.c)
163    if(${PNG_MIPS_MSA} STREQUAL "on")
164      add_definitions(-DPNG_MIPS_MSA_OPT=2)
165    endif()
166  else()
167    add_definitions(-DPNG_MIPS_MSA_OPT=0)
168  endif()
169endif()
170
171else(PNG_HARDWARE_OPTIMIZATIONS)
172
173# set definitions and sources for arm
174if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
175   CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
176  add_definitions(-DPNG_ARM_NEON_OPT=0)
177endif()
178
179# set definitions and sources for powerpc
180if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
181   CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
182  add_definitions(-DPNG_POWERPC_VSX_OPT=0)
183endif()
184
185# set definitions and sources for intel
186if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
187   CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
188  add_definitions(-DPNG_INTEL_SSE_OPT=0)
189endif()
190
191# set definitions and sources for MIPS
192if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
193   CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
194  add_definitions(-DPNG_MIPS_MSA_OPT=0)
195endif()
196
197endif(PNG_HARDWARE_OPTIMIZATIONS)
198
199# SET LIBNAME
200set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
201
202# to distinguish between debug and release lib
203set(CMAKE_DEBUG_POSTFIX "d")
204
205include(CheckCSourceCompiles)
206option(ld-version-script "Enable linker version script" ON)
207if(ld-version-script AND NOT APPLE)
208  # Check if LD supports linker scripts.
209  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" "VERS_1 {
210        global: sym;
211        local: *;
212};
213
214VERS_2 {
215        global: sym2;
216                main;
217} VERS_1;
218")
219  set(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})
220  set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'")
221  check_c_source_compiles("void sym(void) {}
222void sym2(void) {}
223int main(void) {return 0;}
224" HAVE_LD_VERSION_SCRIPT)
225  if(NOT HAVE_LD_VERSION_SCRIPT)
226    set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE} "-Wl,-M -Wl,${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
227  check_c_source_compiles("void sym(void) {}
228void sym2(void) {}
229int main(void) {return 0;}
230" HAVE_SOLARIS_LD_VERSION_SCRIPT)
231  endif()
232  set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})
233  file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
234endif()
235
236# Find symbol prefix.  Likely obsolete and unnecessary with recent
237# toolchains (it's not done in many other projects).
238function(symbol_prefix)
239  set(SYMBOL_PREFIX)
240
241  execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E" "-"
242                  INPUT_FILE /dev/null
243                  OUTPUT_VARIABLE OUT
244                  RESULT_VARIABLE STATUS)
245
246  if(CPP_FAIL)
247    message(WARNING "Failed to run the C preprocessor")
248  endif()
249
250  string(REPLACE "\n" ";" OUT "${OUT}")
251  foreach(line ${OUT})
252    string(REGEX MATCH "^PREFIX=" found_match "${line}")
253    if(found_match)
254      string(REGEX REPLACE "^PREFIX=(.*\)" "\\1" prefix "${line}")
255      string(REGEX MATCH "__USER_LABEL_PREFIX__" found_match "${prefix}")
256      if(found_match)
257        string(REGEX REPLACE "(.*)__USER_LABEL_PREFIX__(.*)" "\\1\\2" prefix "${prefix}")
258      endif()
259      set(SYMBOL_PREFIX "${prefix}")
260    endif()
261  endforeach()
262
263  message(STATUS "Symbol prefix: ${SYMBOL_PREFIX}")
264  set(SYMBOL_PREFIX "${SYMBOL_PREFIX}" PARENT_SCOPE)
265endfunction()
266
267if(UNIX)
268  symbol_prefix()
269endif()
270
271find_program(AWK NAMES gawk awk)
272
273include_directories(${CMAKE_CURRENT_BINARY_DIR})
274
275if(NOT AWK OR ANDROID)
276  # No awk available to generate sources; use pre-built pnglibconf.h
277  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
278                 ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
279  add_custom_target(genfiles) # Dummy
280else()
281  include(CMakeParseArguments)
282  # Generate .chk from .out with awk
283  # generate_chk(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
284  function(generate_chk)
285    set(options)
286    set(oneValueArgs INPUT OUTPUT)
287    set(multiValueArgs DEPENDS)
288    cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
289    if(NOT _GC_INPUT)
290      message(FATAL_ERROR "generate_chk: Missing INPUT argument")
291    endif()
292    if(NOT _GC_OUTPUT)
293      message(FATAL_ERROR "generate_chk: Missing OUTPUT argument")
294    endif()
295
296    add_custom_command(OUTPUT "${_GC_OUTPUT}"
297                       COMMAND "${CMAKE_COMMAND}"
298                               "-DINPUT=${_GC_INPUT}"
299                               "-DOUTPUT=${_GC_OUTPUT}"
300                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake"
301                       DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS}
302                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
303  endfunction()
304
305  # Generate .out from .c with awk
306  # generate_out(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
307  function(generate_out)
308    set(options)
309    set(oneValueArgs INPUT OUTPUT)
310    set(multiValueArgs DEPENDS)
311    cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
312    if(NOT _GO_INPUT)
313      message(FATAL_ERROR "generate_out: Missing INPUT argument")
314    endif()
315    if(NOT _GO_OUTPUT)
316      message(FATAL_ERROR "generate_out: Missing OUTPUT argument")
317    endif()
318
319    add_custom_command(OUTPUT "${_GO_OUTPUT}"
320                       COMMAND "${CMAKE_COMMAND}"
321                               "-DINPUT=${_GO_INPUT}"
322                               "-DOUTPUT=${_GO_OUTPUT}"
323                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake"
324                       DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS}
325                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
326  endfunction()
327
328  # Generate specific source file with awk
329  # generate_source(OUTPUT outputfile [DEPENDS dep1 [dep2...]])
330  function(generate_source)
331    set(options)
332    set(oneValueArgs OUTPUT)
333    set(multiValueArgs DEPENDS)
334    cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
335    if(NOT _GSO_OUTPUT)
336      message(FATAL_ERROR "generate_source: Missing OUTPUT argument")
337    endif()
338
339    add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}"
340                       COMMAND "${CMAKE_COMMAND}"
341                               "-DOUTPUT=${_GSO_OUTPUT}"
342                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake"
343                       DEPENDS ${_GSO_DEPENDS}
344                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
345  endfunction()
346
347  # Copy file
348  function(generate_copy source destination)
349    add_custom_command(OUTPUT "${destination}"
350                       COMMAND "${CMAKE_COMMAND}" -E remove "${destination}"
351                       COMMAND "${CMAKE_COMMAND}" -E copy "${source}"
352                                                          "${destination}"
353                       DEPENDS "${source}")
354  endfunction()
355
356  # Generate scripts/pnglibconf.h
357  generate_source(OUTPUT "scripts/pnglibconf.c"
358                  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
359                          "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
360                          "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
361
362  # Generate pnglibconf.c
363  generate_source(OUTPUT "pnglibconf.c"
364                  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
365                          "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
366                          "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
367
368  if(PNG_PREFIX)
369    set(PNGLIBCONF_H_EXTRA_DEPENDS
370        "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
371        "${CMAKE_CURRENT_SOURCE_DIR}/scripts/macro.lst")
372    set(PNGPREFIX_H_EXTRA_DEPENDS
373        "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out")
374  endif()
375
376  generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
377               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
378
379  # Generate pnglibconf.h
380  generate_source(OUTPUT "pnglibconf.h"
381                  DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
382                          ${PNGLIBCONF_H_EXTRA_DEPENDS})
383
384  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c"
385               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
386               DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
387
388  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c"
389               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
390               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
391                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
392                       "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
393
394  # Generate pngprefix.h
395  generate_source(OUTPUT "pngprefix.h"
396                  DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS})
397
398  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c"
399               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
400               DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
401
402  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c"
403               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
404               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
405                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
406                       "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt")
407
408  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c"
409               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
410               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
411                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
412                       "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
413
414  generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
415               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
416               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk"
417                       "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def")
418
419  add_custom_target(symbol-check DEPENDS
420                    "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk")
421
422  generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
423                "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
424  generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
425                "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
426
427  add_custom_target(genvers DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
428  add_custom_target(gensym DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
429
430  add_custom_target("genprebuilt"
431                    COMMAND "${CMAKE_COMMAND}"
432                            "-DOUTPUT=scripts/pnglibconf.h.prebuilt"
433                            -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake"
434                    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
435
436  # A single target handles generation of all generated files.  If
437  # they are depended upon separately by multiple targets, this
438  # confuses parallel make (it would require a separate top-level
439  # target for each file to track the dependencies properly).
440  add_custom_target(genfiles DEPENDS
441    "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym"
442    "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
443    "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
444    "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
445    "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
446    "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h"
447    "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
448    "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c"
449    "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
450    "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
451    "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
452    "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
453    "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
454endif(NOT AWK OR ANDROID)
455
456# OUR SOURCES
457set(libpng_public_hdrs
458  png.h
459  pngconf.h
460  "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
461)
462set(libpng_private_hdrs
463  pngpriv.h
464  pngdebug.h
465  pnginfo.h
466  pngstruct.h
467)
468if(AWK AND NOT ANDROID)
469  list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
470endif()
471set(libpng_sources
472  ${libpng_public_hdrs}
473  ${libpng_private_hdrs}
474  png.c
475  pngerror.c
476  pngget.c
477  pngmem.c
478  pngpread.c
479  pngread.c
480  pngrio.c
481  pngrtran.c
482  pngrutil.c
483  pngset.c
484  pngtrans.c
485  pngwio.c
486  pngwrite.c
487  pngwtran.c
488  pngwutil.c
489  ${libpng_arm_sources}
490  ${libpng_intel_sources}
491  ${libpng_mips_sources}
492  ${libpng_powerpc_sources}
493)
494set(pngtest_sources
495  pngtest.c
496)
497set(pngvalid_sources
498  contrib/libtests/pngvalid.c
499)
500set(pngstest_sources
501  contrib/libtests/pngstest.c
502)
503set(pngunknown_sources
504  contrib/libtests/pngunknown.c
505)
506set(pngimage_sources
507  contrib/libtests/pngimage.c
508)
509set(pngfix_sources
510  contrib/tools/pngfix.c
511)
512set(png_fix_itxt_sources
513  contrib/tools/png-fix-itxt.c
514)
515
516if(MSVC)
517  add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
518endif()
519
520if(PNG_DEBUG)
521  add_definitions(-DPNG_DEBUG)
522endif()
523
524# NOW BUILD OUR TARGET
525include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIR})
526
527unset(PNG_LIB_TARGETS)
528
529if(PNG_SHARED)
530  add_library(png SHARED ${libpng_sources})
531  set(PNG_LIB_TARGETS png)
532  set_target_properties(png PROPERTIES OUTPUT_NAME ${PNG_LIB_NAME})
533  add_dependencies(png genfiles)
534  if(MSVC)
535    # msvc does not append 'lib' - do it here to have consistent name
536    set_target_properties(png PROPERTIES PREFIX "lib")
537    set_target_properties(png PROPERTIES IMPORT_PREFIX "lib")
538  endif()
539  target_link_libraries(png ${ZLIB_LIBRARY} ${M_LIBRARY})
540
541  if(UNIX AND AWK)
542    if(HAVE_LD_VERSION_SCRIPT)
543      set_target_properties(png PROPERTIES LINK_FLAGS
544        "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
545    elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT)
546      set_target_properties(png PROPERTIES LINK_FLAGS
547        "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
548    endif()
549  endif()
550endif()
551
552if(PNG_STATIC)
553  # does not work without changing name
554  set(PNG_LIB_NAME_STATIC png_static)
555  add_library(png_static STATIC ${libpng_sources})
556  add_dependencies(png_static genfiles)
557  # MSVC doesn't use a different file extension for shared vs. static
558  # libs.  We are able to change OUTPUT_NAME to remove the _static
559  # for all other platforms.
560  if(NOT MSVC)
561    set_target_properties(png_static PROPERTIES
562      OUTPUT_NAME "${PNG_LIB_NAME}"
563      CLEAN_DIRECT_OUTPUT 1)
564  else()
565    set_target_properties(png_static PROPERTIES
566      OUTPUT_NAME "${PNG_LIB_NAME}_static"
567      CLEAN_DIRECT_OUTPUT 1)
568  endif()
569  list(APPEND PNG_LIB_TARGETS png_static)
570  if(MSVC)
571    # msvc does not append 'lib' - do it here to have consistent name
572    set_target_properties(png_static PROPERTIES PREFIX "lib")
573  endif()
574  target_link_libraries(png_static ${ZLIB_LIBRARY} ${M_LIBRARY})
575endif()
576
577if(PNG_FRAMEWORK)
578  set(PNG_LIB_NAME_FRAMEWORK png_framework)
579  add_library(png_framework SHARED ${libpng_sources})
580  add_dependencies(png_framework genfiles)
581  list(APPEND PNG_LIB_TARGETS png_framework)
582  set_target_properties(png_framework PROPERTIES
583    FRAMEWORK TRUE
584    FRAMEWORK_VERSION ${PNGLIB_VERSION}
585    MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PNGLIB_MAJOR}.${PNGLIB_MINOR}
586    MACOSX_FRAMEWORK_BUNDLE_VERSION ${PNGLIB_VERSION}
587    MACOSX_FRAMEWORK_IDENTIFIER org.libpng.libpng
588    XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
589    PUBLIC_HEADER "${libpng_public_hdrs}"
590    OUTPUT_NAME png)
591  target_link_libraries(png_framework ${ZLIB_LIBRARY} ${M_LIBRARY})
592endif()
593
594if(NOT PNG_LIB_TARGETS)
595  message(SEND_ERROR
596    "No library variant selected to build. "
597    "Please enable at least one of the following options: "
598    "PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK")
599endif()
600
601if(PNG_SHARED AND WIN32)
602  set_target_properties(png PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
603endif()
604
605function(png_add_test)
606  set(options)
607  set(oneValueArgs NAME COMMAND)
608  set(multiValueArgs OPTIONS FILES)
609  cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
610
611  if(NOT _PAT_NAME)
612    message(FATAL_ERROR "png_add_test: Missing NAME argument")
613  endif()
614  if(NOT _PAT_COMMAND)
615    message(FATAL_ERROR "png_add_test: Missing COMMAND argument")
616  endif()
617
618  set(TEST_OPTIONS "${_PAT_OPTIONS}")
619  set(TEST_FILES "${_PAT_FILES}")
620
621  configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/test.cmake.in"
622                 "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" @ONLY)
623  add_test(NAME "${_PAT_NAME}"
624           COMMAND "${CMAKE_COMMAND}"
625           "-DLIBPNG=$<TARGET_FILE:png>"
626           "-DTEST_COMMAND=$<TARGET_FILE:${_PAT_COMMAND}>"
627           -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
628endfunction()
629
630if(PNG_TESTS AND PNG_SHARED)
631  # Find test PNG files by globbing, but sort lists to ensure
632  # consistency between different filesystems.
633  file(GLOB PNGSUITE_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/*.png")
634  list(SORT PNGSUITE_PNGS)
635  file(GLOB TEST_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/*.png")
636  list(SORT TEST_PNGS)
637
638  set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png")
639
640  add_executable(pngtest ${pngtest_sources})
641  target_link_libraries(pngtest png)
642
643  png_add_test(NAME pngtest COMMAND pngtest FILES "${PNGTEST_PNG}")
644
645  add_executable(pngvalid ${pngvalid_sources})
646  target_link_libraries(pngvalid png)
647
648  png_add_test(NAME pngvalid-gamma-16-to-8
649               COMMAND pngvalid OPTIONS --gamma-16-to-8)
650  png_add_test(NAME pngvalid-gamma-alpha-mode
651               COMMAND pngvalid OPTIONS --gamma-alpha-mode)
652  png_add_test(NAME pngvalid-gamma-background
653               COMMAND pngvalid OPTIONS --gamma-background)
654  png_add_test(NAME pngvalid-gamma-expand16-alpha-mode
655               COMMAND pngvalid OPTIONS --gamma-alpha-mode --expand16)
656  png_add_test(NAME pngvalid-gamma-expand16-background
657               COMMAND pngvalid OPTIONS --gamma-background --expand16)
658  png_add_test(NAME pngvalid-gamma-expand16-transform
659               COMMAND pngvalid OPTIONS --gamma-transform --expand16)
660  png_add_test(NAME pngvalid-gamma-sbit
661               COMMAND pngvalid OPTIONS --gamma-sbit)
662  png_add_test(NAME pngvalid-gamma-threshold
663               COMMAND pngvalid OPTIONS --gamma-threshold)
664  png_add_test(NAME pngvalid-gamma-transform
665               COMMAND pngvalid OPTIONS --gamma-transform)
666  png_add_test(NAME pngvalid-progressive-interlace-standard
667               COMMAND pngvalid OPTIONS --standard --progressive-read --interlace)
668  png_add_test(NAME pngvalid-progressive-size
669               COMMAND pngvalid OPTIONS --size --progressive-read)
670  png_add_test(NAME pngvalid-progressive-standard
671               COMMAND pngvalid OPTIONS --standard --progressive-read)
672  png_add_test(NAME pngvalid-standard
673               COMMAND pngvalid OPTIONS --standard)
674  png_add_test(NAME pngvalid-transform
675               COMMAND pngvalid OPTIONS --transform)
676
677  add_executable(pngstest ${pngstest_sources})
678  target_link_libraries(pngstest png)
679
680  foreach(gamma_type 1.8 linear none sRGB)
681    foreach(alpha_type none alpha)
682      set(PNGSTEST_FILES)
683      foreach(test_png ${TEST_PNGS})
684        string(REGEX MATCH ".*-linear[-.].*" TEST_PNG_LINEAR "${test_png}")
685        string(REGEX MATCH ".*-sRGB[-.].*" TEST_PNG_SRGB "${test_png}")
686        string(REGEX MATCH ".*-1.8[-.].*" TEST_PNG_G18 "${test_png}")
687        string(REGEX MATCH ".*-alpha-.*" TEST_PNG_ALPHA "${test_png}")
688
689        set(TEST_PNG_VALID TRUE)
690
691        if(TEST_PNG_ALPHA)
692          if(NOT "${alpha_type}" STREQUAL "alpha")
693            set(TEST_PNG_VALID FALSE)
694          endif()
695        else()
696          if("${alpha_type}" STREQUAL "alpha")
697            set(TEST_PNG_VALID FALSE)
698          endif()
699        endif()
700
701        if(TEST_PNG_LINEAR)
702          if(NOT "${gamma_type}" STREQUAL "linear")
703            set(TEST_PNG_VALID FALSE)
704          endif()
705        elseif(TEST_PNG_SRGB)
706          if(NOT "${gamma_type}" STREQUAL "sRGB")
707            set(TEST_PNG_VALID FALSE)
708          endif()
709        elseif(TEST_PNG_G18)
710          if(NOT "${gamma_type}" STREQUAL "1.8")
711            set(TEST_PNG_VALID FALSE)
712          endif()
713        else()
714          if(NOT "${gamma_type}" STREQUAL "none")
715            set(TEST_PNG_VALID FALSE)
716          endif()
717        endif()
718
719        if(TEST_PNG_VALID)
720          list(APPEND PNGSTEST_FILES "${test_png}")
721        endif()
722      endforeach()
723      # Should already be sorted, but sort anyway to be certain.
724      list(SORT PNGSTEST_FILES)
725      png_add_test(NAME pngstest-${gamma_type}-${alpha_type}
726                   COMMAND pngstest
727                   OPTIONS --tmpfile "${gamma_type}-${alpha_type}-" --log
728                   FILES ${PNGSTEST_FILES})
729    endforeach()
730  endforeach()
731
732  add_executable(pngunknown ${pngunknown_sources})
733  target_link_libraries(pngunknown png)
734
735  png_add_test(NAME pngunknown-discard COMMAND pngunknown OPTIONS --strict default=discard FILES "${PNGTEST_PNG}")
736  png_add_test(NAME pngunknown-IDAT COMMAND pngunknown OPTIONS --strict default=discard IDAT=save FILES "${PNGTEST_PNG}")
737  png_add_test(NAME pngunknown-if-safe COMMAND pngunknown OPTIONS --strict default=if-safe FILES "${PNGTEST_PNG}")
738  png_add_test(NAME pngunknown-sAPI COMMAND pngunknown OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save FILES "${PNGTEST_PNG}")
739  png_add_test(NAME pngunknown-save COMMAND pngunknown OPTIONS --strict default=save FILES "${PNGTEST_PNG}")
740  png_add_test(NAME pngunknown-sTER COMMAND pngunknown OPTIONS --strict sTER=if-safe FILES "${PNGTEST_PNG}")
741  png_add_test(NAME pngunknown-vpAg COMMAND pngunknown OPTIONS --strict vpAg=if-safe FILES "${PNGTEST_PNG}")
742
743  add_executable(pngimage ${pngimage_sources})
744  target_link_libraries(pngimage png)
745
746  png_add_test(NAME pngimage-quick COMMAND pngimage OPTIONS --list-combos --log FILES ${PNGSUITE_PNGS})
747  png_add_test(NAME pngimage-full COMMAND pngimage OPTIONS --exhaustive --list-combos --log FILES ${PNGSUITE_PNGS})
748endif()
749
750if(PNG_SHARED)
751  add_executable(pngfix ${pngfix_sources})
752  target_link_libraries(pngfix png)
753  set(PNG_BIN_TARGETS pngfix)
754
755  add_executable(png-fix-itxt ${png_fix_itxt_sources})
756  target_link_libraries(png-fix-itxt ${ZLIB_LIBRARY} ${M_LIBRARY})
757  list(APPEND PNG_BIN_TARGETS png-fix-itxt)
758endif()
759
760# Set a variable with CMake code which:
761# Creates a symlink from src to dest (if possible) or alternatively
762# copies if different.
763include(CMakeParseArguments)
764
765function(create_symlink DEST_FILE)
766
767  cmake_parse_arguments(S "" "FILE;TARGET" "" ${ARGN})
768
769  if(NOT S_TARGET AND NOT S_FILE)
770    message(FATAL_ERROR "create_symlink: Missing TARGET or FILE argument")
771  endif()
772
773  if(S_TARGET AND S_FILE)
774    message(FATAL_ERROR "create_symlink: Both source file ${S_FILE} and build target ${S_TARGET} arguments are present; can only have one.")
775  endif()
776
777  if(S_FILE)
778    # If we don't need to symlink something that's coming from a build target,
779    # we can go ahead and symlink/copy at configure time.
780    if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
781      execute_process(
782        COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${S_FILE} ${DEST_FILE}
783        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
784    else()
785      execute_process(
786        COMMAND ${CMAKE_COMMAND} -E create_symlink ${S_FILE} ${DEST_FILE}
787        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
788    endif()
789  endif()
790
791  if(S_TARGET)
792    # We need to use generator expressions, which can be a bit tricky, so for
793    # simplicity make the symlink a POST_BUILD step and use the TARGET
794    # signature of add_custom_command.
795    if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
796      add_custom_command(TARGET ${S_TARGET} POST_BUILD
797        COMMAND "${CMAKE_COMMAND}" -E copy_if_different $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE})
798    else()
799      add_custom_command(TARGET ${S_TARGET} POST_BUILD
800        COMMAND "${CMAKE_COMMAND}" -E create_symlink $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE})
801    endif()
802  endif()
803
804endfunction()
805
806# Create source generation scripts.
807configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in
808               ${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake @ONLY)
809configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genout.cmake.in
810               ${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake @ONLY)
811configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/gensrc.cmake.in
812               ${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake @ONLY)
813
814# libpng is a library so default to 'lib'
815if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
816  set(CMAKE_INSTALL_LIBDIR lib)
817endif()
818
819# CREATE PKGCONFIG FILES
820# We use the same files like ./configure, so we have to set its vars.
821# Only do this on Windows for Cygwin - the files don't make much sense outside
822# of a UNIX look-alike.
823if(NOT WIN32 OR CYGWIN OR MINGW)
824  set(prefix      ${CMAKE_INSTALL_PREFIX})
825  set(exec_prefix ${CMAKE_INSTALL_PREFIX})
826  set(libdir      ${CMAKE_INSTALL_FULL_LIBDIR})
827  set(includedir  ${CMAKE_INSTALL_FULL_INCLUDEDIR})
828  set(LIBS        "-lz -lm")
829  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
830    ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY)
831  create_symlink(libpng.pc FILE ${PNGLIB_NAME}.pc)
832
833  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in
834    ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)
835  create_symlink(libpng-config FILE ${PNGLIB_NAME}-config)
836endif()
837
838# SET UP LINKS
839if(PNG_SHARED)
840  set_target_properties(png PROPERTIES
841    VERSION 16.${PNGLIB_RELEASE}.git
842#   VERSION 16.${PNGLIB_RELEASE}.0
843    SOVERSION 16
844    CLEAN_DIRECT_OUTPUT 1)
845endif()
846
847# INSTALL
848if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
849  install(TARGETS ${PNG_LIB_TARGETS}
850          EXPORT libpng
851          RUNTIME DESTINATION bin
852          LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
853          ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
854          FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
855
856  if(PNG_SHARED)
857    # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
858    if(CYGWIN OR MINGW)
859      create_symlink(libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} TARGET png)
860      install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}
861              DESTINATION ${CMAKE_INSTALL_LIBDIR})
862    endif()
863
864    if(NOT WIN32)
865      create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png)
866      install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}
867              DESTINATION ${CMAKE_INSTALL_LIBDIR})
868    endif()
869  endif()
870
871  if(PNG_STATIC)
872    if(NOT WIN32 OR CYGWIN OR MINGW)
873      create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static)
874      install(FILES $<TARGET_LINKER_FILE_DIR:png_static>/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}
875              DESTINATION ${CMAKE_INSTALL_LIBDIR})
876    endif()
877  endif()
878endif()
879
880if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
881  install(FILES ${libpng_public_hdrs} DESTINATION include)
882  install(FILES ${libpng_public_hdrs} DESTINATION include/${PNGLIB_NAME})
883endif()
884if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL)
885  if(NOT WIN32 OR CYGWIN OR MINGW)
886    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin)
887    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config DESTINATION bin)
888  endif()
889endif()
890
891if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL)
892  install(TARGETS ${PNG_BIN_TARGETS}
893          RUNTIME DESTINATION bin)
894endif()
895
896if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL)
897  # Install man pages
898  if(NOT PNG_MAN_DIR)
899    set(PNG_MAN_DIR "share/man")
900  endif()
901  install(FILES libpng.3 libpngpf.3 DESTINATION ${PNG_MAN_DIR}/man3)
902  install(FILES png.5 DESTINATION ${PNG_MAN_DIR}/man5)
903  # Install pkg-config files
904  if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
905    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
906            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
907    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
908            DESTINATION bin)
909    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc
910            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
911    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
912            DESTINATION bin)
913  endif()
914endif()
915
916# Create an export file that CMake users can include() to import our targets.
917if(NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL)
918  install(EXPORT libpng DESTINATION lib/libpng FILE lib${PNG_LIB_NAME}.cmake)
919endif()
920
921# what's with libpng-manual.txt and all the extra files?
922
923# UNINSTALL
924# do we need this?
925
926# DIST
927# do we need this?
928
929# to create msvc import lib for mingw compiled shared lib
930# pexports libpng.dll > libpng.def
931# lib /def:libpng.def /machine:x86
932