diff options
author | Brad King <brad.king@kitware.com> | 2016-11-09 14:49:49 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2016-11-09 14:49:49 (GMT) |
commit | 453df662bafe52ec87e0972323cf87ec737f3437 (patch) | |
tree | cf5326c1c63bfee5079353699bcc09d982e4fe66 /Source | |
parent | 25085f41b20f7f5a5fb25e8ab683f77476f917a2 (diff) | |
parent | 09cda9d5e7bb31f05177bdaf11d24aeaf85a8dd3 (diff) | |
download | CMake-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.cxx | 6 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 13 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 4 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 71 | ||||
-rw-r--r-- | Source/cmTarget.h | 3 | ||||
-rw-r--r-- | Source/cmTargetPropertyComputer.cxx | 4 |
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; } |