CPS: Support compile_requires / $<COMPILE_ONLY>

Add support for importing and exporting compile-only requirements
to/from CPS. This also means that we now support and export CPS 0.14.
This commit is contained in:
Matthew Woehlke authored and Brad King committed 2026-01-07 14:56:16 -05:00
1 parent 19b0750434
commit f65e55c9bc
11 files changed
+85 -8

No files matched your search

+10 -5
View File
@@ -30,7 +30,7 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
static std::string const kCPS_VERSION_STR = "0.13.0";
static std::string const kCPS_VERSION_STR = "0.14.0";
cmExportPackageInfoGenerator::cmExportPackageInfoGenerator(
cmPackageInfoArguments arguments)
@@ -397,8 +397,10 @@ void cmExportPackageInfoGenerator::GenerateInterfaceLinkProperties(
// Extract any $<LINK_ONLY:...> from the link libraries, and assert that no
// other generator expressions are present.
std::map<std::string, std::vector<std::string>> allowList = { { "LINK_ONLY",
{} } };
std::map<std::string, std::vector<std::string>> allowList = {
{ "COMPILE_ONLY", {} },
{ "LINK_ONLY", {} },
};
std::string interfaceLinkLibraries;
if (!cmGeneratorExpression::ForbidGeneratorExpressions(
target, iter->first, iter->second, interfaceLinkLibraries,
@@ -407,9 +409,10 @@ void cmExportPackageInfoGenerator::GenerateInterfaceLinkProperties(
return;
}
std::vector<std::string> linkLibraries;
std::vector<std::string> linkRequires;
std::vector<std::string> buildRequires;
std::vector<std::string> compileRequires;
std::vector<std::string> linkRequires;
std::vector<std::string> linkLibraries;
auto addLibraries = [this, &linkLibraries,
&result](std::vector<std::string> const& names,
@@ -428,12 +431,14 @@ void cmExportPackageInfoGenerator::GenerateInterfaceLinkProperties(
}
};
addLibraries(allowList["COMPILE_ONLY"], compileRequires);
addLibraries(allowList["LINK_ONLY"], linkRequires);
addLibraries(cmList{ interfaceLinkLibraries }, buildRequires);
BuildArray(component, "requires", buildRequires);
BuildArray(component, "link_requires", linkRequires);
BuildArray(component, "link_libraries", linkLibraries);
BuildArray(component, "compile_requires", compileRequires);
}
void cmExportPackageInfoGenerator::GenerateInterfaceCompileFeatures(
+7 -1
View File
@@ -129,7 +129,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.14");
cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, version, "0.15");
// TODO Eventually this probably needs to return the version tuple, and
// should share code with cmPackageInfoReader::ParseVersion.
@@ -768,6 +768,12 @@ void cmPackageInfoReader::SetTargetProperties(
NormalizeTargetName(dep, package));
}
for (std::string const& dep : ReadList(data, "compile_requires")) {
std::string const& lib =
cmStrCat("$<COMPILE_ONLY:"_s, NormalizeTargetName(dep, package), '>');
AppendProperty(makefile, target, "LINK_LIBRARIES"_s, configuration, lib);
}
for (std::string const& dep : ReadList(data, "link_requires")) {
std::string const& lib =
cmStrCat("$<LINK_ONLY:"_s, NormalizeTargetName(dep, package), '>');
+4 -1
View File
@@ -217,9 +217,12 @@ endif()
find_package(RequiresTest CONFIG REQUIRED)
add_library(requires-test STATIC requires-test.cxx)
add_executable(requires-test requires-test.cxx)
target_link_libraries(requires-test RequiresTest::Indirect)
add_executable(requires-test-compile_only requires-test.cxx)
target_link_libraries(requires-test-compile_only RequiresTest::CompileOnly)
###############################################################################
# Test importing of (language-specific) include paths.
+14 -1
View File
@@ -1,5 +1,5 @@
{
"cps_version": "0.13",
"cps_version": "0.14.0",
"name": "RequiresTest",
"cps_path": "@prefix@/cps",
"components": {
@@ -14,6 +14,19 @@
"ANSWER": 42
}
}
},
"CompileOnly": {
"type": "interface",
"compile_requires": [ ":BrokenLibrary" ]
},
"BrokenLibrary": {
"type": "archive",
"location": "@prefix@/lib/does-not-exist.a",
"definitions": {
"*": {
"ANSWER": 42
}
}
}
}
}
@@ -5,3 +5,8 @@
# error ANSWER has the wrong value
# endif
#endif
int main()
{
return 0;
}
@@ -0,0 +1,12 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/CompileOnly-build")
file(READ "${out_dir}/bar.cps" content)
string(JSON component GET "${content}" "components" "bar")
expect_array("${component}" 2 "compile_requires")
expect_value("${component}" "foo:linkOnlyOne" "compile_requires" 0)
expect_value("${component}" "foo:linkOnlyTwo" "compile_requires" 1)
expect_array("${component}" 1 "requires")
expect_value("${component}" "foo:foo" "requires" 0)
expect_missing("${component}" "foo:foo" "link_libraries")
@@ -0,0 +1,13 @@
project(LinkOnly CXX)
add_library(linkOnlyOne foo.cxx)
add_library(linkOnlyTwo foo.cxx)
add_library(foo foo.cxx)
add_library(bar foo.cxx)
target_link_libraries(bar $<COMPILE_ONLY:linkOnlyOne> $<COMPILE_ONLY:linkOnlyTwo> foo)
install(TARGETS foo linkOnlyOne linkOnlyTwo EXPORT foo)
export(EXPORT foo PACKAGE_INFO foo)
install(TARGETS bar EXPORT bar)
export(EXPORT bar PACKAGE_INFO bar)
@@ -0,0 +1 @@
1
@@ -0,0 +1,6 @@
CMake Error in CMakeLists\.txt:
\$<COMPILE_ONLY:\.\.\.> expression in "INTERFACE_LINK_LIBRARIES" of target
"bar" contains a generator expression\. This is not allowed\.
CMake Generate step failed\. Build files cannot be regenerated correctly\.
@@ -0,0 +1,11 @@
project(LinkOnly CXX)
add_library(foo foo.cxx)
add_library(bar foo.cxx)
target_link_libraries(bar $<COMPILE_ONLY:$<COMPILE_ONLY:foo>>)
install(TARGETS foo EXPORT foo)
export(EXPORT foo PACKAGE_INFO foo)
install(TARGETS bar EXPORT bar)
export(EXPORT bar PACKAGE_INFO bar)
@@ -32,6 +32,7 @@ run_cmake(ReferencesWronglyNamespacedTarget)
run_cmake(DependsMultipleDifferentNamespace)
run_cmake(DependsMultipleDifferentSets)
run_cmake(LinkInterfaceGeneratorExpression)
run_cmake(CompileOnlyRecursive)
run_cmake(LinkOnlyRecursive)
# Test functionality
@@ -47,6 +48,7 @@ run_cmake(Requirements)
run_cmake(ExportSymbolicComponent)
run_cmake(TargetTypes)
run_cmake(DependsMultiple)
run_cmake(CompileOnly)
run_cmake(LinkOnly)
run_cmake(Config)
run_cmake(EmptyConfig)