diff --git a/CMakeLists.txt b/CMakeLists.txt index 603d917a1..75d25ec5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ # CMakeLists.txt - CMake lists for libpng # -# Copyright (c) 2018-2024 Cosmin Truta. -# Copyright (c) 2007-2018 Glenn Randers-Pehrson. -# Originally written by Christian Ehrlicher, 2007. +# Copyright (c) 2018-2025 Cosmin Truta +# Copyright (c) 2007-2018 Glenn Randers-Pehrson +# Originally written by Christian Ehrlicher, 2007 # # Use, modification and distribution are subject to # the same licensing terms and conditions as libpng. @@ -364,6 +364,9 @@ if(NOT AWK OR (ANDROID OR IOS)) ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h) add_custom_target(png_genfiles) else() + # Include the internal module PNGGenConfig.cmake + include(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGGenConfig.cmake) + # Copy the awk scripts, converting their line endings to Unix (LF) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk ${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk @@ -378,93 +381,6 @@ else() @ONLY NEWLINE_STYLE LF) - # Generate .chk from .out with awk: - # generate_chk(INPUT OUTPUT [DEPENDS ...]) - function(generate_chk) - set(options) - set(oneValueArgs INPUT OUTPUT) - set(multiValueArgs DEPENDS) - cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if(NOT _GC_INPUT) - message(FATAL_ERROR "generate_chk: Missing INPUT argument") - endif() - if(NOT _GC_OUTPUT) - message(FATAL_ERROR "generate_chk: Missing OUTPUT argument") - endif() - - add_custom_command(OUTPUT "${_GC_OUTPUT}" - COMMAND "${CMAKE_COMMAND}" - "-DINPUT=${_GC_INPUT}" - "-DOUTPUT=${_GC_OUTPUT}" - -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake" - DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS} - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - endfunction() - - # Generate .out from .c with awk: - # generate_out(INPUT OUTPUT [DEPENDS ...]) - function(generate_out) - set(options) - set(oneValueArgs INPUT OUTPUT) - set(multiValueArgs DEPENDS) - cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if(NOT _GO_INPUT) - message(FATAL_ERROR "generate_out: Missing INPUT argument") - endif() - if(NOT _GO_OUTPUT) - message(FATAL_ERROR "generate_out: Missing OUTPUT argument") - endif() - - add_custom_command(OUTPUT "${_GO_OUTPUT}" - COMMAND "${CMAKE_COMMAND}" - "-DINPUT=${_GO_INPUT}" - "-DOUTPUT=${_GO_OUTPUT}" - -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake" - DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS} - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - endfunction() - - # Generate specific source file with awk: - # generate_source(OUTPUT [DEPENDS ...]) - function(generate_source) - set(options) - set(oneValueArgs OUTPUT) - set(multiValueArgs DEPENDS) - cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if(NOT _GSO_OUTPUT) - message(FATAL_ERROR "generate_source: Missing OUTPUT argument") - endif() - - add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}" - COMMAND "${CMAKE_COMMAND}" - "-DOUTPUT=${_GSO_OUTPUT}" - -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake" - DEPENDS ${_GSO_DEPENDS} - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - endfunction() - - # Copy file: - # generate_copy(INPUT OUTPUT [DEPENDS ...]) - function(generate_copy) - set(options) - set(oneValueArgs INPUT OUTPUT) - set(multiValueArgs DEPENDS) - cmake_parse_arguments(_GCO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if(NOT _GCO_INPUT) - message(FATAL_ERROR "generate_copy: Missing INPUT argument") - endif() - if(NOT _GCO_OUTPUT) - message(FATAL_ERROR "generate_copy: Missing OUTPUT argument") - endif() - - add_custom_command(OUTPUT "${_GCO_OUTPUT}" - COMMAND "${CMAKE_COMMAND}" - -E remove "${_GCO_OUTPUT}" - COMMAND "${CMAKE_COMMAND}" - -E copy "${_GCO_INPUT}" "${_GCO_OUTPUT}" - DEPENDS "${source}" ${_GCO_DEPENDS}) - endfunction() - # Generate scripts/pnglibconf.h generate_source(OUTPUT "scripts/pnglibconf.c" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa" @@ -771,32 +687,8 @@ endif() if(PNG_TESTS AND PNG_SHARED) enable_testing() - # Add a custom target to run a test: - # png_add_test(NAME COMMAND [OPTIONS ...] [FILES ...]) - function(png_add_test) - set(options) - set(oneValueArgs NAME COMMAND) - set(multiValueArgs OPTIONS FILES) - cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if(NOT _PAT_NAME) - message(FATAL_ERROR "png_add_test: Missing NAME argument") - endif() - if(NOT _PAT_COMMAND) - message(FATAL_ERROR "png_add_test: Missing COMMAND argument") - endif() - - set(TEST_OPTIONS "${_PAT_OPTIONS}") - set(TEST_FILES "${_PAT_FILES}") - - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/test.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" - @ONLY) - add_test(NAME "${_PAT_NAME}" - COMMAND "${CMAKE_COMMAND}" - "-DLIBPNG=$" - "-DTEST_COMMAND=$" - -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake") - endfunction() + # Include the internal module PNGTest.cmake + include(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGTest.cmake) # Find test PNG files by globbing, but sort lists to ensure # consistency between different filesystems. @@ -980,6 +872,10 @@ endif() # or make a copy of the target file (if symlinking is not possible): # create_symlink( [FILE | TARGET ]) function(create_symlink DEST_FILE) + # TODO: + # Replace this implementation with CMake's built-in create_symlink function, + # which has been fully functional on all platforms, including Windows, since + # CMake version 3.13. cmake_parse_arguments(_SYM "" "FILE;TARGET" "" ${ARGN}) if(NOT _SYM_FILE AND NOT _SYM_TARGET) message(FATAL_ERROR "create_symlink: Missing FILE or TARGET argument") diff --git a/scripts/cmake/PNGGenConfig.cmake b/scripts/cmake/PNGGenConfig.cmake new file mode 100644 index 000000000..4a0030edd --- /dev/null +++ b/scripts/cmake/PNGGenConfig.cmake @@ -0,0 +1,104 @@ +# PNGGenConfig.cmake +# Utility functions for configuring and building libpng + +# Copyright (c) 2018-2025 Cosmin Truta +# Copyright (c) 2016-2018 Glenn Randers-Pehrson +# Written by Roger Leigh, 2016 +# +# Use, modification and distribution are subject to +# the same licensing terms and conditions as libpng. +# Please see the copyright notice in png.h or visit +# http://libpng.org/pub/png/src/libpng-LICENSE.txt +# +# SPDX-License-Identifier: libpng-2.0 + +# Generate .chk from .out with awk, based upon the automake logic: +# generate_chk(INPUT OUTPUT [DEPENDS ...]) +function(generate_chk) + set(options) + set(oneValueArgs INPUT OUTPUT) + set(multiValueArgs DEPENDS) + cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT _GC_INPUT) + message(FATAL_ERROR "generate_chk: Missing INPUT argument") + endif() + if(NOT _GC_OUTPUT) + message(FATAL_ERROR "generate_chk: Missing OUTPUT argument") + endif() + + # Run genchk.cmake to generate the .chk file. + add_custom_command(OUTPUT "${_GC_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + "-DINPUT=${_GC_INPUT}" + "-DOUTPUT=${_GC_OUTPUT}" + -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake" + DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") +endfunction() + +# Generate .out from C source file with awk: +# generate_out(INPUT OUTPUT [DEPENDS ...]) +function(generate_out) + set(options) + set(oneValueArgs INPUT OUTPUT) + set(multiValueArgs DEPENDS) + cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT _GO_INPUT) + message(FATAL_ERROR "generate_out: Missing INPUT argument") + endif() + if(NOT _GO_OUTPUT) + message(FATAL_ERROR "generate_out: Missing OUTPUT argument") + endif() + + # Run genout.cmake to generate the .out file. + add_custom_command(OUTPUT "${_GO_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + "-DINPUT=${_GO_INPUT}" + "-DOUTPUT=${_GO_OUTPUT}" + -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake" + DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") +endfunction() + +# Generate a source file with awk: +# generate_source(OUTPUT [DEPENDS ...]) +function(generate_source) + set(options) + set(oneValueArgs OUTPUT) + set(multiValueArgs DEPENDS) + cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT _GSO_OUTPUT) + message(FATAL_ERROR "generate_source: Missing OUTPUT argument") + endif() + + # Run gensrc.cmake to generate the source file. + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + "-DOUTPUT=${_GSO_OUTPUT}" + -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake" + DEPENDS ${_GSO_DEPENDS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") +endfunction() + +# Generate an identical file copy: +# generate_copy(INPUT OUTPUT [DEPENDS ...]) +function(generate_copy) + set(options) + set(oneValueArgs INPUT OUTPUT) + set(multiValueArgs DEPENDS) + cmake_parse_arguments(_GCO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT _GCO_INPUT) + message(FATAL_ERROR "generate_copy: Missing INPUT argument") + endif() + if(NOT _GCO_OUTPUT) + message(FATAL_ERROR "generate_copy: Missing OUTPUT argument") + endif() + + # Make a forced file copy, overwriting any pre-existing output file. + add_custom_command(OUTPUT "${_GCO_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + -E remove "${_GCO_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + -E copy "${_GCO_INPUT}" "${_GCO_OUTPUT}" + DEPENDS "${source}" ${_GCO_DEPENDS}) +endfunction() diff --git a/scripts/cmake/PNGTest.cmake b/scripts/cmake/PNGTest.cmake new file mode 100644 index 000000000..184773bc0 --- /dev/null +++ b/scripts/cmake/PNGTest.cmake @@ -0,0 +1,42 @@ +# PNGTest.cmake +# Utility functions for testing libpng + +# Copyright (c) 2018-2025 Cosmin Truta +# Copyright (c) 2016-2018 Glenn Randers-Pehrson +# Written by Roger Leigh, 2016 +# +# Use, modification and distribution are subject to +# the same licensing terms and conditions as libpng. +# Please see the copyright notice in png.h or visit +# http://libpng.org/pub/png/src/libpng-LICENSE.txt +# +# SPDX-License-Identifier: libpng-2.0 + +# Add a custom target to run a test: +# png_add_test(NAME COMMAND [OPTIONS ...] [FILES ...]) +function(png_add_test) + set(options) + set(oneValueArgs NAME COMMAND) + set(multiValueArgs OPTIONS FILES) + cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT _PAT_NAME) + message(FATAL_ERROR "png_add_test: Missing NAME argument") + endif() + if(NOT _PAT_COMMAND) + message(FATAL_ERROR "png_add_test: Missing COMMAND argument") + endif() + + # Initialize the global variables used by the "${_PAT_NAME}.cmake" script. + set(TEST_OPTIONS "${_PAT_OPTIONS}") + set(TEST_FILES "${_PAT_FILES}") + + # Generate and run the "${_PAT_NAME}.cmake" script. + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/test.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" + @ONLY) + add_test(NAME "${_PAT_NAME}" + COMMAND "${CMAKE_COMMAND}" + "-DLIBPNG=$" + "-DTEST_COMMAND=$" + -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake") +endfunction()