Skip to content

Commit

Permalink
cmake: Correctly handle generated files
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
glebm authored and ctruta committed Sep 10, 2022
1 parent 6a42bc1 commit cbf8c64
Showing 1 changed file with 49 additions and 32 deletions.
81 changes: 49 additions & 32 deletions CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -347,26 +348,33 @@ 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
generate_source(OUTPUT "scripts/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(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
Expand All @@ -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")
Expand All @@ -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.
Expand Down

0 comments on commit cbf8c64

Please sign in to comment.