From 2a845ff819215e4f99a75136bd691ad0ffa9ae05 Mon Sep 17 00:00:00 2001 From: Cosmin Truta Date: Mon, 6 Jan 2025 17:09:10 +0200 Subject: [PATCH] build: Move portions from the main CMake file to separate modules In preparation for the upcoming changes in the build system, any parts of the CMake file that are unlikely to be affected should be moved out of the way. This should facilitate an easier resync between the branch 'libpng16' and its successor(s). Specifically: * Move the functions `generate_chk`, `generate_out`, `generate_source` and `generate_copy` to scripts/cmake/PNGGenConfig.cmake. * Move the function `png_add_test` to scripts/cmake/PNGTest.cmake. * Leave the function `create_symlink` in place, but add a TODO note. As we raised the minimum required CMake version to 3.14, we should now be able to use CMake's built-in function instead. --- CMakeLists.txt | 128 +++---------------------------- scripts/cmake/PNGGenConfig.cmake | 104 +++++++++++++++++++++++++ scripts/cmake/PNGTest.cmake | 42 ++++++++++ 3 files changed, 158 insertions(+), 116 deletions(-) create mode 100644 scripts/cmake/PNGGenConfig.cmake create mode 100644 scripts/cmake/PNGTest.cmake 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()