|
|
@@ -49,6 +49,25 @@ std::unordered_map<std::string, std::string> Languages = {
|
|
|
// clang-format on
|
|
|
};
|
|
|
|
|
|
+enum LanguageGlobOption
|
|
|
+{
|
|
|
+ DisallowGlob,
|
|
|
+ AllowGlob,
|
|
|
+};
|
|
|
+
|
|
|
+cm::string_view MapLanguage(cm::string_view lang,
|
|
|
+ LanguageGlobOption glob = AllowGlob)
|
|
|
+{
|
|
|
+ if (glob == AllowGlob && lang == "*"_s) {
|
|
|
+ return "*"_s;
|
|
|
+ }
|
|
|
+ auto const li = Languages.find(cmSystemTools::LowerCase(lang));
|
|
|
+ if (li != Languages.end()) {
|
|
|
+ return li->second;
|
|
|
+ }
|
|
|
+ return {};
|
|
|
+}
|
|
|
+
|
|
|
std::string GetRealPath(std::string const& path)
|
|
|
{
|
|
|
return cmSystemTools::GetRealPath(path);
|
|
|
@@ -244,6 +263,64 @@ void AddLinkFeature(cmMakefile* makefile, cmTarget* target,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+std::string BuildDefinition(std::string const& name, Json::Value const& value)
|
|
|
+{
|
|
|
+ if (!value.isNull() && value.isConvertibleTo(Json::stringValue)) {
|
|
|
+ return cmStrCat(name, '=', value.asString());
|
|
|
+ }
|
|
|
+ return name;
|
|
|
+}
|
|
|
+
|
|
|
+void AddDefinition(cmMakefile* makefile, cmTarget* target,
|
|
|
+ cm::string_view configuration,
|
|
|
+ std::string const& definition)
|
|
|
+{
|
|
|
+ AppendProperty(makefile, target, "COMPILE_DEFINITIONS"_s, configuration,
|
|
|
+ definition);
|
|
|
+}
|
|
|
+
|
|
|
+using DefinitionLanguageMap = std::map<cm::string_view, Json::Value>;
|
|
|
+using DefinitionsMap = std::map<std::string, DefinitionLanguageMap>;
|
|
|
+
|
|
|
+void AddDefinitions(cmMakefile* makefile, cmTarget* target,
|
|
|
+ cm::string_view configuration,
|
|
|
+ DefinitionsMap const& definitions)
|
|
|
+{
|
|
|
+ for (auto const& di : definitions) {
|
|
|
+ auto const& g = di.second.find("*"_s);
|
|
|
+ if (g != di.second.end()) {
|
|
|
+ std::string const& def = BuildDefinition(di.first, g->second);
|
|
|
+ if (di.second.size() == 1) {
|
|
|
+ // Only the non-language-specific definition exists.
|
|
|
+ AddDefinition(makefile, target, configuration, def);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create a genex to apply this definition to all languages except
|
|
|
+ // those that override it.
|
|
|
+ std::vector<cm::string_view> excludedLanguages;
|
|
|
+ for (auto const& li : di.second) {
|
|
|
+ if (li.first != "*"_s) {
|
|
|
+ excludedLanguages.emplace_back(li.first);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ AddDefinition(makefile, target, configuration,
|
|
|
+ cmStrCat("$<$<NOT:$<COMPILE_LANGUAGE:"_s,
|
|
|
+ cmJoin(excludedLanguages, ","_s), ">>:"_s, def,
|
|
|
+ '>'));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add language-specific definitions.
|
|
|
+ for (auto const& li : di.second) {
|
|
|
+ if (li.first != "*"_s) {
|
|
|
+ AddDefinition(makefile, target, configuration,
|
|
|
+ cmStrCat("$<$<COMPILE_LANGUAGE:"_s, li.first, ">:"_s,
|
|
|
+ BuildDefinition(di.first, li.second), '>'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
} // namespace
|
|
|
|
|
|
std::unique_ptr<cmPackageInfoReader> cmPackageInfoReader::Read(
|
|
|
@@ -386,10 +463,24 @@ void cmPackageInfoReader::SetTargetProperties(
|
|
|
}
|
|
|
|
|
|
// Add compile definitions.
|
|
|
- for (std::string const& def : ReadList(data, "definitions")) {
|
|
|
- AppendProperty(makefile, target, "COMPILE_DEFINITIONS"_s, configuration,
|
|
|
- def);
|
|
|
+ Json::Value const& defs = data["definitions"];
|
|
|
+ DefinitionsMap definitionsMap;
|
|
|
+ for (auto ldi = defs.begin(), lde = defs.end(); ldi != lde; ++ldi) {
|
|
|
+ cm::string_view const originalLang = IterKey(ldi);
|
|
|
+ cm::string_view const lang = MapLanguage(originalLang);
|
|
|
+ if (lang.empty()) {
|
|
|
+ makefile->IssueMessage(MessageType::WARNING,
|
|
|
+ cmStrCat("ignoring unknown language "_s,
|
|
|
+ originalLang, " in definitions for "_s,
|
|
|
+ target->GetName()));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (auto di = ldi->begin(), de = ldi->end(); di != de; ++di) {
|
|
|
+ definitionsMap[di.name()].emplace(lang, *di);
|
|
|
+ }
|
|
|
}
|
|
|
+ AddDefinitions(makefile, target, configuration, definitionsMap);
|
|
|
|
|
|
// Add include directories.
|
|
|
for (std::string inc : ReadList(data, "includes")) {
|
|
|
@@ -408,11 +499,11 @@ void cmPackageInfoReader::SetTargetProperties(
|
|
|
data["link_name"]);
|
|
|
|
|
|
// Add link languages.
|
|
|
- for (std::string const& lang : ReadList(data, "link_languages")) {
|
|
|
- auto const li = Languages.find(cmSystemTools::LowerCase(lang));
|
|
|
- if (li != Languages.end()) {
|
|
|
+ for (std::string const& originalLang : ReadList(data, "link_languages")) {
|
|
|
+ cm::string_view const lang = MapLanguage(originalLang, DisallowGlob);
|
|
|
+ if (!lang.empty()) {
|
|
|
AppendProperty(makefile, target, "LINK_LANGUAGES"_s, configuration,
|
|
|
- li->second);
|
|
|
+ std::string{ lang });
|
|
|
}
|
|
|
}
|
|
|
|