diff options
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 1987 |
1 files changed, 0 insertions, 1987 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index cf33791..1f8f07a 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -69,27 +69,6 @@ struct cmTarget::OutputInfo }; //---------------------------------------------------------------------------- -struct cmTarget::ImportInfo -{ - ImportInfo(): NoSOName(false), Multiplicity(0) {} - bool NoSOName; - int Multiplicity; - std::string Location; - std::string SOName; - std::string ImportLibrary; - std::string Languages; - std::string Libraries; - std::string LibrariesProp; - std::string SharedDeps; -}; - -//---------------------------------------------------------------------------- -struct cmTarget::CompileInfo -{ - std::string CompilePdbDir; -}; - -//---------------------------------------------------------------------------- class cmTargetInternals { public: @@ -147,9 +126,6 @@ public: typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType; ImportInfoMapType ImportInfoMap; - typedef std::map<std::string, cmTarget::CompileInfo> CompileInfoMapType; - CompileInfoMapType CompileInfoMap; - // Cache link implementation computation from each configuration. struct OptionalLinkImplementation: public cmTarget::LinkImplementation { @@ -175,23 +151,6 @@ public: HeadToLinkImplementationMap> LinkImplMapType; LinkImplMapType LinkImplMap; - typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType; - LinkClosureMapType LinkClosureMap; - - struct LinkImplClosure: public std::vector<cmTarget const*> - { - LinkImplClosure(): Done(false) {} - bool Done; - }; - std::map<std::string, LinkImplClosure> LinkImplClosureMap; - - struct CompatibleInterfaces: public cmTarget::CompatibleInterfaces - { - CompatibleInterfaces(): Done(false) {} - bool Done; - }; - std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap; - typedef std::map<std::string, std::vector<cmSourceFile*> > SourceFilesMapType; SourceFilesMapType SourceFilesMap; @@ -540,10 +499,7 @@ void cmTarget::ClearLinkMaps() this->Internal->LinkImplMap.clear(); this->Internal->LinkInterfaceMap.clear(); this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear(); - this->Internal->LinkClosureMap.clear(); this->Internal->SourceFilesMap.clear(); - cmDeleteAll(this->LinkInformation); - this->LinkInformation.clear(); } //---------------------------------------------------------------------------- @@ -625,13 +581,6 @@ bool cmTarget::IsXCTestOnApple() const } //---------------------------------------------------------------------------- -bool cmTarget::IsBundleOnApple() const -{ - return this->IsFrameworkOnApple() || this->IsAppBundleOnApple() || - this->IsCFBundleOnApple(); -} - -//---------------------------------------------------------------------------- static bool processSources(cmTarget const* tgt, const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, std::vector<std::string> &srcs, @@ -2251,31 +2200,6 @@ static void processCompileOptions(cmTarget const* tgt, } //---------------------------------------------------------------------------- -void cmTarget::GetAutoUicOptions(std::vector<std::string> &result, - const std::string& config) const -{ - const char *prop - = this->GetLinkInterfaceDependentStringProperty("AUTOUIC_OPTIONS", - config); - if (!prop) - { - return; - } - cmGeneratorExpression ge; - - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), - "AUTOUIC_OPTIONS", 0, 0); - cmSystemTools::ExpandListArgument(ge.Parse(prop) - ->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker), - result); -} - -//---------------------------------------------------------------------------- void cmTarget::GetCompileOptions(std::vector<std::string> &result, const std::string& config, const std::string& language) const @@ -2671,45 +2595,6 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo( } //---------------------------------------------------------------------------- -cmTarget::CompileInfo const* cmTarget::GetCompileInfo( - const std::string& config) const -{ - // There is no compile information for imported targets. - if(this->IsImported()) - { - return 0; - } - - if(this->GetType() > cmTarget::OBJECT_LIBRARY) - { - std::string msg = "cmTarget::GetCompileInfo called for "; - msg += this->GetName(); - msg += " which has type "; - msg += cmTarget::GetTargetTypeName(this->GetType()); - this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg); - return 0; - } - - // Lookup/compute/cache the compile information for this configuration. - std::string config_upper; - if(!config.empty()) - { - config_upper = cmSystemTools::UpperCase(config); - } - typedef cmTargetInternals::CompileInfoMapType CompileInfoMapType; - CompileInfoMapType::const_iterator i = - this->Internal->CompileInfoMap.find(config_upper); - if(i == this->Internal->CompileInfoMap.end()) - { - CompileInfo info; - this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir); - CompileInfoMapType::value_type entry(config_upper, info); - i = this->Internal->CompileInfoMap.insert(entry).first; - } - return &i->second; -} - -//---------------------------------------------------------------------------- std::string cmTarget::GetDirectory(const std::string& config, bool implib) const { @@ -2740,16 +2625,6 @@ std::string cmTarget::GetPDBDirectory(const std::string& config) const } //---------------------------------------------------------------------------- -std::string cmTarget::GetCompilePDBDirectory(const std::string& config) const -{ - if(CompileInfo const* info = this->GetCompileInfo(config)) - { - return info->CompilePdbDir; - } - return ""; -} - -//---------------------------------------------------------------------------- const char* cmTarget::ImportedGetLocation(const std::string& config) const { static std::string location; @@ -3192,229 +3067,6 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const } //---------------------------------------------------------------------------- -class cmTargetCollectLinkLanguages -{ -public: - cmTargetCollectLinkLanguages(cmTarget const* target, - const std::string& config, - UNORDERED_SET<std::string>& languages, - cmTarget const* head): - Config(config), Languages(languages), HeadTarget(head), - Makefile(target->GetMakefile()), Target(target) - { this->Visited.insert(target); } - - void Visit(cmLinkItem const& item) - { - if(!item.Target) - { - if(item.find("::") != std::string::npos) - { - bool noMessage = false; - cmake::MessageType messageType = cmake::FATAL_ERROR; - std::ostringstream e; - switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028)) - { - case cmPolicies::WARN: - { - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n"; - messageType = cmake::AUTHOR_WARNING; - } - break; - case cmPolicies::OLD: - noMessage = true; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - // Issue the fatal message. - break; - } - - if(!noMessage) - { - e << "Target \"" << this->Target->GetName() - << "\" links to target \"" << item - << "\" but the target was not found. Perhaps a find_package() " - "call is missing for an IMPORTED target, or an ALIAS target is " - "missing?"; - this->Makefile->GetCMakeInstance()->IssueMessage(messageType, - e.str(), - this->Target->GetBacktrace()); - } - } - return; - } - if(!this->Visited.insert(item.Target).second) - { - return; - } - - cmTarget::LinkInterface const* iface = - item.Target->GetLinkInterface(this->Config, this->HeadTarget); - if(!iface) { return; } - - for(std::vector<std::string>::const_iterator - li = iface->Languages.begin(); li != iface->Languages.end(); ++li) - { - this->Languages.insert(*li); - } - - for(std::vector<cmLinkItem>::const_iterator - li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li) - { - this->Visit(*li); - } - } -private: - std::string Config; - UNORDERED_SET<std::string>& Languages; - cmTarget const* HeadTarget; - cmMakefile* Makefile; - const cmTarget* Target; - std::set<cmTarget const*> Visited; -}; - -//---------------------------------------------------------------------------- -std::string cmTarget::GetLinkerLanguage(const std::string& config) const -{ - return this->GetLinkClosure(config)->LinkerLanguage; -} - -//---------------------------------------------------------------------------- -cmTarget::LinkClosure const* -cmTarget::GetLinkClosure(const std::string& config) const -{ - std::string key(cmSystemTools::UpperCase(config)); - cmTargetInternals::LinkClosureMapType::iterator - i = this->Internal->LinkClosureMap.find(key); - if(i == this->Internal->LinkClosureMap.end()) - { - LinkClosure lc; - this->ComputeLinkClosure(config, lc); - cmTargetInternals::LinkClosureMapType::value_type entry(key, lc); - i = this->Internal->LinkClosureMap.insert(entry).first; - } - return &i->second; -} - -//---------------------------------------------------------------------------- -class cmTargetSelectLinker -{ - int Preference; - cmTarget const* Target; - cmMakefile* Makefile; - cmGlobalGenerator* GG; - UNORDERED_SET<std::string> Preferred; -public: - cmTargetSelectLinker(cmTarget const* target): Preference(0), Target(target) - { - this->Makefile = this->Target->GetMakefile(); - this->GG = this->Makefile->GetGlobalGenerator(); - } - void Consider(const std::string& lang) - { - int preference = this->GG->GetLinkerPreference(lang); - if(preference > this->Preference) - { - this->Preference = preference; - this->Preferred.clear(); - } - if(preference == this->Preference) - { - this->Preferred.insert(lang); - } - } - std::string Choose() - { - if(this->Preferred.empty()) - { - return ""; - } - else if(this->Preferred.size() > 1) - { - std::ostringstream e; - e << "Target " << this->Target->GetName() - << " contains multiple languages with the highest linker preference" - << " (" << this->Preference << "):\n"; - for(UNORDERED_SET<std::string>::const_iterator - li = this->Preferred.begin(); li != this->Preferred.end(); ++li) - { - e << " " << *li << "\n"; - } - e << "Set the LINKER_LANGUAGE property for this target."; - cmake* cm = this->Makefile->GetCMakeInstance(); - cm->IssueMessage(cmake::FATAL_ERROR, e.str(), - this->Target->GetBacktrace()); - } - return *this->Preferred.begin(); - } -}; - -//---------------------------------------------------------------------------- -void cmTarget::ComputeLinkClosure(const std::string& config, - LinkClosure& lc) const -{ - // Get languages built in this target. - UNORDERED_SET<std::string> languages; - LinkImplementation const* impl = this->GetLinkImplementation(config); - for(std::vector<std::string>::const_iterator li = impl->Languages.begin(); - li != impl->Languages.end(); ++li) - { - languages.insert(*li); - } - - // Add interface languages from linked targets. - cmTargetCollectLinkLanguages cll(this, config, languages, this); - for(std::vector<cmLinkImplItem>::const_iterator - li = impl->Libraries.begin(); - li != impl->Libraries.end(); ++li) - { - cll.Visit(*li); - } - - // Store the transitive closure of languages. - for(UNORDERED_SET<std::string>::const_iterator li = languages.begin(); - li != languages.end(); ++li) - { - lc.Languages.push_back(*li); - } - - // Choose the language whose linker should be used. - if(this->GetProperty("HAS_CXX")) - { - lc.LinkerLanguage = "CXX"; - } - else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE")) - { - lc.LinkerLanguage = linkerLang; - } - else - { - // Find the language with the highest preference value. - cmTargetSelectLinker tsl(this); - - // First select from the languages compiled directly in this target. - for(std::vector<std::string>::const_iterator li = impl->Languages.begin(); - li != impl->Languages.end(); ++li) - { - tsl.Consider(*li); - } - - // Now consider languages that propagate from linked targets. - for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin(); - sit != languages.end(); ++sit) - { - std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES"; - if(this->Makefile->IsOn(propagates)) - { - tsl.Consider(*sit); - } - } - - lc.LinkerLanguage = tsl.Choose(); - } -} - -//---------------------------------------------------------------------------- void cmTarget::ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, @@ -3517,133 +3169,6 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) const } //---------------------------------------------------------------------------- -std::string cmTarget::GetPDBName(const std::string& config) const -{ - std::string prefix; - std::string base; - std::string suffix; - this->GetFullNameInternal(config, false, prefix, base, suffix); - - std::vector<std::string> props; - std::string configUpper = cmSystemTools::UpperCase(config); - if(!configUpper.empty()) - { - // PDB_NAME_<CONFIG> - props.push_back("PDB_NAME_" + configUpper); - } - - // PDB_NAME - props.push_back("PDB_NAME"); - - for(std::vector<std::string>::const_iterator i = props.begin(); - i != props.end(); ++i) - { - if(const char* outName = this->GetProperty(*i)) - { - base = outName; - break; - } - } - return prefix+base+".pdb"; -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetCompilePDBName(const std::string& config) const -{ - std::string prefix; - std::string base; - std::string suffix; - this->GetFullNameInternal(config, false, prefix, base, suffix); - - // Check for a per-configuration output directory target property. - std::string configUpper = cmSystemTools::UpperCase(config); - std::string configProp = "COMPILE_PDB_NAME_"; - configProp += configUpper; - const char* config_name = this->GetProperty(configProp); - if(config_name && *config_name) - { - return prefix + config_name + ".pdb"; - } - - const char* name = this->GetProperty("COMPILE_PDB_NAME"); - if(name && *name) - { - return prefix + name + ".pdb"; - } - - return ""; -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetCompilePDBPath(const std::string& config) const -{ - std::string dir = this->GetCompilePDBDirectory(config); - std::string name = this->GetCompilePDBName(config); - if(dir.empty() && !name.empty()) - { - dir = this->GetPDBDirectory(config); - } - if(!dir.empty()) - { - dir += "/"; - } - return dir + name; -} - -//---------------------------------------------------------------------------- -bool cmTarget::HasSOName(const std::string& config) const -{ - // soname is supported only for shared libraries and modules, - // and then only when the platform supports an soname flag. - return ((this->GetType() == cmTarget::SHARED_LIBRARY || - this->GetType() == cmTarget::MODULE_LIBRARY) && - !this->GetPropertyAsBool("NO_SONAME") && - this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config))); -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetSOName(const std::string& config) const -{ - if(this->IsImported()) - { - // Lookup the imported soname. - if(cmTarget::ImportInfo const* info = this->GetImportInfo(config)) - { - if(info->NoSOName) - { - // The imported library has no builtin soname so the name - // searched at runtime will be just the filename. - return cmSystemTools::GetFilenameName(info->Location); - } - else - { - // Use the soname given if any. - if(info->SOName.find("@rpath/") == 0) - { - return info->SOName.substr(6); - } - return info->SOName; - } - } - else - { - return ""; - } - } - else - { - // Compute the soname that will be built. - std::string name; - std::string soName; - std::string realName; - std::string impName; - std::string pdbName; - this->GetLibraryNames(name, soName, realName, impName, pdbName, config); - return soName; - } -} - -//---------------------------------------------------------------------------- bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const { bool install_name_is_rpath = false; @@ -3770,20 +3295,6 @@ bool cmTarget::IsImportedSharedLibWithoutSOName( } //---------------------------------------------------------------------------- -std::string cmTarget::GetFullName(const std::string& config, - bool implib) const -{ - if(this->IsImported()) - { - return this->GetFullNameImported(config, implib); - } - else - { - return this->GetFullNameInternal(config, implib); - } -} - -//---------------------------------------------------------------------------- std::string cmTarget::GetFullNameImported(const std::string& config, bool implib) const { @@ -3792,15 +3303,6 @@ cmTarget::GetFullNameImported(const std::string& config, bool implib) const } //---------------------------------------------------------------------------- -void cmTarget::GetFullNameComponents(std::string& prefix, std::string& base, - std::string& suffix, - const std::string& config, - bool implib) const -{ - this->GetFullNameInternal(config, implib, prefix, base, suffix); -} - -//---------------------------------------------------------------------------- std::string cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const { @@ -3818,237 +3320,6 @@ cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const } //---------------------------------------------------------------------------- -std::string -cmTarget::GetFullNameInternal(const std::string& config, bool implib) const -{ - std::string prefix; - std::string base; - std::string suffix; - this->GetFullNameInternal(config, implib, prefix, base, suffix); - return prefix+base+suffix; -} - -//---------------------------------------------------------------------------- -void cmTarget::GetFullNameInternal(const std::string& config, - bool implib, - std::string& outPrefix, - std::string& outBase, - std::string& outSuffix) const -{ - // Use just the target name for non-main target types. - if(this->GetType() != cmTarget::STATIC_LIBRARY && - this->GetType() != cmTarget::SHARED_LIBRARY && - this->GetType() != cmTarget::MODULE_LIBRARY && - this->GetType() != cmTarget::EXECUTABLE) - { - outPrefix = ""; - outBase = this->GetName(); - outSuffix = ""; - return; - } - - // Return an empty name for the import library if this platform - // does not support import libraries. - if(implib && - !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) - { - outPrefix = ""; - outBase = ""; - outSuffix = ""; - return; - } - - // The implib option is only allowed for shared libraries, module - // libraries, and executables. - if(this->GetType() != cmTarget::SHARED_LIBRARY && - this->GetType() != cmTarget::MODULE_LIBRARY && - this->GetType() != cmTarget::EXECUTABLE) - { - implib = false; - } - - // Compute the full name for main target types. - const char* targetPrefix = (implib - ? this->GetProperty("IMPORT_PREFIX") - : this->GetProperty("PREFIX")); - const char* targetSuffix = (implib - ? this->GetProperty("IMPORT_SUFFIX") - : this->GetProperty("SUFFIX")); - const char* configPostfix = 0; - if(!config.empty()) - { - std::string configProp = cmSystemTools::UpperCase(config); - configProp += "_POSTFIX"; - configPostfix = this->GetProperty(configProp); - // Mac application bundles and frameworks have no postfix. - if(configPostfix && - (this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) - { - configPostfix = 0; - } - } - const char* prefixVar = this->GetPrefixVariableInternal(implib); - const char* suffixVar = this->GetSuffixVariableInternal(implib); - - // Check for language-specific default prefix and suffix. - std::string ll = this->GetLinkerLanguage(config); - if(!ll.empty()) - { - if(!targetSuffix && suffixVar && *suffixVar) - { - std::string langSuff = suffixVar + std::string("_") + ll; - targetSuffix = this->Makefile->GetDefinition(langSuff); - } - if(!targetPrefix && prefixVar && *prefixVar) - { - std::string langPrefix = prefixVar + std::string("_") + ll; - targetPrefix = this->Makefile->GetDefinition(langPrefix); - } - } - - // if there is no prefix on the target use the cmake definition - if(!targetPrefix && prefixVar) - { - targetPrefix = this->Makefile->GetSafeDefinition(prefixVar); - } - // if there is no suffix on the target use the cmake definition - if(!targetSuffix && suffixVar) - { - targetSuffix = this->Makefile->GetSafeDefinition(suffixVar); - } - - // frameworks have directory prefix but no suffix - std::string fw_prefix; - if(this->IsFrameworkOnApple()) - { - fw_prefix = this->GetOutputName(config, false); - fw_prefix += ".framework/"; - targetPrefix = fw_prefix.c_str(); - targetSuffix = 0; - } - - if(this->IsCFBundleOnApple()) - { - fw_prefix = this->GetCFBundleDirectory(config, false); - fw_prefix += "/"; - targetPrefix = fw_prefix.c_str(); - targetSuffix = 0; - } - - // Begin the final name with the prefix. - outPrefix = targetPrefix?targetPrefix:""; - - // Append the target name or property-specified name. - outBase += this->GetOutputName(config, implib); - - // Append the per-configuration postfix. - outBase += configPostfix?configPostfix:""; - - // Name shared libraries with their version number on some platforms. - if(const char* soversion = this->GetProperty("SOVERSION")) - { - if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib && - this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")) - { - outBase += "-"; - outBase += soversion; - } - } - - // Append the suffix. - outSuffix = targetSuffix?targetSuffix:""; -} - -//---------------------------------------------------------------------------- -void cmTarget::GetLibraryNames(std::string& name, - std::string& soName, - std::string& realName, - std::string& impName, - std::string& pdbName, - const std::string& config) const -{ - // This should not be called for imported targets. - // TODO: Split cmTarget into a class hierarchy to get compile-time - // enforcement of the limited imported target API. - if(this->IsImported()) - { - std::string msg = "GetLibraryNames called on imported target: "; - msg += this->GetName(); - this->Makefile->IssueMessage(cmake::INTERNAL_ERROR, - msg); - return; - } - - assert(this->GetType() != INTERFACE_LIBRARY); - - // Check for library version properties. - const char* version = this->GetProperty("VERSION"); - const char* soversion = this->GetProperty("SOVERSION"); - if(!this->HasSOName(config) || - this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") || - this->IsFrameworkOnApple()) - { - // Versioning is supported only for shared libraries and modules, - // and then only when the platform supports an soname flag. - version = 0; - soversion = 0; - } - if(version && !soversion) - { - // The soversion must be set if the library version is set. Use - // the library version as the soversion. - soversion = version; - } - if(!version && soversion) - { - // Use the soversion as the library version. - version = soversion; - } - - // Get the components of the library name. - std::string prefix; - std::string base; - std::string suffix; - this->GetFullNameInternal(config, false, prefix, base, suffix); - - // The library name. - name = prefix+base+suffix; - - if(this->IsFrameworkOnApple()) - { - realName = prefix; - realName += "Versions/"; - realName += this->GetFrameworkVersion(); - realName += "/"; - realName += base; - soName = realName; - } - else - { - // The library's soname. - this->ComputeVersionedName(soName, prefix, base, suffix, - name, soversion); - // The library's real name on disk. - this->ComputeVersionedName(realName, prefix, base, suffix, - name, version); - } - - // The import library name. - if(this->GetType() == cmTarget::SHARED_LIBRARY || - this->GetType() == cmTarget::MODULE_LIBRARY) - { - impName = this->GetFullNameInternal(config, true); - } - else - { - impName = ""; - } - - // The program database file name. - pdbName = this->GetPDBName(config); -} - -//---------------------------------------------------------------------------- void cmTarget::ComputeVersionedName(std::string& vName, std::string const& prefix, std::string const& base, @@ -4066,68 +3337,6 @@ void cmTarget::ComputeVersionedName(std::string& vName, } //---------------------------------------------------------------------------- -void cmTarget::GetExecutableNames(std::string& name, - std::string& realName, - std::string& impName, - std::string& pdbName, - const std::string& config) const -{ - // This should not be called for imported targets. - // TODO: Split cmTarget into a class hierarchy to get compile-time - // enforcement of the limited imported target API. - if(this->IsImported()) - { - std::string msg = - "GetExecutableNames called on imported target: "; - msg += this->GetName(); - this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg); - } - - // This versioning is supported only for executables and then only - // when the platform supports symbolic links. -#if defined(_WIN32) && !defined(__CYGWIN__) - const char* version = 0; -#else - // Check for executable version properties. - const char* version = this->GetProperty("VERSION"); - if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE")) - { - version = 0; - } -#endif - - // Get the components of the executable name. - std::string prefix; - std::string base; - std::string suffix; - this->GetFullNameInternal(config, false, prefix, base, suffix); - - // The executable name. - name = prefix+base+suffix; - - // The executable's real name on disk. -#if defined(__CYGWIN__) - realName = prefix+base; -#else - realName = name; -#endif - if(version) - { - realName += "-"; - realName += version; - } -#if defined(__CYGWIN__) - realName += suffix; -#endif - - // The import library name. - impName = this->GetFullNameInternal(config, true); - - // The program database file name. - pdbName = this->GetPDBName(config); -} - -//---------------------------------------------------------------------------- bool cmTarget::HasImplibGNUtoMS() const { return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS"); @@ -4189,137 +3398,6 @@ bool cmTarget::HaveInstallTreeRPATH() const } //---------------------------------------------------------------------------- -bool cmTarget::NeedRelinkBeforeInstall(const std::string& config) const -{ - // Only executables and shared libraries can have an rpath and may - // need relinking. - if(this->TargetTypeValue != cmTarget::EXECUTABLE && - this->TargetTypeValue != cmTarget::SHARED_LIBRARY && - this->TargetTypeValue != cmTarget::MODULE_LIBRARY) - { - return false; - } - - // If there is no install location this target will not be installed - // and therefore does not need relinking. - if(!this->GetHaveInstallRule()) - { - return false; - } - - // If skipping all rpaths completely then no relinking is needed. - if(this->Makefile->IsOn("CMAKE_SKIP_RPATH")) - { - return false; - } - - // If building with the install-tree rpath no relinking is needed. - if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH")) - { - return false; - } - - // If chrpath is going to be used no relinking is needed. - if(this->IsChrpathUsed(config)) - { - return false; - } - - // Check for rpath support on this platform. - std::string ll = this->GetLinkerLanguage(config); - if(!ll.empty()) - { - std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; - flagVar += ll; - flagVar += "_FLAG"; - if(!this->Makefile->IsSet(flagVar)) - { - // There is no rpath support on this platform so nothing needs - // relinking. - return false; - } - } - else - { - // No linker language is known. This error will be reported by - // other code. - return false; - } - - // If either a build or install tree rpath is set then the rpath - // will likely change between the build tree and install tree and - // this target must be relinked. - return this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(); -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetInstallNameDirForBuildTree( - const std::string& config) const -{ - // If building directly for installation then the build tree install_name - // is the same as the install tree. - if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH")) - { - return GetInstallNameDirForInstallTree(); - } - - // Use the build tree directory for the target. - if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") && - !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && - !this->GetPropertyAsBool("SKIP_BUILD_RPATH")) - { - std::string dir; - bool macosx_rpath = this->MacOSXRpathInstallNameDirDefault(); - if(macosx_rpath) - { - dir = "@rpath"; - } - else - { - dir = this->GetDirectory(config); - } - dir += "/"; - return dir; - } - else - { - return ""; - } -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetInstallNameDirForInstallTree() const -{ - if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) - { - std::string dir; - const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR"); - - if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") && - !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH")) - { - if(install_name_dir && *install_name_dir) - { - dir = install_name_dir; - dir += "/"; - } - } - if(!install_name_dir) - { - if(this->MacOSXRpathInstallNameDirDefault()) - { - dir = "@rpath/"; - } - } - return dir; - } - else - { - return ""; - } -} - -//---------------------------------------------------------------------------- const char* cmTarget::GetOutputTargetType(bool implib) const { switch(this->GetType()) @@ -4527,54 +3605,6 @@ bool cmTarget::UsesDefaultOutputDir(const std::string& config, } //---------------------------------------------------------------------------- -std::string cmTarget::GetOutputName(const std::string& config, - bool implib) const -{ - std::vector<std::string> props; - std::string type = this->GetOutputTargetType(implib); - std::string configUpper = cmSystemTools::UpperCase(config); - if(!type.empty() && !configUpper.empty()) - { - // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG> - props.push_back(type + "_OUTPUT_NAME_" + configUpper); - } - if(!type.empty()) - { - // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME - props.push_back(type + "_OUTPUT_NAME"); - } - if(!configUpper.empty()) - { - // OUTPUT_NAME_<CONFIG> - props.push_back("OUTPUT_NAME_" + configUpper); - // <CONFIG>_OUTPUT_NAME - props.push_back(configUpper + "_OUTPUT_NAME"); - } - // OUTPUT_NAME - props.push_back("OUTPUT_NAME"); - - std::string outName; - for(std::vector<std::string>::const_iterator i = props.begin(); - i != props.end(); ++i) - { - if (const char* outNameProp = this->GetProperty(*i)) - { - outName = outNameProp; - break; - } - } - - if (outName.empty()) - { - outName = this->GetName(); - } - - cmGeneratorExpression ge; - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName); - return cge->Evaluate(this->Makefile, config); -} - -//---------------------------------------------------------------------------- std::string cmTarget::GetFrameworkVersion() const { assert(this->GetType() != INTERFACE_LIBRARY); @@ -4627,500 +3657,6 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const } //---------------------------------------------------------------------------- -template<typename PropertyType> -PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop); - -//---------------------------------------------------------------------------- -template<> -bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop) -{ - return tgt->GetPropertyAsBool(prop); -} - -//---------------------------------------------------------------------------- -template<> -const char *getTypedProperty<const char *>(cmTarget const* tgt, - const std::string& prop) -{ - return tgt->GetProperty(prop); -} - -enum CompatibleType -{ - BoolType, - StringType, - NumberMinType, - NumberMaxType -}; - -//---------------------------------------------------------------------------- -template<typename PropertyType> -std::pair<bool, PropertyType> consistentProperty(PropertyType lhs, - PropertyType rhs, - CompatibleType t); - -//---------------------------------------------------------------------------- -template<> -std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType) -{ - return std::make_pair(lhs == rhs, lhs); -} - -//---------------------------------------------------------------------------- -std::pair<bool, const char*> consistentStringProperty(const char *lhs, - const char *rhs) -{ - const bool b = strcmp(lhs, rhs) == 0; - return std::make_pair(b, b ? lhs : 0); -} - -//---------------------------------------------------------------------------- -std::pair<bool, const char*> consistentNumberProperty(const char *lhs, - const char *rhs, - CompatibleType t) -{ - char *pEnd; - - const char* const null_ptr = 0; - - long lnum = strtol(lhs, &pEnd, 0); - if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) - { - return std::pair<bool, const char*>(false, null_ptr); - } - - long rnum = strtol(rhs, &pEnd, 0); - if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) - { - return std::pair<bool, const char*>(false, null_ptr); - } - - if (t == NumberMaxType) - { - return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs); - } - else - { - return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs); - } -} - -//---------------------------------------------------------------------------- -template<> -std::pair<bool, const char*> consistentProperty(const char *lhs, - const char *rhs, - CompatibleType t) -{ - if (!lhs && !rhs) - { - return std::make_pair(true, lhs); - } - if (!lhs) - { - return std::make_pair(true, rhs); - } - if (!rhs) - { - return std::make_pair(true, lhs); - } - - const char* const null_ptr = 0; - - switch(t) - { - case BoolType: - assert(0 && "consistentProperty for strings called with BoolType"); - return std::pair<bool, const char*>(false, null_ptr); - case StringType: - return consistentStringProperty(lhs, rhs); - case NumberMinType: - case NumberMaxType: - return consistentNumberProperty(lhs, rhs, t); - } - assert(0 && "Unreachable!"); - return std::pair<bool, const char*>(false, null_ptr); -} - -template<typename PropertyType> -PropertyType impliedValue(PropertyType); -template<> -bool impliedValue<bool>(bool) -{ - return false; -} -template<> -const char* impliedValue<const char*>(const char*) -{ - return ""; -} - - -template<typename PropertyType> -std::string valueAsString(PropertyType); -template<> -std::string valueAsString<bool>(bool value) -{ - return value ? "TRUE" : "FALSE"; -} -template<> -std::string valueAsString<const char*>(const char* value) -{ - return value ? value : "(unset)"; -} - -//---------------------------------------------------------------------------- -void -cmTarget::ReportPropertyOrigin(const std::string &p, - const std::string &result, - const std::string &report, - const std::string &compatibilityType) const -{ - std::vector<std::string> debugProperties; - const char *debugProp = - this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); - if (debugProp) - { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); - } - - bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] - && std::find(debugProperties.begin(), - debugProperties.end(), - p) - != debugProperties.end(); - - if (this->Makefile->IsConfigured()) - { - this->DebugCompatiblePropertiesDone[p] = true; - } - if (!debugOrigin) - { - return; - } - - std::string areport = compatibilityType; - areport += std::string(" of property \"") + p + "\" for target \""; - areport += std::string(this->GetName()); - areport += "\" (result: \""; - areport += result; - areport += "\"):\n" + report; - - this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport); -} - -//---------------------------------------------------------------------------- -std::string compatibilityType(CompatibleType t) -{ - switch(t) - { - case BoolType: - return "Boolean compatibility"; - case StringType: - return "String compatibility"; - case NumberMaxType: - return "Numeric maximum compatibility"; - case NumberMinType: - return "Numeric minimum compatibility"; - } - assert(0 && "Unreachable!"); - return ""; -} - -//---------------------------------------------------------------------------- -std::string compatibilityAgree(CompatibleType t, bool dominant) -{ - switch(t) - { - case BoolType: - case StringType: - return dominant ? "(Disagree)\n" : "(Agree)\n"; - case NumberMaxType: - case NumberMinType: - return dominant ? "(Dominant)\n" : "(Ignored)\n"; - } - assert(0 && "Unreachable!"); - return ""; -} - -//---------------------------------------------------------------------------- -template<typename PropertyType> -PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, - const std::string &p, - const std::string& config, - const char *defaultValue, - CompatibleType t, - PropertyType *) -{ - PropertyType propContent = getTypedProperty<PropertyType>(tgt, p); - const bool explicitlySet = tgt->GetProperties() - .find(p) - != tgt->GetProperties().end(); - const bool impliedByUse = - tgt->IsNullImpliedByLinkLibraries(p); - assert((impliedByUse ^ explicitlySet) - || (!impliedByUse && !explicitlySet)); - - std::vector<cmTarget const*> const& deps = - tgt->GetLinkImplementationClosure(config); - - if(deps.empty()) - { - return propContent; - } - bool propInitialized = explicitlySet; - - std::string report = " * Target \""; - report += tgt->GetName(); - if (explicitlySet) - { - report += "\" has property content \""; - report += valueAsString<PropertyType>(propContent); - report += "\"\n"; - } - else if (impliedByUse) - { - report += "\" property is implied by use.\n"; - } - else - { - report += "\" property not set.\n"; - } - - std::string interfaceProperty = "INTERFACE_" + p; - for(std::vector<cmTarget const*>::const_iterator li = - deps.begin(); - li != deps.end(); ++li) - { - // An error should be reported if one dependency - // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other - // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the - // target itself has a POSITION_INDEPENDENT_CODE which disagrees - // with a dependency. - - cmTarget const* theTarget = *li; - - const bool ifaceIsSet = theTarget->GetProperties() - .find(interfaceProperty) - != theTarget->GetProperties().end(); - PropertyType ifacePropContent = - getTypedProperty<PropertyType>(theTarget, - interfaceProperty); - - std::string reportEntry; - if (ifaceIsSet) - { - reportEntry += " * Target \""; - reportEntry += theTarget->GetName(); - reportEntry += "\" property value \""; - reportEntry += valueAsString<PropertyType>(ifacePropContent); - reportEntry += "\" "; - } - - if (explicitlySet) - { - if (ifaceIsSet) - { - std::pair<bool, PropertyType> consistent = - consistentProperty(propContent, - ifacePropContent, t); - report += reportEntry; - report += compatibilityAgree(t, propContent != consistent.second); - if (!consistent.first) - { - std::ostringstream e; - e << "Property " << p << " on target \"" - << tgt->GetName() << "\" does\nnot match the " - "INTERFACE_" << p << " property requirement\nof " - "dependency \"" << theTarget->GetName() << "\".\n"; - cmSystemTools::Error(e.str().c_str()); - break; - } - else - { - propContent = consistent.second; - continue; - } - } - else - { - // Explicitly set on target and not set in iface. Can't disagree. - continue; - } - } - else if (impliedByUse) - { - propContent = impliedValue<PropertyType>(propContent); - - if (ifaceIsSet) - { - std::pair<bool, PropertyType> consistent = - consistentProperty(propContent, - ifacePropContent, t); - report += reportEntry; - report += compatibilityAgree(t, propContent != consistent.second); - if (!consistent.first) - { - std::ostringstream e; - e << "Property " << p << " on target \"" - << tgt->GetName() << "\" is\nimplied to be " << defaultValue - << " because it was used to determine the link libraries\n" - "already. The INTERFACE_" << p << " property on\ndependency \"" - << theTarget->GetName() << "\" is in conflict.\n"; - cmSystemTools::Error(e.str().c_str()); - break; - } - else - { - propContent = consistent.second; - continue; - } - } - else - { - // Implicitly set on target and not set in iface. Can't disagree. - continue; - } - } - else - { - if (ifaceIsSet) - { - if (propInitialized) - { - std::pair<bool, PropertyType> consistent = - consistentProperty(propContent, - ifacePropContent, t); - report += reportEntry; - report += compatibilityAgree(t, propContent != consistent.second); - if (!consistent.first) - { - std::ostringstream e; - e << "The INTERFACE_" << p << " property of \"" - << theTarget->GetName() << "\" does\nnot agree with the value " - "of " << p << " already determined\nfor \"" - << tgt->GetName() << "\".\n"; - cmSystemTools::Error(e.str().c_str()); - break; - } - else - { - propContent = consistent.second; - continue; - } - } - else - { - report += reportEntry + "(Interface set)\n"; - propContent = ifacePropContent; - propInitialized = true; - } - } - else - { - // Not set. Nothing to agree on. - continue; - } - } - } - - tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent), - report, compatibilityType(t)); - return propContent; -} - -//---------------------------------------------------------------------------- -bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, - const std::string& config) const -{ - return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE", - BoolType, 0); -} - -//---------------------------------------------------------------------------- -const char * cmTarget::GetLinkInterfaceDependentStringProperty( - const std::string &p, - const std::string& config) const -{ - return checkInterfacePropertyCompatibility<const char *>(this, - p, - config, - "empty", - StringType, 0); -} - -//---------------------------------------------------------------------------- -const char * cmTarget::GetLinkInterfaceDependentNumberMinProperty( - const std::string &p, - const std::string& config) const -{ - return checkInterfacePropertyCompatibility<const char *>(this, - p, - config, - "empty", - NumberMinType, 0); -} - -//---------------------------------------------------------------------------- -const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty( - const std::string &p, - const std::string& config) const -{ - return checkInterfacePropertyCompatibility<const char *>(this, - p, - config, - "empty", - NumberMaxType, 0); -} - -//---------------------------------------------------------------------------- -bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, - const std::string& config) const -{ - if (this->TargetTypeValue == OBJECT_LIBRARY - || this->TargetTypeValue == INTERFACE_LIBRARY) - { - return false; - } - return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0; -} - -//---------------------------------------------------------------------------- -bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, - const std::string& config) const -{ - if (this->TargetTypeValue == OBJECT_LIBRARY - || this->TargetTypeValue == INTERFACE_LIBRARY) - { - return false; - } - return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0; -} - -//---------------------------------------------------------------------------- -bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p, - const std::string& config) const -{ - if (this->TargetTypeValue == OBJECT_LIBRARY - || this->TargetTypeValue == INTERFACE_LIBRARY) - { - return false; - } - return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0; -} - -//---------------------------------------------------------------------------- -bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, - const std::string& config) const -{ - if (this->TargetTypeValue == OBJECT_LIBRARY - || this->TargetTypeValue == INTERFACE_LIBRARY) - { - return false; - } - return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0; -} - -//---------------------------------------------------------------------------- void cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const { @@ -5206,73 +3742,6 @@ void cmTarget::GetLanguages(std::set<std::string>& languages, } //---------------------------------------------------------------------------- -bool cmTarget::IsChrpathUsed(const std::string& config) const -{ - // Only certain target types have an rpath. - if(!(this->GetType() == cmTarget::SHARED_LIBRARY || - this->GetType() == cmTarget::MODULE_LIBRARY || - this->GetType() == cmTarget::EXECUTABLE)) - { - return false; - } - - // If the target will not be installed we do not need to change its - // rpath. - if(!this->GetHaveInstallRule()) - { - return false; - } - - // Skip chrpath if skipping rpath altogether. - if(this->Makefile->IsOn("CMAKE_SKIP_RPATH")) - { - return false; - } - - // Skip chrpath if it does not need to be changed at install time. - if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH")) - { - return false; - } - - // Allow the user to disable builtin chrpath explicitly. - if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH")) - { - return false; - } - - if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) - { - return true; - } - -#if defined(CMAKE_USE_ELF_PARSER) - // Enable if the rpath flag uses a separator and the target uses ELF - // binaries. - std::string ll = this->GetLinkerLanguage(config); - if(!ll.empty()) - { - std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; - sepVar += ll; - sepVar += "_FLAG_SEP"; - const char* sep = this->Makefile->GetDefinition(sepVar); - if(sep && *sep) - { - // TODO: Add ELF check to ABI detection and get rid of - // CMAKE_EXECUTABLE_FORMAT. - if(const char* fmt = - this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT")) - { - return strcmp(fmt, "ELF") == 0; - } - } - } -#endif - static_cast<void>(config); - return false; -} - -//---------------------------------------------------------------------------- cmTarget::ImportInfo const* cmTarget::GetImportInfo(const std::string& config) const { @@ -5760,86 +4229,6 @@ cmTarget::GetImportLinkInterface(const std::string& config, } //---------------------------------------------------------------------------- -void processILibs(const std::string& config, - cmTarget const* headTarget, - cmLinkItem const& item, - std::vector<cmTarget const*>& tgts, - std::set<cmTarget const*>& emitted) -{ - if (item.Target && emitted.insert(item.Target).second) - { - tgts.push_back(item.Target); - if(cmTarget::LinkInterfaceLibraries const* iface = - item.Target->GetLinkInterfaceLibraries(config, headTarget, true)) - { - for(std::vector<cmLinkItem>::const_iterator - it = iface->Libraries.begin(); - it != iface->Libraries.end(); ++it) - { - processILibs(config, headTarget, *it, tgts, emitted); - } - } - } -} - -//---------------------------------------------------------------------------- -std::vector<cmTarget const*> const& -cmTarget::GetLinkImplementationClosure(const std::string& config) const -{ - cmTargetInternals::LinkImplClosure& tgts = - this->Internal->LinkImplClosureMap[config]; - if(!tgts.Done) - { - tgts.Done = true; - std::set<cmTarget const*> emitted; - - cmTarget::LinkImplementationLibraries const* impl - = this->GetLinkImplementationLibraries(config); - - for(std::vector<cmLinkImplItem>::const_iterator - it = impl->Libraries.begin(); - it != impl->Libraries.end(); ++it) - { - processILibs(config, this, *it, tgts , emitted); - } - } - return tgts; -} - -//---------------------------------------------------------------------------- -cmTarget::CompatibleInterfaces const& -cmTarget::GetCompatibleInterfaces(std::string const& config) const -{ - cmTargetInternals::CompatibleInterfaces& compat = - this->Internal->CompatibleInterfacesMap[config]; - if(!compat.Done) - { - compat.Done = true; - compat.PropsBool.insert("POSITION_INDEPENDENT_CODE"); - compat.PropsString.insert("AUTOUIC_OPTIONS"); - std::vector<cmTarget const*> const& deps = - this->GetLinkImplementationClosure(config); - for(std::vector<cmTarget const*>::const_iterator li = deps.begin(); - li != deps.end(); ++li) - { -#define CM_READ_COMPATIBLE_INTERFACE(X, x) \ - if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \ - { \ - std::vector<std::string> props; \ - cmSystemTools::ExpandListArgument(prop, props); \ - compat.Props##x.insert(props.begin(), props.end()); \ - } - CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool) - CM_READ_COMPATIBLE_INTERFACE(STRING, String) - CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin) - CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax) -#undef CM_READ_COMPATIBLE_INTERFACE - } - } - return compat; -} - -//---------------------------------------------------------------------------- void cmTargetInternals::ComputeLinkInterfaceLibraries( cmTarget const* thisTarget, @@ -6396,382 +4785,6 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const return lib; } -template<typename PropertyType> -PropertyType getLinkInterfaceDependentProperty(cmTarget const* tgt, - const std::string& prop, - const std::string& config, - CompatibleType, - PropertyType *); - -template<> -bool getLinkInterfaceDependentProperty(cmTarget const* tgt, - const std::string& prop, - const std::string& config, - CompatibleType, bool *) -{ - return tgt->GetLinkInterfaceDependentBoolProperty(prop, config); -} - -template<> -const char * getLinkInterfaceDependentProperty(cmTarget const* tgt, - const std::string& prop, - const std::string& config, - CompatibleType t, - const char **) -{ - switch(t) - { - case BoolType: - assert(0 && "String compatibility check function called for boolean"); - return 0; - case StringType: - return tgt->GetLinkInterfaceDependentStringProperty(prop, config); - case NumberMinType: - return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config); - case NumberMaxType: - return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config); - } - assert(0 && "Unreachable!"); - return 0; -} - -//---------------------------------------------------------------------------- -template<typename PropertyType> -void checkPropertyConsistency(cmTarget const* depender, - cmTarget const* dependee, - const std::string& propName, - std::set<std::string> &emitted, - const std::string& config, - CompatibleType t, - PropertyType *) -{ - const char *prop = dependee->GetProperty(propName); - if (!prop) - { - return; - } - - std::vector<std::string> props; - cmSystemTools::ExpandListArgument(prop, props); - std::string pdir = - dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT"); - pdir += "/Help/prop_tgt/"; - - for(std::vector<std::string>::iterator pi = props.begin(); - pi != props.end(); ++pi) - { - std::string pname = cmSystemTools::HelpFileName(*pi); - std::string pfile = pdir + pname + ".rst"; - if(cmSystemTools::FileExists(pfile.c_str(), true)) - { - std::ostringstream e; - e << "Target \"" << dependee->GetName() << "\" has property \"" - << *pi << "\" listed in its " << propName << " property. " - "This is not allowed. Only user-defined properties may appear " - "listed in the " << propName << " property."; - depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str()); - return; - } - if(emitted.insert(*pi).second) - { - getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config, - t, 0); - if (cmSystemTools::GetErrorOccuredFlag()) - { - return; - } - } - } -} - -static std::string intersect(const std::set<std::string> &s1, - const std::set<std::string> &s2) -{ - std::set<std::string> intersect; - std::set_intersection(s1.begin(),s1.end(), - s2.begin(),s2.end(), - std::inserter(intersect,intersect.begin())); - if (!intersect.empty()) - { - return *intersect.begin(); - } - return ""; -} -static std::string intersect(const std::set<std::string> &s1, - const std::set<std::string> &s2, - const std::set<std::string> &s3) -{ - std::string result; - result = intersect(s1, s2); - if (!result.empty()) - return result; - result = intersect(s1, s3); - if (!result.empty()) - return result; - return intersect(s2, s3); -} -static std::string intersect(const std::set<std::string> &s1, - const std::set<std::string> &s2, - const std::set<std::string> &s3, - const std::set<std::string> &s4) -{ - std::string result; - result = intersect(s1, s2); - if (!result.empty()) - return result; - result = intersect(s1, s3); - if (!result.empty()) - return result; - result = intersect(s1, s4); - if (!result.empty()) - return result; - return intersect(s2, s3, s4); -} - -//---------------------------------------------------------------------------- -void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, - const std::string& config) const -{ - const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); - - std::set<std::string> emittedBools; - static std::string strBool = "COMPATIBLE_INTERFACE_BOOL"; - std::set<std::string> emittedStrings; - static std::string strString = "COMPATIBLE_INTERFACE_STRING"; - std::set<std::string> emittedMinNumbers; - static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN"; - std::set<std::string> emittedMaxNumbers; - static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX"; - - for(cmComputeLinkInformation::ItemVector::const_iterator li = - deps.begin(); - li != deps.end(); ++li) - { - if (!li->Target) - { - continue; - } - - checkPropertyConsistency<bool>(this, li->Target, - strBool, - emittedBools, config, BoolType, 0); - if (cmSystemTools::GetErrorOccuredFlag()) - { - return; - } - checkPropertyConsistency<const char *>(this, li->Target, - strString, - emittedStrings, config, - StringType, 0); - if (cmSystemTools::GetErrorOccuredFlag()) - { - return; - } - checkPropertyConsistency<const char *>(this, li->Target, - strNumMin, - emittedMinNumbers, config, - NumberMinType, 0); - if (cmSystemTools::GetErrorOccuredFlag()) - { - return; - } - checkPropertyConsistency<const char *>(this, li->Target, - strNumMax, - emittedMaxNumbers, config, - NumberMaxType, 0); - if (cmSystemTools::GetErrorOccuredFlag()) - { - return; - } - } - - std::string prop = intersect(emittedBools, - emittedStrings, - emittedMinNumbers, - emittedMaxNumbers); - - if (!prop.empty()) - { - // Use a sorted std::vector to keep the error message sorted. - std::vector<std::string> props; - std::set<std::string>::const_iterator i = emittedBools.find(prop); - if (i != emittedBools.end()) - { - props.push_back(strBool); - } - i = emittedStrings.find(prop); - if (i != emittedStrings.end()) - { - props.push_back(strString); - } - i = emittedMinNumbers.find(prop); - if (i != emittedMinNumbers.end()) - { - props.push_back(strNumMin); - } - i = emittedMaxNumbers.find(prop); - if (i != emittedMaxNumbers.end()) - { - props.push_back(strNumMax); - } - std::sort(props.begin(), props.end()); - - std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", "); - propsString += " and the " + props.back(); - - std::ostringstream e; - e << "Property \"" << prop << "\" appears in both the " - << propsString << - " property in the dependencies of target \"" << this->GetName() << - "\". This is not allowed. A property may only require compatibility " - "in a boolean interpretation, a numeric minimum, a numeric maximum or a " - "string interpretation, but not a mixture."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); - } -} - -//---------------------------------------------------------------------------- -cmComputeLinkInformation* -cmTarget::GetLinkInformation(const std::string& config) const -{ - // Lookup any existing information for this configuration. - std::string key(cmSystemTools::UpperCase(config)); - cmTargetLinkInformationMap::iterator - i = this->LinkInformation.find(key); - if(i == this->LinkInformation.end()) - { - // Compute information for this configuration. - cmComputeLinkInformation* info = - new cmComputeLinkInformation(this, config); - if(!info || !info->Compute()) - { - delete info; - info = 0; - } - - // Store the information for this configuration. - cmTargetLinkInformationMap::value_type entry(key, info); - i = this->LinkInformation.insert(entry).first; - - if (info) - { - this->CheckPropertyCompatibility(info, config); - } - } - return i->second; -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetFrameworkDirectory(const std::string& config, - bool rootDir) const -{ - std::string fpath; - fpath += this->GetOutputName(config, false); - fpath += ".framework"; - if(!rootDir) - { - fpath += "/Versions/"; - fpath += this->GetFrameworkVersion(); - } - return fpath; -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetCFBundleDirectory(const std::string& config, - bool contentOnly) const -{ - std::string fpath; - fpath += this->GetOutputName(config, false); - fpath += "."; - const char *ext = this->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - if (this->IsXCTestOnApple()) - { - ext = "xctest"; - } - else - { - ext = "bundle"; - } - } - fpath += ext; - fpath += "/Contents"; - if(!contentOnly) - fpath += "/MacOS"; - return fpath; -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetAppBundleDirectory(const std::string& config, - bool contentOnly) const -{ - std::string fpath = this->GetFullName(config, false); - fpath += ".app/Contents"; - if(!contentOnly) - fpath += "/MacOS"; - return fpath; -} - -//---------------------------------------------------------------------------- -std::string cmTarget::BuildMacContentDirectory(const std::string& base, - const std::string& config, - bool contentOnly) const -{ - std::string fpath = base; - if(this->IsAppBundleOnApple()) - { - fpath += this->GetAppBundleDirectory(config, contentOnly); - } - if(this->IsFrameworkOnApple()) - { - fpath += this->GetFrameworkDirectory(config, contentOnly); - } - if(this->IsCFBundleOnApple()) - { - fpath += this->GetCFBundleDirectory(config, contentOnly); - } - return fpath; -} - -//---------------------------------------------------------------------------- -std::string cmTarget::GetMacContentDirectory(const std::string& config, - bool implib) const -{ - // Start with the output directory for the target. - std::string fpath = this->GetDirectory(config, implib); - fpath += "/"; - bool contentOnly = true; - if(this->IsFrameworkOnApple()) - { - // additional files with a framework go into the version specific - // directory - contentOnly = false; - } - fpath = this->BuildMacContentDirectory(fpath, config, contentOnly); - return fpath; -} - -//---------------------------------------------------------------------------- -cmTargetLinkInformationMap -::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived() -{ - // Ideally cmTarget instances should never be copied. However until - // we can make a sweep to remove that, this copy constructor avoids - // allowing the resources (LinkInformation) from getting copied. In - // the worst case this will lead to extra cmComputeLinkInformation - // instances. We also enforce in debug mode that the map be emptied - // when copied. - static_cast<void>(r); - assert(r.empty()); -} - -//---------------------------------------------------------------------------- -cmTargetLinkInformationMap::~cmTargetLinkInformationMap() -{ - cmDeleteAll(*this); -} - //---------------------------------------------------------------------------- cmTargetInternalPointer::cmTargetInternalPointer() { |