cmPackageInfoReader: "Fix" handling of "includes"

Rewrite how cmPackageInfoReader parses "includes" to also support
language-specific includes (i.e. map-of-string-to-list-of-string).
Previously, we only supported the simpler list-of-string shorthand for
"includes" that do not have any language-specific includes.
This commit is contained in:
Matthew Woehlke
2024-12-18 15:55:03 -05:00
committed by Brad King
parent c44c5b07be
commit 5fb1726761
5 changed files with 91 additions and 6 deletions

View File

@@ -180,11 +180,10 @@ cm::string_view IterKey(Json::Value::const_iterator const& iter)
}
// Get list-of-strings value from object.
std::vector<std::string> ReadList(Json::Value const& data, char const* key)
std::vector<std::string> ReadList(Json::Value const& arr)
{
std::vector<std::string> result;
Json::Value const& arr = data[key];
if (arr.isArray()) {
for (Json::Value const& val : arr) {
if (val.isString()) {
@@ -196,6 +195,11 @@ std::vector<std::string> ReadList(Json::Value const& data, char const* key)
return result;
}
std::vector<std::string> ReadList(Json::Value const& data, char const* key)
{
return ReadList(data[key]);
}
std::string NormalizeTargetName(std::string const& name,
std::string const& context)
{
@@ -226,6 +230,47 @@ void AppendProperty(cmMakefile* makefile, cmTarget* target,
target->AppendProperty(fullprop, value, makefile->GetBacktrace());
}
template <typename Transform>
void AppendLanguageProperties(cmMakefile* makefile, cmTarget* target,
cm::string_view property,
cm::string_view configuration,
Json::Value const& data, char const* key,
Transform transform)
{
Json::Value const& value = data[key];
if (value.isArray()) {
for (std::string v : ReadList(value)) {
AppendProperty(makefile, target, property, configuration,
transform(std::move(v)));
}
} else if (value.isObject()) {
for (auto vi = value.begin(), ve = value.end(); vi != ve; ++vi) {
cm::string_view const originalLang = IterKey(vi);
cm::string_view const lang = MapLanguage(originalLang);
if (lang.empty()) {
makefile->IssueMessage(MessageType::WARNING,
cmStrCat("ignoring unknown language "_s,
originalLang, " in "_s, key, " for "_s,
target->GetName()));
continue;
}
if (lang == "*"_s) {
for (std::string v : ReadList(*vi)) {
AppendProperty(makefile, target, property, configuration,
transform(std::move(v)));
}
} else {
for (std::string v : ReadList(*vi)) {
v = cmStrCat("$<$<COMPILE_LANGUAGE:"_s, lang, ">:"_s,
transform(std::move(v)), '>');
AppendProperty(makefile, target, property, configuration, v);
}
}
}
}
}
void AddCompileFeature(cmMakefile* makefile, cmTarget* target,
cm::string_view configuration, std::string const& value)
{
@@ -483,10 +528,11 @@ void cmPackageInfoReader::SetTargetProperties(
AddDefinitions(makefile, target, configuration, definitionsMap);
// Add include directories.
for (std::string inc : ReadList(data, "includes")) {
AppendProperty(makefile, target, "INCLUDE_DIRECTORIES"_s, configuration,
this->ResolvePath(std::move(inc)));
}
AppendLanguageProperties(makefile, target, "INCLUDE_DIRECTORIES"_s,
configuration, data, "includes",
[this](std::string p) -> std::string {
return this->ResolvePath(std::move(p));
});
// Add link name/location(s).
this->SetOptionalProperty(target, "LOCATION"_s, configuration,

View File

@@ -137,3 +137,27 @@ else()
add_library(defs-test STATIC defs-test-c.c defs-test-cxx.cxx)
target_link_libraries(defs-test defs::defs)
endif()
###############################################################################
# Test importing of (language-specific) include paths.
include(CheckIncludeFile)
include(CheckIncludeFileCXX)
find_package(includes CONFIG REQUIRED)
set(CMAKE_REQUIRED_LIBRARIES includes::default)
check_include_file(cmincludetest/global.h C_GLOBAL_H)
check_include_file(cmincludetest/cxxonly.h C_CXXONLY_H)
check_include_file_cxx(cmincludetest/cxxonly.h CXX_CXXONLY_H)
set(CMAKE_REQUIRED_LIBRARIES)
if(NOT C_GLOBAL_H)
message(SEND_ERROR "cmincludetest/global.h not found !")
endif()
if(NOT CXX_CXXONLY_H)
message(SEND_ERROR "cmincludetest/cxxonly.h not found in C++ mode !")
endif()
if(C_CXXONLY_H)
message(SEND_ERROR "cmincludetest/cxxonly.h unexpectedly found in C mode ?!")
endif()

View File

@@ -0,0 +1,15 @@
{
"cps_version": "0.13",
"name": "includes",
"cps_path": "@prefix@/cps",
"components": {
"default": {
"type": "interface",
"includes": {
"bogus": [],
"cxx": ["@prefix@/include/cxx"],
"*": ["@prefix@/include"]
}
}
}
}