summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2022-03-03 18:07:10 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2022-03-03 19:31:54 (GMT)
commit8c23ecbd93eb86f7316cdeb2cdc561d28ee95de7 (patch)
tree30bfdd7c329ef4226629c32ad6deca399cc51994
parent04a7200c7561509a83c34f2af45b2d091ae59248 (diff)
downloadCMake-8c23ecbd93eb86f7316cdeb2cdc561d28ee95de7.zip
CMake-8c23ecbd93eb86f7316cdeb2cdc561d28ee95de7.tar.gz
CMake-8c23ecbd93eb86f7316cdeb2cdc561d28ee95de7.tar.bz2
target_sources(): Process multiple FILE_SET arguments per block
Fixes: #23287
-rw-r--r--Help/command/target_sources.rst5
-rw-r--r--Source/cmTargetSourcesCommand.cxx33
-rw-r--r--Tests/RunCMake/target_sources/FileSetProperties.cmake14
3 files changed, 40 insertions, 12 deletions
diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst
index e482117..234f5be 100644
--- a/Help/command/target_sources.rst
+++ b/Help/command/target_sources.rst
@@ -68,8 +68,9 @@ File Sets
.. code-block:: cmake
target_sources(<target>
- <INTERFACE|PUBLIC|PRIVATE> FILE_SET set1 [TYPE type1] [BASE_DIRS dirs1...] [FILES files1...]
- [<INTERFACE|PUBLIC|PRIVATE> FILE_SET set2 [TYPE type2] [BASE_DIRS dirs2...] [FILES files2...])
+ [<INTERFACE|PUBLIC|PRIVATE>
+ [FILE_SET <set> [TYPE <type>] [BASE_DIRS <dirs>...] [FILES <files>...]]...
+ ]...)
Adds a file set to a target, or adds files to an existing file set. Targets
have zero or more named file sets. Each file set has a name, a type, a scope of
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index b425acb..17af789 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -38,6 +38,14 @@ auto const FileSetArgsParser = cmArgumentParser<FileSetArgs>()
.Bind("BASE_DIRS"_s, &FileSetArgs::BaseDirs)
.Bind("FILES"_s, &FileSetArgs::Files);
+struct FileSetsArgs
+{
+ std::vector<std::vector<std::string>> FileSets;
+};
+
+auto const FileSetsArgsParser =
+ cmArgumentParser<FileSetsArgs>().Bind("FILE_SET"_s, &FileSetsArgs::FileSets);
+
class TargetSourcesImpl : public cmTargetPropCommandBase
{
public:
@@ -79,7 +87,7 @@ private:
bool prepend, bool system) override
{
if (!content.empty() && content.front() == "FILE_SET"_s) {
- return this->HandleFileSetMode(scope, content, prepend, system);
+ return this->HandleFileSetMode(scope, content);
}
return this->cmTargetPropCommandBase::PopulateTargetProperties(
scope, content, prepend, system);
@@ -105,8 +113,9 @@ private:
IsInterface isInterfaceContent, CheckCMP0076 checkCmp0076);
bool HandleFileSetMode(const std::string& scope,
- const std::vector<std::string>& content, bool prepend,
- bool system);
+ const std::vector<std::string>& content);
+ bool HandleOneFileSet(const std::string& scope,
+ const std::vector<std::string>& content);
};
std::vector<std::string> TargetSourcesImpl::ConvertToAbsoluteContent(
@@ -186,8 +195,22 @@ std::vector<std::string> TargetSourcesImpl::ConvertToAbsoluteContent(
}
bool TargetSourcesImpl::HandleFileSetMode(
- const std::string& scope, const std::vector<std::string>& content,
- bool /*prepend*/, bool /*system*/)
+ const std::string& scope, const std::vector<std::string>& content)
+{
+ auto args = FileSetsArgsParser.Parse(content);
+
+ for (auto& argList : args.FileSets) {
+ argList.emplace(argList.begin(), "FILE_SET"_s);
+ if (!this->HandleOneFileSet(scope, argList)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TargetSourcesImpl::HandleOneFileSet(
+ const std::string& scope, const std::vector<std::string>& content)
{
std::vector<std::string> unparsed;
auto args = FileSetArgsParser.Parse(content, &unparsed);
diff --git a/Tests/RunCMake/target_sources/FileSetProperties.cmake b/Tests/RunCMake/target_sources/FileSetProperties.cmake
index ce010a3..a671ab3 100644
--- a/Tests/RunCMake/target_sources/FileSetProperties.cmake
+++ b/Tests/RunCMake/target_sources/FileSetProperties.cmake
@@ -46,22 +46,26 @@ 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>")
assert_prop_eq(lib1 INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.>")
-target_sources(lib1 INTERFACE FILE_SET c TYPE HEADERS)
+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")
+assert_prop_eq(lib1 INTERFACE_HEADER_SETS "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}")
+assert_prop_eq(lib1 HEADER_SET_d "")
assert_prop_eq(lib1 INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>")
-assert_prop_eq(lib1 INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_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}>")
target_sources(lib1 PUBLIC FILE_SET HEADERS BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" FILES h1.h)
+assert_prop_eq(lib1 INTERFACE_HEADER_SETS "a;c;d;HEADERS")
assert_prop_eq(lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
assert_prop_eq(lib1 HEADER_SET "${CMAKE_CURRENT_SOURCE_DIR}/h1.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}>")
+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 HEADERS FILES h2.h)
+assert_prop_eq(lib1 INTERFACE_HEADER_SETS "a;c;d;HEADERS")
assert_prop_eq(lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
assert_prop_eq(lib1 HEADER_SET "${CMAKE_CURRENT_SOURCE_DIR}/h1.h;${CMAKE_CURRENT_SOURCE_DIR}/h2.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}>")
+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}>")