diff options
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 63bfbc6..0cb299c 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4978,6 +4978,16 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, } } + // Get information if target is managed assembly. + { + std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME"; + if (auto pc = this->GetProperty(linkProp + suffix)) { + info.Managed = this->CheckManagedType(pc); + } else if (auto p = this->GetProperty(linkProp)) { + info.Managed = this->CheckManagedType(p); + } + } + // Get the cyclic repetition count. if (this->GetType() == cmStateEnums::STATIC_LIBRARY) { std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; @@ -5195,6 +5205,18 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages, } } +bool cmGeneratorTarget::HasLanguage(std::string const& language, + std::string const& config, + bool exclusive) const +{ + std::set<std::string> languages; + this->GetLanguages(languages, config); + // add linker language (if it is different from compiler languages) + languages.insert(this->GetLinkerLanguage(config)); + return (languages.size() == 1 || !exclusive) && + languages.count(language) > 0; +} + void cmGeneratorTarget::ComputeLinkImplementationLanguages( const std::string& config, cmOptionalLinkImplementation& impl) const { @@ -5381,16 +5403,17 @@ std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const return ""; } -bool cmGeneratorTarget::HasImplibGNUtoMS() const +bool cmGeneratorTarget::HasImplibGNUtoMS(std::string const& config) const { - return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS"); + return this->HasImportLibrary(config) && this->GetPropertyAsBool("GNUtoMS"); } -bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& gnuName, +bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& config, + std::string const& gnuName, std::string& out, const char* newExt) const { - if (this->HasImplibGNUtoMS() && gnuName.size() > 6 && + if (this->HasImplibGNUtoMS(config) && gnuName.size() > 6 && gnuName.substr(gnuName.size() - 6) == ".dll.a") { out = gnuName.substr(0, gnuName.size() - 6); out += newExt ? newExt : ".lib"; @@ -5405,11 +5428,14 @@ bool cmGeneratorTarget::IsExecutableWithExports() const this->GetPropertyAsBool("ENABLE_EXPORTS")); } -bool cmGeneratorTarget::HasImportLibrary() const +bool cmGeneratorTarget::HasImportLibrary(std::string const& config) const { return (this->IsDLLPlatform() && (this->GetType() == cmStateEnums::SHARED_LIBRARY || - this->IsExecutableWithExports())); + this->IsExecutableWithExports()) && + // Assemblies which have only managed code do not have + // import libraries. + this->GetManagedType(config) != ManagedType::Managed); } std::string cmGeneratorTarget::GetSupportDirectory() const @@ -5462,3 +5488,49 @@ bool cmGeneratorTarget::IsCFBundleOnApple() const return (this->GetType() == cmStateEnums::MODULE_LIBRARY && this->Makefile->IsOn("APPLE") && this->GetPropertyAsBool("BUNDLE")); } + +cmGeneratorTarget::ManagedType cmGeneratorTarget::CheckManagedType( + std::string const& propval) const +{ + // The type of the managed assembly (mixed unmanaged C++ and C++/CLI, + // or only C++/CLI) does only depend on whether the property is an empty + // string or contains any value at all. In Visual Studio generators + // this propval is prepended with /clr[:] which results in: + // + // 1. propval does not exist: no /clr flag, unmanaged target, has import + // lib + // 2. empty propval: add /clr as flag, mixed unmanaged/managed + // target, has import lib + // 3. any value (safe,pure): add /clr:[propval] as flag, target with + // managed code only, no import lib + return propval.empty() ? ManagedType::Mixed : ManagedType::Managed; +} + +cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType( + const std::string& config) const +{ + // Only libraries and executables can be managed targets. + if (this->GetType() != cmStateEnums::SHARED_LIBRARY && + this->GetType() != cmStateEnums::STATIC_LIBRARY && + this->GetType() != cmStateEnums::EXECUTABLE) { + return ManagedType::Undefined; + } + + // Check imported target. + if (this->IsImported()) { + if (cmGeneratorTarget::ImportInfo const* info = + this->GetImportInfo(config)) { + return info->Managed; + } + return ManagedType::Undefined; + } + + // Check for explicitly set clr target property. + if (auto* clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) { + return this->CheckManagedType(clr); + } + + // TODO: need to check if target is a CSharp target here. + // If yes: return ManagedType::Managed. + return ManagedType::Native; +} |