PrintHelpers: Fix target SOURCES property

It's been a long-standing bug in CMakePrintHelpers that the
cmake_print_properties() function cannot print the SOURCES
property of a requested TARGET, confusing it with a request
to print properties of SOURCES.

We work around this by parsing the arguments in two stages,
so that a SOURCES that comes after the PROPERTIES keyword
is handled differently from a SOURCES that comes before it.

This adds the restriction that the "mode" keyword (TARGETS
SOURCES DIRECTORIES etc...) and its arguments **must** precede
the PROPERTIES keyword and its arguments. In other words:

1. Both of these are now valid and will be interpreted correctly,
   whereas previously only the first was, and the second caused
   a FATAL_ERROR:

   cmake_print_properties(SOURCES foo.c PROPERTIES LANGUAGE)
   cmake_print_properties(TARGETS foo PROPERTIES SOURCES)

2. This, OTOH, which used to be valid, no longer is, and will
   trigger a FATAL_ERROR:

   cmake_print_properties(PROPERTIES LANGUAGE SOURCES foo.c)

Fixes: #14883
This commit is contained in:
FeRD (Frank Dana)
2022-06-06 12:25:51 -04:00
parent 2a56c24039
commit 2579503f45

View File

@@ -56,17 +56,34 @@ endfunction()
function(cmake_print_properties) function(cmake_print_properties)
set(options ) set(options )
set(oneValueArgs ) set(oneValueArgs )
set(multiValueArgs TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES ) set(cpp_multiValueArgs PROPERTIES )
set(cppmode_multiValueArgs TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES )
cmake_parse_arguments(CPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) string(JOIN " " _mode_names ${cppmode_multiValueArgs})
set(_missing_mode_message
"Mode keyword missing in cmake_print_properties() call, there must be exactly one of ${_mode_names}")
if(CPP_UNPARSED_ARGUMENTS) cmake_parse_arguments(
message(FATAL_ERROR "Unknown keywords given to cmake_print_properties(): \"${CPP_UNPARSED_ARGUMENTS}\"") CPP "${options}" "${oneValueArgs}" "${cpp_multiValueArgs}" ${ARGN})
if(NOT CPP_PROPERTIES)
message(FATAL_ERROR
"Required argument PROPERTIES missing in cmake_print_properties() call")
return() return()
endif() endif()
if(NOT CPP_PROPERTIES) if(NOT CPP_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Required argument PROPERTIES missing in cmake_print_properties() call") message(FATAL_ERROR "${_missing_mode_message}")
return()
endif()
cmake_parse_arguments(
CPPMODE "${options}" "${oneValueArgs}" "${cppmode_multiValueArgs}"
${CPP_UNPARSED_ARGUMENTS})
if(CPPMODE_UNPARSED_ARGUMENTS)
message(FATAL_ERROR
"Unknown keywords given to cmake_print_properties(): \"${CPPMODE_UNPARSED_ARGUMENTS}\"")
return() return()
endif() endif()
@@ -74,32 +91,32 @@ function(cmake_print_properties)
set(items) set(items)
set(keyword) set(keyword)
if(CPP_TARGETS) if(CPPMODE_TARGETS)
set(items ${CPP_TARGETS}) set(items ${CPPMODE_TARGETS})
set(mode ${mode} TARGETS) set(mode ${mode} TARGETS)
set(keyword TARGET) set(keyword TARGET)
endif() endif()
if(CPP_SOURCES) if(CPPMODE_SOURCES)
set(items ${CPP_SOURCES}) set(items ${CPPMODE_SOURCES})
set(mode ${mode} SOURCES) set(mode ${mode} SOURCES)
set(keyword SOURCE) set(keyword SOURCE)
endif() endif()
if(CPP_TESTS) if(CPPMODE_TESTS)
set(items ${CPP_TESTS}) set(items ${CPPMODE_TESTS})
set(mode ${mode} TESTS) set(mode ${mode} TESTS)
set(keyword TEST) set(keyword TEST)
endif() endif()
if(CPP_DIRECTORIES) if(CPPMODE_DIRECTORIES)
set(items ${CPP_DIRECTORIES}) set(items ${CPPMODE_DIRECTORIES})
set(mode ${mode} DIRECTORIES) set(mode ${mode} DIRECTORIES)
set(keyword DIRECTORY) set(keyword DIRECTORY)
endif() endif()
if(CPP_CACHE_ENTRIES) if(CPPMODE_CACHE_ENTRIES)
set(items ${CPP_CACHE_ENTRIES}) set(items ${CPPMODE_CACHE_ENTRIES})
set(mode ${mode} CACHE_ENTRIES) set(mode ${mode} CACHE_ENTRIES)
# This is a workaround for the fact that passing `CACHE` as an argument to # This is a workaround for the fact that passing `CACHE` as an argument to
# set() causes a cache variable to be set. # set() causes a cache variable to be set.