|
|
@@ -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;
|