diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx index 5fccb44c2b..63b4038c3a 100644 --- a/Source/cmPackageInfoReader.cxx +++ b/Source/cmPackageInfoReader.cxx @@ -180,11 +180,10 @@ cm::string_view IterKey(Json::Value::const_iterator const& iter) } // Get list-of-strings value from object. -std::vector ReadList(Json::Value const& data, char const* key) +std::vector ReadList(Json::Value const& arr) { std::vector 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 ReadList(Json::Value const& data, char const* key) return result; } +std::vector 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 +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("$<$:"_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, diff --git a/Tests/FindPackageCpsTest/CMakeLists.txt b/Tests/FindPackageCpsTest/CMakeLists.txt index e612610281..8b5a68e900 100644 --- a/Tests/FindPackageCpsTest/CMakeLists.txt +++ b/Tests/FindPackageCpsTest/CMakeLists.txt @@ -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() diff --git a/Tests/FindPackageCpsTest/cps/includes.cps b/Tests/FindPackageCpsTest/cps/includes.cps new file mode 100644 index 0000000000..ea6b080d3f --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/includes.cps @@ -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"] + } + } + } +} diff --git a/Tests/FindPackageCpsTest/include/cmincludetest/global.h b/Tests/FindPackageCpsTest/include/cmincludetest/global.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/FindPackageCpsTest/include/cxx/cmincludetest/cxxonly.h b/Tests/FindPackageCpsTest/include/cxx/cmincludetest/cxxonly.h new file mode 100644 index 0000000000..e69de29bb2