summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmComputeLinkInformation.cxx6
-rw-r--r--Source/cmGeneratorTarget.cxx13
-rw-r--r--Source/cmGeneratorTarget.h4
-rw-r--r--Source/cmTarget.cxx55
-rw-r--r--Source/cmTarget.h3
-rw-r--r--Source/cmTargetPropertyComputer.cxx4
6 files changed, 72 insertions, 13 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 28aa533..80e7e7d 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -606,6 +606,12 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
// of COMPATIBLE_INTERFACE_ enforcement. The generators will ignore
// this for the actual link line.
this->Items.push_back(Item(std::string(), false, tgt));
+
+ // Also add the item the interface specifies to be used in its place.
+ std::string const& libName = tgt->GetImportedLibName(config);
+ if (!libName.empty()) {
+ this->AddItem(libName, CM_NULLPTR);
+ }
} else {
// Decide whether to use an import library.
bool implib =
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index ca056c0..a18a9ef 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2796,6 +2796,16 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const
}
}
+std::string cmGeneratorTarget::GetImportedLibName(
+ std::string const& config) const
+{
+ if (cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config)) {
+ return info->LibName;
+ }
+ return std::string();
+}
+
std::string cmGeneratorTarget::GetFullPath(const std::string& config,
bool implib, bool realname) const
{
@@ -4711,6 +4721,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
}
}
if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ if (loc) {
+ info.LibName = loc;
+ }
return;
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 3805bfc..4c3c14b 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -147,6 +147,9 @@ public:
const cmGeneratorTarget* head,
bool usage_requirements_only) const;
+ /** Get the library name for an imported interface library. */
+ std::string GetImportedLibName(std::string const& config) const;
+
/** Get the full path to the target according to the settings in its
makefile and the configuration type. */
std::string GetFullPath(const std::string& config = "", bool implib = false,
@@ -643,6 +646,7 @@ private:
std::string Location;
std::string SOName;
std::string ImportLibrary;
+ std::string LibName;
std::string Languages;
std::string Libraries;
std::string LibrariesProp;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e37a9f8..434edf5 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -912,6 +912,9 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->SourceEntries.push_back(value);
this->Internal->SourceBacktraces.push_back(lfbt);
}
+ } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") &&
+ !this->CheckImportedLibName(prop, value ? value : "")) {
+ /* error was reported by check method */
} else {
this->Properties.SetProperty(prop, value);
}
@@ -979,6 +982,9 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->SourceEntries.push_back(value);
this->Internal->SourceBacktraces.push_back(lfbt);
+ } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ prop + " property may not be APPENDed.");
} else {
this->Properties.AppendProperty(prop, value, asString);
}
@@ -1374,20 +1380,41 @@ void cmTarget::SetPropertyDefault(const std::string& property,
}
}
+bool cmTarget::CheckImportedLibName(std::string const& prop,
+ std::string const& value) const
+{
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY ||
+ !this->IsImported()) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR, prop +
+ " property may be set only on imported INTERFACE library targets.");
+ return false;
+ }
+ if (!value.empty()) {
+ if (value[0] == '-') {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, prop +
+ " property value\n " + value +
+ "\nmay not start with '-'.");
+ return false;
+ }
+ std::string::size_type bad = value.find_first_of(":/\\;");
+ if (bad != value.npos) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR, prop + " property value\n " + value +
+ "\nmay not contain '" + value.substr(bad, 1) + "'.");
+ return false;
+ }
+ }
+ return true;
+}
+
bool cmTarget::GetMappedConfig(std::string const& desired_config,
const char** loc, const char** imp,
std::string& suffix) const
{
- if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
- // This method attempts to find a config-specific LOCATION for the
- // IMPORTED library. In the case of cmStateEnums::INTERFACE_LIBRARY, there
- // is no
- // LOCATION at all, so leaving *loc and *imp unchanged is the appropriate
- // and valid response.
- return true;
- }
-
- std::string const locPropBase = "IMPORTED_LOCATION";
+ std::string const locPropBase =
+ this->GetType() == cmStateEnums::INTERFACE_LIBRARY ? "IMPORTED_LIBNAME"
+ : "IMPORTED_LOCATION";
// Track the configuration-specific property suffix.
suffix = "_";
@@ -1445,7 +1472,9 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
// then the target location is not found. The project does not want
// any other configuration.
if (!mappedConfigs.empty() && !*loc && !*imp) {
- return false;
+ // Interface libraries are always available because their
+ // library name is optional so it is okay to leave *loc empty.
+ return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
}
// If we have not yet found it then there are no mapped
@@ -1499,7 +1528,9 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
}
// If we have not yet found it then the target location is not available.
if (!*loc && !*imp) {
- return false;
+ // Interface libraries are always available because their
+ // library name is optional so it is okay to leave *loc empty.
+ return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
}
return true;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 1f035a1..2f6aa12 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -277,6 +277,9 @@ private:
void SetPropertyDefault(const std::string& property,
const char* default_value);
+ bool CheckImportedLibName(std::string const& prop,
+ std::string const& value) const;
+
private:
cmPropertyMap Properties;
std::set<std::string> SystemIncludeDirectories;
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index 7cf1fd8..5ad1694 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -66,7 +66,9 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
return true;
}
- if (cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) {
+ if (prop == "IMPORTED_CONFIGURATIONS" || prop == "IMPORTED_LIBNAME" ||
+ cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME_") ||
+ cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) {
return true;
}