cmake: Correctly handle generated files

Generated files depend on other generated files, and this previously
resulted in the same custom command output being a dependency of
multiple other custom commands without a shared custom targets.

Adds a top-level target for each generated file and ensures that
commands that depend on generated files also depend on the corresponding
custom targets.

Per CMake documentation:

> Do not list the output in more than one independent target
> that may build in parallel or the two instances of the rule
> may conflict (instead use add_custom_target to drive the command
> and make the other targets depend on that one).

Signed-off-by: Cosmin Truta <ctruta@gmail.com>
This commit is contained in:
Gleb Mazovetskiy 2021-12-04 11:23:42 +00:00 committed by Cosmin Truta
parent 6a42bc1c8e
commit cbf8c64b58

View File

@ -16,6 +16,7 @@
# Revised by Steve Robinson, 2020
# Revised by Simon Hausmann, 2020
# Revised by Alex Gaynor, 2020
# Revised by Gleb Mazovetskiy, 2021
# This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer
@ -347,13 +348,18 @@ else()
endfunction()
# Copy file
function(generate_copy source destination)
add_custom_command(OUTPUT "${destination}"
# generate_copy(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
function(generate_copy)
set(options)
set(oneValueArgs INPUT OUTPUT)
set(multiValueArgs DEPENDS)
cmake_parse_arguments(_GCO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
add_custom_command(OUTPUT "${_GCO_OUTPUT}"
COMMAND "${CMAKE_COMMAND}"
-E remove "${destination}"
-E remove "${_GCO_OUTPUT}"
COMMAND "${CMAKE_COMMAND}"
-E copy "${source}" "${destination}"
DEPENDS "${source}")
-E copy "${_GCO_INPUT}" "${_GCO_OUTPUT}"
DEPENDS "${source}" ${_GCO_DEPENDS})
endfunction()
# Generate scripts/pnglibconf.h
@ -361,12 +367,14 @@ else()
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
add_custom_target(scripts_pnglibconf_c DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c")
# Generate pnglibconf.c
generate_source(OUTPUT "pnglibconf.c"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
add_custom_target(pnglibconf_c DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c")
if(PNG_PREFIX)
set(PNGLIBCONF_H_EXTRA_DEPENDS
@ -377,55 +385,67 @@ else()
endif()
generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
DEPENDS pnglibconf_c)
add_custom_target(pnglibconf_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
# Generate pnglibconf.h
generate_source(OUTPUT "pnglibconf.h"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out
${PNGLIBCONF_H_EXTRA_DEPENDS})
add_custom_target(pnglibconf_h DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h)
add_custom_target(scripts_intprefix_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out)
add_custom_target(scripts_prefix_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out")
# Generate pngprefix.h
generate_source(OUTPUT "pngprefix.h"
DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS})
add_custom_target(pngprefix_h DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h)
add_custom_target(scripts_sym_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt")
add_custom_target(scripts_symbols_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h)
add_custom_target(scripts_vers_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk"
DEPENDS scripts_symbols_out
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def")
add_custom_target(symbol-check
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk")
generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
"${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
"${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym"
DEPENDS scripts_sym_out)
generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
DEPENDS scripts_vers_out)
add_custom_target(genvers
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
@ -439,23 +459,20 @@ else()
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
# A single target handles generation of all generated files.
# If they are depended upon separately by multiple targets, this
# confuses parallel make (it would require a separate top-level
# target for each file to track the dependencies properly).
add_custom_target(genfiles
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym"
"${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
"${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym" gensym
"${CMAKE_CURRENT_BINARY_DIR}/libpng.vers" genvers
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" pnglibconf_c
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out
"${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h" pngprefix_h
"${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" scripts_intprefix_out
"${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c" scripts_pnglibconf_c
"${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" scripts_prefix_out
"${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" scripts_sym_out
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" symbol-check
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" scripts_symbols_out
"${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" scripts_vers_out)
endif(NOT AWK OR ANDROID OR IOS)
# List the source code files.