Add target properties to discover target's file set information

Currently, target properties related to file sets are specific to file set
type (for example "SOURCE_SETS"). This raises some concerns:
1. For each new file set type, 6 new properties are created which need a lot
   off documentation update
2. there is no "generic" way to discover file sets information

The new target properties (FILE_SET_TYPES, FILE_SETS_<TYPE>,
and INTERFACE_FILE_SETS_<TYPE>), in conjunction with the file sets
properties, enable a complete generic file sets information discovery.
This commit is contained in:
Marc Chevrier
2026-06-30 16:03:32 +02:00
parent ab78260559
commit 08855d03c2
13 changed files with 198 additions and 21 deletions
+3
View File
@@ -227,6 +227,8 @@ Properties on Targets
/prop_tgt/EXPORT_PROPERTIES
/prop_tgt/FASTBUILD_CACHING
/prop_tgt/FASTBUILD_DISTRIBUTION
/prop_tgt/FILE_SET_TYPES
/prop_tgt/FILE_SETS_TYPE
/prop_tgt/FOLDER
/prop_tgt/Fortran_BUILDING_INTRINSIC_MODULES
/prop_tgt/Fortran_FORMAT
@@ -295,6 +297,7 @@ Properties on Targets
/prop_tgt/INTERFACE_COMPILE_FEATURES
/prop_tgt/INTERFACE_COMPILE_OPTIONS
/prop_tgt/INTERFACE_CXX_MODULE_SETS
/prop_tgt/INTERFACE_FILE_SETS_TYPE
/prop_tgt/INTERFACE_HEADER_SETS
/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY
/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
+13 -4
View File
@@ -7,8 +7,17 @@ Read-only list of the target's ``PRIVATE`` and ``PUBLIC`` C++ module sets (i.e.
all file sets with the type ``CXX_MODULES``). Files listed in these file sets
are treated as source files for the purpose of IDE integration.
C++ module sets may be defined using the :command:`target_sources` command
``FILE_SET`` option with type ``CXX_MODULES``.
See Also
^^^^^^^^
See also :prop_tgt:`CXX_MODULE_SET_<NAME>`, :prop_tgt:`CXX_MODULE_SET` and
:prop_tgt:`INTERFACE_CXX_MODULE_SETS`.
Related properties:
* :prop_tgt:`FILE_SETS_<TYPE>`
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>`
* :prop_tgt:`INTERFACE_CXX_MODULE_SETS`
* :prop_tgt:`CXX_MODULE_SET_<NAME>`
* :prop_tgt:`CXX_MODULE_SET`
Related commands:
* :command:`target_sources` to define file sets of type ``CXX_MODULES``
+25
View File
@@ -0,0 +1,25 @@
FILE_SETS_<TYPE>
----------------
.. versionadded:: 4.5
Read-only list of the target's ``PRIVATE`` and ``PUBLIC`` file sets of type
``<TYPE>``.
See Also
^^^^^^^^
Related properties:
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>` to list the target's ``INTERFACE`` file sets
* :prop_tgt:`FILE_SET_TYPES` to list the target's file set types
* :prop_tgt:`HEADER_SETS` to list the target's ``PRIVATE`` file sets of type
``HEADER``
* :prop_tgt:`SOURCE_SETS` to list the target's ``PRIVATE`` file sets of type
``SOURCE``
* :prop_tgt:`CXX_MODULE_SETS` to list the target's ``PRIVATE`` file sets of
type ``CXX_MODULES``
Related commands:
* :command:`target_sources` to define file sets
+16
View File
@@ -0,0 +1,16 @@
FILE_SET_TYPES
--------------
.. versionadded:: 4.5
Read-only list of the target's file set types.
See Also
^^^^^^^^
Related properties:
* :prop_tgt:`FILE_SETS_<TYPE>` to list ``PRIVATE`` and ``PUBLIC`` file sets of
type ``<TYPE>``.
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>` to list ``INTERFACE`` and ``PUBLIC``
file sets of type ``<TYPE>``.
+13 -4
View File
@@ -8,8 +8,17 @@ all file sets with the type ``HEADERS``). Files listed in these file sets are
treated as source files for the purpose of IDE integration. The files also
have their :prop_sf:`HEADER_FILE_ONLY` property set to ``TRUE``.
Header sets may be defined using the :command:`target_sources` command
``FILE_SET`` option with type ``HEADERS``.
See Also
^^^^^^^^
See also :prop_tgt:`HEADER_SET_<NAME>`, :prop_tgt:`HEADER_SET` and
:prop_tgt:`INTERFACE_HEADER_SETS`.
Related properties:
* :prop_tgt:`FILE_SETS_<TYPE>`
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>`
* :prop_tgt:`INTERFACE_HEADER_SETS`
* :prop_tgt:`HEADER_SET_<NAME>`
* :prop_tgt:`HEADER_SET`
Related commands:
* :command:`target_sources` to define file sets of type ``HEADERS``
+11 -3
View File
@@ -8,7 +8,15 @@ with the type ``CXX_MODULES``). Files listed in these C++ module sets can be
installed with :command:`install(TARGETS)` and exported with
:command:`install(EXPORT)` and :command:`export`.
C++ module sets may be defined using the :command:`target_sources` command
``FILE_SET`` option with type ``CXX_MODULES``.
See Also
^^^^^^^^
See also :prop_tgt:`CXX_MODULE_SETS`.
Related properties:
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>`
* :prop_tgt:`FILE_SETS_<TYPE>`
* :prop_tgt:`CXX_MODULE_SETS`
Related commands:
* :command:`target_sources` to define file sets of type ``CXX_MODULES``
@@ -0,0 +1,25 @@
INTERFACE_FILE_SETS_<TYPE>
--------------------------
.. versionadded:: 4.5
Read-only list of the target's ``INTERFACE`` and ``PUBLIC`` file sets of type
``<TYPE>``.
See Also
^^^^^^^^
Related properties:
* :prop_tgt:`FILE_SETS_<TYPE>` to list the target's ``PRIVATE`` file sets
* :prop_tgt:`FILE_SET_TYPES` to list the target's file set types
* :prop_tgt:`INTERFACE_HEADER_SETS` to list the target's ``INTERFACE`` file
sets of type ``HEADER``
* :prop_tgt:`INTERFACE_SOURCE_SETS` to list the target's ``INTERFACE`` file
sets of type ``SOURCE``
* :prop_tgt:`INTERFACE_CXX_MODULE_SETS` to list the target's ``INTERFACE`` file
sets of type ``CXX_MODULES``
Related commands:
* :command:`target_sources` to define file sets
+11 -3
View File
@@ -8,7 +8,15 @@ all file sets with the type ``HEADERS``). Files listed in these header sets
can be installed with :command:`install(TARGETS)` and exported with
:command:`install(EXPORT)` and :command:`export`.
Header sets may be defined using the :command:`target_sources` command
``FILE_SET`` option with type ``HEADERS``.
See Also
^^^^^^^^
See also :prop_tgt:`HEADER_SETS`.
Related properties:
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>`
* :prop_tgt:`FILE_SETS_<TYPE>`
* :prop_tgt:`HEADER_SETS`
Related commands:
* :command:`target_sources` to define file sets of type ``HEADERS``
+11 -3
View File
@@ -8,7 +8,15 @@ all file sets with the type ``SOURCES``). Files listed in these source sets
can be installed with :command:`install(TARGETS)` and exported with
:command:`install(EXPORT)` and :command:`export`.
Source sets may be defined using the :command:`target_sources` command
``FILE_SET`` option with type ``SOURCES``.
See Also
^^^^^^^^
See also :prop_tgt:`SOURCE_SETS`.
Related properties:
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>`
* :prop_tgt:`FILE_SETS_<TYPE>`
* :prop_tgt:`SOURCE_SETS`
Related commands:
* :command:`target_sources` to define file sets of type ``SOURCES``
+13 -4
View File
@@ -7,8 +7,17 @@ Read-only list of the target's ``PRIVATE`` and ``PUBLIC`` source sets (i.e.
all file sets with the type ``SOURCES``). Files listed in these file sets are
treated as source files.
Source sets may be defined using the :command:`target_sources` command
``FILE_SET`` option with type ``SOURCES``.
See Also
^^^^^^^^
See also :prop_tgt:`SOURCE_SET_<NAME>`, :prop_tgt:`SOURCE_SET` and
:prop_tgt:`INTERFACE_SOURCE_SETS`.
Related properties:
* :prop_tgt:`FILE_SETS_<TYPE>`
* :prop_tgt:`INTERFACE_FILE_SETS_<TYPE>`
* :prop_tgt:`INTERFACE_SOURCE_SETS`
* :prop_tgt:`SOURCE_SET_<NAME>`
* :prop_tgt:`SOURCE_SET`
Related commands:
* :command:`target_sources` to define file sets of type ``SOURCES``
@@ -0,0 +1,6 @@
target-FILE_SET-properties
--------------------------
* The :prop_tgt:`FILE_SET_TYPES`, :prop_tgt:`FILE_SETS_<TYPE>`, and
:prop_tgt:`INTERFACE_FILE_SETS_<TYPE>` target properties were added to get
information about file sets attached to the target.
+33
View File
@@ -41,6 +41,7 @@
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTargetPropertyComputer.h"
#include "cmValue.h"
@@ -2114,6 +2115,7 @@ bool IsSettableProperty(cmMakefile* context, cmTarget* target,
using ROC = ReadOnlyCondition;
static std::unordered_map<std::string, ReadOnlyProperty> const readOnlyProps{
{ "EXPORT_NAME", { ROC::Imported } },
{ "FILE_SET_TYPES", { ROC::All } },
{ "HEADER_SETS", { ROC::All } },
{ "IMPORTED_GLOBAL", { ROC::NonImported } },
{ "INTERFACE_HEADER_SETS", { ROC::All } },
@@ -2181,6 +2183,11 @@ void cmTarget::SetProperty(std::string const& prop, cmValue value)
}
}
if (cmHasPrefix(prop, "FILE_SETS_"_s) ||
cmHasPrefix(prop, "INTERFACE_FILE_SETS_"_s)) {
// these properties are always read-only
return;
}
for (auto& fileSetType : this->impl->FileSetTypes) {
if (fileSetType.second.WriteProperties(this, this->impl.get(), prop, value,
FileSetType::Action::Set)) {
@@ -2773,6 +2780,32 @@ cmValue cmTarget::GetProperty(std::string const& prop) const
}
// Check fileset properties.
if (prop == "FILE_SET_TYPES"_s) {
static std::string fsTypes;
cmList types;
for (auto const& fileSetType : this->impl->FileSetTypes) {
if (!fileSetType.second.SelfEntries.Entries.empty() ||
!fileSetType.second.InterfaceEntries.Entries.empty()) {
types.push_back(fileSetType.first);
}
}
std::sort(types.begin(), types.end());
fsTypes = types.to_string();
return cmValue{ fsTypes };
}
if (cmHasPrefix(prop, "FILE_SETS_"_s)) {
static std::string fileSets;
std::string type = prop.substr(10);
fileSets = cmList::to_string(this->GetFileSetsEntries(type));
return cmValue{ fileSets };
}
if (cmHasPrefix(prop, "INTERFACE_FILE_SETS_"_s)) {
static std::string fileSets;
std::string type = prop.substr(20);
fileSets = cmList::to_string(this->GetInterfaceFileSetsEntries(type));
return cmValue{ fileSets };
}
{
for (auto const& fileSetType : this->impl->FileSetTypes) {
auto value =
@@ -21,10 +21,14 @@ assert_prop_eq(lib1 HEADER_SETS "")
assert_prop_eq(lib1 INTERFACE_HEADER_SETS "")
assert_prop_undef(lib1 INCLUDE_DIRECTORIES)
assert_prop_undef(lib1 INTERFACE_INCLUDE_DIRECTORIES)
assert_prop_eq(lib1 FILE_SET_TYPES "")
target_sources(lib1 PUBLIC FILE_SET a TYPE HEADERS BASE_DIRS "." FILES h1.h h2.h)
assert_prop_eq(lib1 HEADER_SETS "a")
assert_prop_eq(lib1 INTERFACE_HEADER_SETS "a")
assert_prop_eq(lib1 FILE_SET_TYPES "HEADERS")
assert_prop_eq(lib1 FILE_SETS_HEADERS "a")
assert_prop_eq(lib1 INTERFACE_FILE_SETS_HEADERS "a")
assert_prop_eq(lib1 HEADER_DIRS_a "${CMAKE_CURRENT_SOURCE_DIR}/.")
assert_prop_eq(lib1 HEADER_SET_a "${CMAKE_CURRENT_SOURCE_DIR}/h1.h;${CMAKE_CURRENT_SOURCE_DIR}/h2.h")
assert_prop_eq(lib1 INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.>")
@@ -41,6 +45,9 @@ assert_prop_eq(lib1 INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CUR
target_sources(lib1 PRIVATE FILE_SET b TYPE HEADERS BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/dir" FILES dir/dir.h)
assert_prop_eq(lib1 HEADER_SETS "a;b")
assert_prop_eq(lib1 INTERFACE_HEADER_SETS "a")
assert_prop_eq(lib1 FILE_SET_TYPES "HEADERS")
assert_prop_eq(lib1 FILE_SETS_HEADERS "a;b")
assert_prop_eq(lib1 INTERFACE_FILE_SETS_HEADERS "a")
assert_prop_eq(lib1 HEADER_DIRS_b "${CMAKE_CURRENT_SOURCE_DIR}/dir")
assert_prop_eq(lib1 HEADER_SET_b "${CMAKE_CURRENT_SOURCE_DIR}/dir/dir.h")
assert_prop_eq(lib1 INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>")
@@ -49,6 +56,8 @@ assert_prop_eq(lib1 INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CUR
target_sources(lib1 INTERFACE FILE_SET c TYPE HEADERS FILE_SET d TYPE HEADERS)
assert_prop_eq(lib1 HEADER_SETS "a;b")
assert_prop_eq(lib1 INTERFACE_HEADER_SETS "a;c;d")
assert_prop_eq(lib1 FILE_SETS_HEADERS "a;b")
assert_prop_eq(lib1 INTERFACE_FILE_SETS_HEADERS "a;c;d")
assert_prop_eq(lib1 HEADER_DIRS_c "${CMAKE_CURRENT_SOURCE_DIR}")
assert_prop_eq(lib1 HEADER_SET_c "")
assert_prop_eq(lib1 HEADER_DIRS_d "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -58,6 +67,8 @@ assert_prop_eq(lib1 INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CUR
target_sources(lib1 PUBLIC FILE_SET HEADERS BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" FILES h4.h)
assert_prop_eq(lib1 INTERFACE_HEADER_SETS "a;c;d;HEADERS")
assert_prop_eq(lib1 FILE_SETS_HEADERS "a;b;HEADERS")
assert_prop_eq(lib1 INTERFACE_FILE_SETS_HEADERS "a;c;d;HEADERS")
assert_prop_eq(lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
assert_prop_eq(lib1 HEADER_SET "${CMAKE_CURRENT_SOURCE_DIR}/h4.h")
assert_prop_eq(lib1 HEADER_DIRS_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -73,3 +84,10 @@ assert_prop_eq(lib1 HEADER_DIRS_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}")
assert_prop_eq(lib1 HEADER_SET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/h4.h;${CMAKE_CURRENT_SOURCE_DIR}/h5.h")
assert_prop_eq(lib1 INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
assert_prop_eq(lib1 INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
target_sources(lib1 PUBLIC FILE_SET src1 TYPE SOURCES FILES lib1.c)
assert_prop_eq(lib1 FILE_SET_TYPES "HEADERS;SOURCES")
assert_prop_eq(lib1 FILE_SETS_HEADERS "a;b;HEADERS")
assert_prop_eq(lib1 INTERFACE_FILE_SETS_HEADERS "a;c;d;HEADERS")
assert_prop_eq(lib1 FILE_SETS_SOURCES "src1")
assert_prop_eq(lib1 INTERFACE_FILE_SETS_SOURCES "src1")