summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-11-09 14:49:49 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2016-11-09 14:49:49 (GMT)
commit453df662bafe52ec87e0972323cf87ec737f3437 (patch)
treecf5326c1c63bfee5079353699bcc09d982e4fe66 /Source
parent25085f41b20f7f5a5fb25e8ab683f77476f917a2 (diff)
parent09cda9d5e7bb31f05177bdaf11d24aeaf85a8dd3 (diff)
downloadCMake-453df662bafe52ec87e0972323cf87ec737f3437.zip
CMake-453df662bafe52ec87e0972323cf87ec737f3437.tar.gz
CMake-453df662bafe52ec87e0972323cf87ec737f3437.tar.bz2
Merge topic 'imported-interface-libname'
09cda9d5 Allow imported INTERFACE libraries to specify a link library name 1d1f1eeb cmTarget: Refactor GetMappedConfig to choose location property up front 479932fa cmTarget: Add comment clarifying interface library special case 925e4270 cmTarget: Clarify comments in GetMappedConfig
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.cxx71
-rw-r--r--Source/cmTarget.h3
-rw-r--r--Source/cmTargetPropertyComputer.cxx4
6 files changed, 82 insertions, 19 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 1a454ac..903bcec 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2798,6 +2798,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
{
@@ -4713,6 +4723,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 dabdda5..54bdfe6 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -291,6 +291,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
ci != configNames.end(); ++ci) {
std::string configUpper = cmSystemTools::UpperCase(*ci);
for (const char** p = configProps; *p; ++p) {
+ // Interface libraries have no output locations, so honor only
+ // the configuration map.
if (this->TargetTypeValue == cmStateEnums::INTERFACE_LIBRARY &&
strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0) {
continue;
@@ -912,6 +914,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 +984,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,18 +1382,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 =
+ this->GetType() == cmStateEnums::INTERFACE_LIBRARY ? "IMPORTED_LIBNAME"
+ : "IMPORTED_LOCATION";
// Track the configuration-specific property suffix.
suffix = "_";
@@ -1412,7 +1443,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
if (mci->empty()) {
// An empty string in the mapping has a special meaning:
// look up the config-less properties.
- *loc = this->GetProperty("IMPORTED_LOCATION");
+ *loc = this->GetProperty(locPropBase);
if (allowImp) {
*imp = this->GetProperty("IMPORTED_IMPLIB");
}
@@ -1422,7 +1453,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
}
} else {
std::string mcUpper = cmSystemTools::UpperCase(*mci);
- std::string locProp = "IMPORTED_LOCATION_";
+ std::string locProp = locPropBase + "_";
locProp += mcUpper;
*loc = this->GetProperty(locProp);
if (allowImp) {
@@ -1440,16 +1471,18 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
}
// If we needed to find one of the mapped configurations but did not
- // then the target is not found. The project does not want any
- // other configuration.
+ // 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
// configurations. Look for an exact-match.
if (!*loc && !*imp) {
- std::string locProp = "IMPORTED_LOCATION";
+ std::string locProp = locPropBase;
locProp += suffix;
*loc = this->GetProperty(locProp);
if (allowImp) {
@@ -1467,7 +1500,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
// Look for a configuration-less location. This may be set by
// manually-written code.
- *loc = this->GetProperty("IMPORTED_LOCATION");
+ *loc = this->GetProperty(locPropBase);
if (allowImp) {
*imp = this->GetProperty("IMPORTED_IMPLIB");
}
@@ -1485,7 +1518,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
!*loc && !*imp && aci != availableConfigs.end(); ++aci) {
suffix = "_";
suffix += cmSystemTools::UpperCase(*aci);
- std::string locProp = "IMPORTED_LOCATION";
+ std::string locProp = locPropBase;
locProp += suffix;
*loc = this->GetProperty(locProp);
if (allowImp) {
@@ -1495,9 +1528,11 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
}
}
}
- // If we have not yet found it then the target is not available.
+ // 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 57ef8d2..1d40d20 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -278,6 +278,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 04931af..3a9bddb 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -65,7 +65,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;
}