Merge topic 'cps-import-file-sets'

cc94d43f52 CPS: Add release note for file set import/export
232f9473c7 CPS: Fix export version
9fb5f0fb5b CPS: Implement importing of file sets

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !12261
This commit is contained in:
Brad King
2026-07-14 13:18:04 +00:00
committed by Kitware Robot
7 changed files with 219 additions and 4 deletions

View File

@@ -0,0 +1,4 @@
cps-file-sets
-------------
* CPS import and export now supports header file sets.

View File

@@ -34,7 +34,7 @@
#include "cmTarget.h"
#include "cmTargetTypes.h"
static std::string const kCPS_VERSION_STR = "0.14.1";
static std::string const kCPS_VERSION_STR = "0.15.0";
cmExportPackageInfoGenerator::cmExportPackageInfoGenerator(
cmPackageInfoArguments arguments)

View File

@@ -20,6 +20,8 @@
#include "cmCxxModuleMetadata.h"
#include "cmExecutionStatus.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
@@ -131,7 +133,7 @@ bool CheckSchemaVersion(Json::Value const& data)
// Check that we understand this version.
return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL,
version, "0.13") &&
cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, version, "0.15");
cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, version, "0.16");
// TODO Eventually this probably needs to return the version tuple, and
// should share code with cmPackageInfoReader::ParseVersion.
@@ -228,6 +230,20 @@ std::vector<std::string> ReadList(Json::Value const& data, char const* key)
return ReadList(data[key]);
}
Json::Value GetExtensions(Json::Value const& data)
{
if (data.isObject()) {
Json::Value const& extensions = data["extensions"];
if (extensions.isObject()) {
Json::Value const& cmake = extensions["cmake"];
if (cmake.isObject()) {
return cmake;
}
}
}
return Json::Value{ Json::objectValue };
}
std::string NormalizeTargetName(std::string const& name,
std::string const& context)
{
@@ -869,9 +885,55 @@ cmTarget* cmPackageInfoReader::AddLibraryComponent(
this->SetTargetProperties(makefile, target, *ci, package, IterKey(ci));
}
// Add target sources.
this->AddTargetSources(makefile, target, data["file_sets"]);
return target;
}
void cmPackageInfoReader::AddTargetSources(cmMakefile* makefile,
cmTarget* target,
Json::Value const& data) const
{
if (data.isArray()) {
for (Json::Value const& fs : data) {
if (fs.isObject()) {
std::string const& type = ToString(fs["type"]);
std::string const& root = this->ResolvePath(ToString(fs["root"]));
std::vector<std::string> files = ReadList(fs["files"]);
if (files.empty() || root.empty() || type != "includes") {
continue;
}
Json::Value const& ext = GetExtensions(fs);
std::string const& name = [&] {
std::string const& extName = ToString(ext["name@v1"]);
if (!extName.empty()) {
return extName;
}
return std::string{ cm::FileSetMetadata::HEADERS };
}();
// TODO: When we support more than one file set type, check that we
// don't see the same 'name' on sets of different types.
auto fileSet = target->GetOrCreateFileSet(
name, std::string{ cm::FileSetMetadata::HEADERS },
cm::FileSetMetadata::Visibility::Interface);
cmListFileBacktrace const& bt = makefile->GetBacktrace();
for (std::string& file : files) {
file = cmStrCat(root, '/', file);
}
fileSet.first->AddFileEntry(
BT<std::string>{ cmList{ files }.to_string(), bt });
fileSet.first->AddDirectoryEntry(BT<std::string>{ root, bt });
}
}
}
}
bool cmPackageInfoReader::ImportTargets(cmMakefile* makefile,
cmExecutionStatus& status,
cm::ImportedTargetScope scope)

View File

@@ -99,6 +99,9 @@ private:
void AddTargetConfiguration(cmTarget* target,
cm::string_view configuration) const;
void AddTargetSources(cmMakefile* makefile, cmTarget* target,
Json::Value const& data) const;
void SetTargetProperties(cmMakefile* makefile, cmTarget* target,
Json::Value const& data, std::string const& package,
cm::string_view configuration) const;

View File

@@ -27,9 +27,9 @@ function(expect PACKAGE VAR OP VALUE WHAT)
endif()
endfunction()
function(expect_property TARGET PROPERTY DESCRIPTION EXPECTED)
function(expect_property TARGET PROPERTY DESCRIPTION)
get_target_property(actual ${TARGET} ${PROPERTY})
if(NOT "${actual}" STREQUAL "${EXPECTED}")
if(NOT "${actual}" STREQUAL "${ARGN}")
message(SEND_ERROR "${TARGET} has wrong ${DESCRIPTION} '${actual}' !")
endif()
endfunction()
@@ -375,3 +375,77 @@ else()
DefaultConfigurationsTest::Target2 IMPORTED_CONFIGURATIONS
"configurations" "TEST")
endif()
###############################################################################
# Test unnamed file sets.
find_package(FileSets-Anonymous)
if(NOT FileSets-Anonymous_FOUND)
message(SEND_ERROR "FileSets-Anonymous not found !")
elseif(NOT TARGET FileSets-Anonymous::Target)
message(SEND_ERROR "FileSets-Anonymous::Target missing !")
else()
expect_property(
FileSets-Anonymous::Target INTERFACE_HEADER_SETS
"include set names" "HEADERS")
expect_property(
FileSets-Anonymous::Target HEADER_DIRS
"include set roots"
"${CMAKE_SOURCE_DIR}/include"
"${CMAKE_SOURCE_DIR}/include")
expect_property(
FileSets-Anonymous::Target HEADER_DIRS_HEADERS
"include set 'HEADERS' roots"
"${CMAKE_SOURCE_DIR}/include"
"${CMAKE_SOURCE_DIR}/include")
expect_property(
FileSets-Anonymous::Target HEADER_SET
"include set files"
"${CMAKE_SOURCE_DIR}/include/header1.h"
"${CMAKE_SOURCE_DIR}/include/header2.h"
"${CMAKE_SOURCE_DIR}/include/header3.h")
expect_property(
FileSets-Anonymous::Target HEADER_SET_HEADERS
"include set 'HEADERS' files"
"${CMAKE_SOURCE_DIR}/include/header1.h"
"${CMAKE_SOURCE_DIR}/include/header2.h"
"${CMAKE_SOURCE_DIR}/include/header3.h")
endif()
###############################################################################
# Test named file sets.
find_package(FileSets-Named)
if(NOT FileSets-Named_FOUND)
message(SEND_ERROR "FileSets-Named not found !")
elseif(NOT TARGET FileSets-Named::Target)
message(SEND_ERROR "FileSets-Named::Target missing !")
else()
expect_property(
FileSets-Named::Target INTERFACE_HEADER_SETS
"include set names" "foo;bar")
expect_property(
FileSets-Named::Target HEADER_DIRS_foo
"include set roots"
"${CMAKE_SOURCE_DIR}/include/a"
"${CMAKE_SOURCE_DIR}/include/b")
expect_property(
FileSets-Named::Target HEADER_DIRS_foo
"include set 'foo' roots"
"${CMAKE_SOURCE_DIR}/include/a"
"${CMAKE_SOURCE_DIR}/include/b")
expect_property(
FileSets-Named::Target HEADER_DIRS_bar
"include set 'bar' roots"
"${CMAKE_SOURCE_DIR}/include")
expect_property(
FileSets-Named::Target HEADER_SET_foo
"include set 'foo' files"
"${CMAKE_SOURCE_DIR}/include/a/foo1.h"
"${CMAKE_SOURCE_DIR}/include/a/foo2.h"
"${CMAKE_SOURCE_DIR}/include/b/foo3.h")
expect_property(
FileSets-Named::Target HEADER_SET_bar
"include set 'bar' files"
"${CMAKE_SOURCE_DIR}/include/bar.h")
endif()

View File

@@ -0,0 +1,23 @@
{
"cps_version": "0.15.0",
"name": "FileSets-Anonymous",
"cps_path": "@prefix@/cps",
"components": {
"Target": {
"file_sets":
[
{
"type": "includes",
"root": "@prefix@/include",
"files": [ "header1.h", "header2.h" ]
},
{
"type": "includes",
"root": "@prefix@/include",
"files": [ "header3.h" ]
}
],
"type": "interface"
}
}
}

View File

@@ -0,0 +1,49 @@
{
"cps_version": "0.15.0",
"name": "FileSets-Named",
"cps_path": "@prefix@/cps",
"components": {
"Target": {
"file_sets":
[
{
"extensions":
{
"cmake":
{
"name@v1": "foo"
}
},
"type": "includes",
"root": "@prefix@/include/a",
"files": [ "foo1.h", "foo2.h" ]
},
{
"extensions":
{
"cmake":
{
"name@v1": "foo"
}
},
"type": "includes",
"root": "@prefix@/include/b",
"files": [ "foo3.h" ]
},
{
"extensions":
{
"cmake":
{
"name@v1": "bar"
}
},
"type": "includes",
"root": "@prefix@/include",
"files": [ "bar.h" ]
}
],
"type": "interface"
}
}
}