diff options
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 630 |
1 files changed, 540 insertions, 90 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 4fd9cec..b2959fe 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -335,6 +335,26 @@ std::string cmGeneratorTarget::GetName() const } //---------------------------------------------------------------------------- +std::string cmGeneratorTarget::GetExportName() const +{ + const char *exportName = this->GetProperty("EXPORT_NAME"); + + if (exportName && *exportName) + { + if (!cmGeneratorExpression::IsValidTargetName(exportName)) + { + std::ostringstream e; + e << "EXPORT_NAME property \"" << exportName << "\" for \"" + << this->GetName() << "\": is not valid."; + cmSystemTools::Error(e.str().c_str()); + return ""; + } + return exportName; + } + return this->GetName(); +} + +//---------------------------------------------------------------------------- const char *cmGeneratorTarget::GetProperty(const std::string& prop) const { return this->Target->GetProperty(prop); @@ -774,9 +794,8 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const for(std::set<std::string>::const_iterator i = utilities.begin(); i != utilities.end(); ++i) { - cmTarget* tgt = this->Makefile->FindTargetToUse(*i); - cmGeneratorTarget* gt = tgt ? this->GlobalGenerator - ->GetGeneratorTarget(tgt) : 0; + cmGeneratorTarget* gt = + this->LocalGenerator->FindGeneratorTargetToUse(*i); this->UtilityItems.insert(cmLinkItem(*i, gt)); } } @@ -797,7 +816,7 @@ void cmGeneratorTarget const char* cmGeneratorTarget::GetLocation(const std::string& config) const { static std::string location; - if (this->Target->IsImported()) + if (this->IsImported()) { location = this->Target->ImportedGetFullPath(config, false); } @@ -832,7 +851,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const location += cfgid; } - if(this->Target->IsAppBundleOnApple()) + if(this->IsAppBundleOnApple()) { std::string macdir = this->BuildMacContentDirectory("", "", false); @@ -986,7 +1005,7 @@ static bool processSources(cmGeneratorTarget const* tgt, { if(!e.empty()) { - cmake* cm = mf->GetCMakeInstance(); + cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance(); cm->IssueMessage(cmake::FATAL_ERROR, e, tgt->Target->GetBacktrace()); } @@ -1044,7 +1063,7 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string> &files, { assert(this->GetType() != cmState::INTERFACE_LIBRARY); - if (!this->Makefile->GetGlobalGenerator()->GetConfigureDoneCMP0026()) + if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) { // At configure-time, this method can be called as part of getting the // LOCATION property or to export() a file to be include()d. However @@ -1089,7 +1108,7 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string> &files, "SOURCES") != debugProperties.end(); - if (this->Makefile->GetGlobalGenerator()->GetConfigureDoneCMP0026()) + if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) { this->DebugSourcesDone = true; } @@ -1365,7 +1384,8 @@ bool cmGeneratorTarget::IsImportedSharedLibWithoutSOName( { if(this->IsImported() && this->GetType() == cmState::SHARED_LIBRARY) { - if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config)) + if(cmGeneratorTarget::ImportInfo const* info = + this->GetImportInfo(config)) { return info->NoSOName; } @@ -1406,7 +1426,8 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir( else { // Lookup the imported soname. - if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config)) + if(cmGeneratorTarget::ImportInfo const* info = + this->GetImportInfo(config)) { if(!info->NoSOName && !info->SOName.empty()) { @@ -1448,7 +1469,7 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir( w << " This could be because you are using a Mac OS X version"; w << " less than 10.5 or because CMake's platform configuration is"; w << " corrupt."; - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = this->LocalGenerator->GetCMakeInstance(); cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->Target->GetBacktrace()); } @@ -1475,7 +1496,7 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const if(cmp0042 == cmPolicies::WARN) { - this->Makefile->GetGlobalGenerator()-> + this->LocalGenerator->GetGlobalGenerator()-> AddCMP0042WarnTarget(this->GetName()); } @@ -1490,10 +1511,11 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const //---------------------------------------------------------------------------- std::string cmGeneratorTarget::GetSOName(const std::string& config) const { - if(this->Target->IsImported()) + if(this->IsImported()) { // Lookup the imported soname. - if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config)) + if(cmGeneratorTarget::ImportInfo const* info = + this->GetImportInfo(config)) { if(info->NoSOName) { @@ -1550,9 +1572,9 @@ cmGeneratorTarget::GetAppBundleDirectory(const std::string& config, //---------------------------------------------------------------------------- bool cmGeneratorTarget::IsBundleOnApple() const { - return this->Target->IsFrameworkOnApple() - || this->Target->IsAppBundleOnApple() - || this->Target->IsCFBundleOnApple(); + return this->IsFrameworkOnApple() + || this->IsAppBundleOnApple() + || this->IsCFBundleOnApple(); } //---------------------------------------------------------------------------- @@ -1565,7 +1587,7 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config, const char *ext = this->GetProperty("BUNDLE_EXTENSION"); if (!ext) { - if (this->Target->IsXCTestOnApple()) + if (this->IsXCTestOnApple()) { ext = "xctest"; } @@ -1604,9 +1626,9 @@ cmGeneratorTarget::GetFrameworkDirectory(const std::string& config, std::string cmGeneratorTarget::GetFullName(const std::string& config, bool implib) const { - if(this->Target->IsImported()) + if(this->IsImported()) { - return this->Target->GetFullNameImported(config, implib); + return this->GetFullNameImported(config, implib); } else { @@ -1691,7 +1713,7 @@ public: cmGeneratorTarget const* head): Config(config), Languages(languages), HeadTarget(head), Makefile(target->Target->GetMakefile()), Target(target) - { this->Visited.insert(target->Target); } + { this->Visited.insert(target); } void Visit(cmLinkItem const& item) { @@ -1732,7 +1754,7 @@ public: } return; } - if(!this->Visited.insert(item.Target->Target).second) + if(!this->Visited.insert(item.Target).second) { return; } @@ -1758,7 +1780,7 @@ private: cmGeneratorTarget const* HeadTarget; cmMakefile* Makefile; const cmGeneratorTarget* Target; - std::set<cmTarget const*> Visited; + std::set<cmGeneratorTarget const*> Visited; }; //---------------------------------------------------------------------------- @@ -1783,14 +1805,12 @@ class cmTargetSelectLinker { int Preference; cmGeneratorTarget const* Target; - cmMakefile* Makefile; cmGlobalGenerator* GG; std::set<std::string> Preferred; public: cmTargetSelectLinker(cmGeneratorTarget const* target) : Preference(0), Target(target) { - this->Makefile = this->Target->Makefile; this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator(); } void Consider(const char* lang) @@ -1824,7 +1844,7 @@ public: e << " " << *li << "\n"; } e << "Set the LINKER_LANGUAGE property for this target."; - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = this->Target->GetLocalGenerator()->GetCMakeInstance(); cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->Target->Target->GetBacktrace()); } @@ -1915,15 +1935,15 @@ cmGeneratorTarget::BuildMacContentDirectory(const std::string& base, bool contentOnly) const { std::string fpath = base; - if(this->Target->IsAppBundleOnApple()) + if(this->IsAppBundleOnApple()) { fpath += this->GetAppBundleDirectory(config, contentOnly); } - if(this->Target->IsFrameworkOnApple()) + if(this->IsFrameworkOnApple()) { fpath += this->GetFrameworkDirectory(config, contentOnly); } - if(this->Target->IsCFBundleOnApple()) + if(this->IsCFBundleOnApple()) { fpath += this->GetCFBundleDirectory(config, contentOnly); } @@ -1939,7 +1959,7 @@ cmGeneratorTarget::GetMacContentDirectory(const std::string& config, std::string fpath = this->GetDirectory(config, implib); fpath += "/"; bool contentOnly = true; - if(this->Target->IsFrameworkOnApple()) + if(this->IsFrameworkOnApple()) { // additional files with a framework go into the version specific // directory @@ -2004,27 +2024,26 @@ cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs, { std::vector<cmSourceFile const*> objectFiles; this->GetExternalObjects(objectFiles, config); - std::vector<cmTarget*> objectLibraries; + std::vector<cmGeneratorTarget*> objectLibraries; for(std::vector<cmSourceFile const*>::const_iterator it = objectFiles.begin(); it != objectFiles.end(); ++it) { std::string objLib = (*it)->GetObjectLibrary(); - if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib)) + if (cmGeneratorTarget* tgt = + this->LocalGenerator->FindGeneratorTargetToUse(objLib)) { objectLibraries.push_back(tgt); } } - std::vector<cmTarget*>::const_iterator end + std::vector<cmGeneratorTarget*>::const_iterator end = cmRemoveDuplicates(objectLibraries); - for(std::vector<cmTarget*>::const_iterator + for(std::vector<cmGeneratorTarget*>::const_iterator ti = objectLibraries.begin(); ti != end; ++ti) { - cmTarget* objLib = *ti; - cmGeneratorTarget* ogt = - this->GlobalGenerator->GetGeneratorTarget(objLib); + cmGeneratorTarget* ogt = *ti; std::vector<cmSourceFile const*> objectSources; ogt->GetObjectSources(objectSources, config); for(std::vector<cmSourceFile const*>::const_iterator @@ -2121,9 +2140,9 @@ public: cmTargetTraceDependencies(cmGeneratorTarget* target); void Trace(); private: - cmTarget* Target; cmGeneratorTarget* GeneratorTarget; cmMakefile* Makefile; + cmLocalGenerator* LocalGenerator; cmGlobalGenerator const* GlobalGenerator; typedef cmGeneratorTarget::SourceEntry SourceEntry; SourceEntry* CurrentEntry; @@ -2147,11 +2166,12 @@ private: //---------------------------------------------------------------------------- cmTargetTraceDependencies ::cmTargetTraceDependencies(cmGeneratorTarget* target): - Target(target->Target), GeneratorTarget(target) + GeneratorTarget(target) { // Convenience. - this->Makefile = this->Target->GetMakefile(); - this->GlobalGenerator = target->GetLocalGenerator()->GetGlobalGenerator(); + this->Makefile = target->Target->GetMakefile(); + this->LocalGenerator = target->GetLocalGenerator(); + this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator(); this->CurrentEntry = 0; // Queue all the source files already specified for the target. @@ -2194,9 +2214,12 @@ cmTargetTraceDependencies } // Queue pre-build, pre-link, and post-build rule dependencies. - this->CheckCustomCommands(this->Target->GetPreBuildCommands()); - this->CheckCustomCommands(this->Target->GetPreLinkCommands()); - this->CheckCustomCommands(this->Target->GetPostBuildCommands()); + this->CheckCustomCommands( + this->GeneratorTarget->Target->GetPreBuildCommands()); + this->CheckCustomCommands( + this->GeneratorTarget->Target->GetPreLinkCommands()); + this->CheckCustomCommands( + this->GeneratorTarget->Target->GetPostBuildCommands()); } //---------------------------------------------------------------------------- @@ -2325,7 +2348,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep) tLocation = cmSystemTools::CollapseFullPath(tLocation); if(depLocation == tLocation) { - this->Target->AddUtility(util); + this->GeneratorTarget->Target->AddUtility(util); return true; } } @@ -2334,7 +2357,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep) { // The original name of the dependency was not a full path. It // must name a target, so add the target-level dependency. - this->Target->AddUtility(util); + this->GeneratorTarget->Target->AddUtility(util); return true; } } @@ -2360,7 +2383,8 @@ cmTargetTraceDependencies { std::string const& command = *cit->begin(); // Check for a target with this name. - if(cmTarget* t = this->Makefile->FindTargetToUse(command)) + if(cmGeneratorTarget* t = + this->LocalGenerator->FindGeneratorTargetToUse(command)) { if(t->GetType() == cmState::EXECUTABLE) { @@ -2368,7 +2392,7 @@ cmTargetTraceDependencies // this project. Add the target-level dependency to make // sure the executable is up to date before this custom // command possibly runs. - this->Target->AddUtility(command); + this->GeneratorTarget->Target->AddUtility(command); } } @@ -2387,7 +2411,7 @@ cmTargetTraceDependencies for(std::set<cmGeneratorTarget*>::iterator ti = targets.begin(); ti != targets.end(); ++ti) { - this->Target->AddUtility((*ti)->GetName()); + this->GeneratorTarget->Target->AddUtility((*ti)->GetName()); } // Queue the custom command dependencies. @@ -3029,7 +3053,7 @@ void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list, void cmGeneratorTarget::ComputeTargetManifest( const std::string& config) const { - if (this->Target->IsImported()) + if (this->IsImported()) { return; } @@ -3103,7 +3127,7 @@ void cmGeneratorTarget::ComputeTargetManifest( std::string cmGeneratorTarget::GetFullPath(const std::string& config, bool implib, bool realname) const { - if(this->Target->IsImported()) + if(this->IsImported()) { return this->Target->ImportedGetFullPath(config, implib); } @@ -3119,7 +3143,7 @@ std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config, { std::string fpath = this->GetDirectory(config, implib); fpath += "/"; - if(this->Target->IsAppBundleOnApple()) + if(this->IsAppBundleOnApple()) { fpath = this->BuildMacContentDirectory(fpath, config, false); fpath += "/"; @@ -3148,7 +3172,7 @@ cmGeneratorTarget::NormalGetRealName(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->Target->IsImported()) + if(this->IsImported()) { std::string msg = "NormalGetRealName called on imported target: "; msg += this->GetName(); @@ -3190,7 +3214,7 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name, // 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->Target->IsImported()) + if(this->IsImported()) { std::string msg = "GetLibraryNames called on imported target: "; msg += this->GetName(); @@ -3203,7 +3227,7 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name, const char* version = this->GetProperty("VERSION"); const char* soversion = this->GetProperty("SOVERSION"); if(!this->HasSOName(config) || - this->Target->IsFrameworkOnApple()) + this->IsFrameworkOnApple()) { // Versioning is supported only for shared libraries and modules, // and then only when the platform supports an soname flag. @@ -3231,7 +3255,7 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name, // The library name. name = prefix+base+suffix; - if(this->Target->IsFrameworkOnApple()) + if(this->IsFrameworkOnApple()) { realName = prefix; if(!this->Makefile->PlatformIsAppleIos()) @@ -3246,11 +3270,11 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name, else { // The library's soname. - this->Target->ComputeVersionedName(soName, prefix, base, suffix, + this->ComputeVersionedName(soName, prefix, base, suffix, name, soversion); // The library's real name on disk. - this->Target->ComputeVersionedName(realName, prefix, base, suffix, + this->ComputeVersionedName(realName, prefix, base, suffix, name, version); } @@ -3279,7 +3303,7 @@ void cmGeneratorTarget::GetExecutableNames(std::string& name, // 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->Target->IsImported()) + if(this->IsImported()) { std::string msg = "GetExecutableNames called on imported target: "; @@ -3343,6 +3367,24 @@ std::string cmGeneratorTarget::GetFullNameInternal(const std::string& config, } //---------------------------------------------------------------------------- +const char* +cmGeneratorTarget::ImportedGetLocation(const std::string& config) const +{ + static std::string location; + assert(this->IsImported()); + location = this->Target->ImportedGetFullPath(config, false); + return location.c_str(); +} + +//---------------------------------------------------------------------------- +std::string cmGeneratorTarget::GetFullNameImported(const std::string& config, + bool implib) const +{ + return cmSystemTools::GetFilenameName( + this->Target->ImportedGetFullPath(config, implib)); +} + +//---------------------------------------------------------------------------- void cmGeneratorTarget::GetFullNameInternal(const std::string& config, bool implib, std::string& outPrefix, @@ -3396,8 +3438,7 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config, configPostfix = this->GetProperty(configProp); // Mac application bundles and frameworks have no postfix. if(configPostfix && - (this->Target->IsAppBundleOnApple() - || this->Target->IsFrameworkOnApple())) + (this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) { configPostfix = 0; } @@ -3434,7 +3475,7 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config, // frameworks have directory prefix but no suffix std::string fw_prefix; - if(this->Target->IsFrameworkOnApple()) + if(this->IsFrameworkOnApple()) { fw_prefix = this->GetOutputName(config, false); fw_prefix += ".framework/"; @@ -3442,7 +3483,7 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config, targetSuffix = 0; } - if(this->Target->IsCFBundleOnApple()) + if(this->IsCFBundleOnApple()) { fw_prefix = this->GetCFBundleDirectory(config, false); fw_prefix += "/"; @@ -4377,6 +4418,61 @@ cmGeneratorTarget::GetLinkInformation(const std::string& config) const } //---------------------------------------------------------------------------- +void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const +{ + int patch; + this->GetTargetVersion(false, major, minor, patch); +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GetTargetVersion(bool soversion, + int& major, int& minor, int& patch) const +{ + // Set the default values. + major = 0; + minor = 0; + patch = 0; + + assert(this->GetType() != cmState::INTERFACE_LIBRARY); + + // Look for a VERSION or SOVERSION property. + const char* prop = soversion? "SOVERSION" : "VERSION"; + if(const char* version = this->GetProperty(prop)) + { + // Try to parse the version number and store the results that were + // successfully parsed. + int parsed_major; + int parsed_minor; + int parsed_patch; + switch(sscanf(version, "%d.%d.%d", + &parsed_major, &parsed_minor, &parsed_patch)) + { + case 3: patch = parsed_patch; // no break! + case 2: minor = parsed_minor; // no break! + case 1: major = parsed_major; // no break! + default: break; + } + } +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::ComputeVersionedName(std::string& vName, + std::string const& prefix, + std::string const& base, + std::string const& suffix, + std::string const& name, + const char* version) const +{ + vName = this->Makefile->IsOn("APPLE") ? (prefix+base) : name; + if(version) + { + vName += "."; + vName += version; + } + vName += this->Makefile->IsOn("APPLE") ? suffix : std::string(); +} + +//---------------------------------------------------------------------------- void cmGeneratorTarget::ReportPropertyOrigin(const std::string &p, const std::string &result, @@ -4423,7 +4519,7 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names, for(std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) { - std::string name = this->Target->CheckCMP0004(*i); + std::string name = this->CheckCMP0004(*i); if(name == this->GetName() || name.empty()) { continue; @@ -4658,7 +4754,7 @@ cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config, std::string cmGeneratorTarget::GetDirectory(const std::string& config, bool implib) const { - if (this->Target->IsImported()) + if (this->IsImported()) { // Return the directory from which the target is imported. return @@ -4782,7 +4878,7 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config, // Skip per-configuration subdirectory. conf = ""; } - else if(const char* outdir = this->Target->GetProperty(propertyName)) + else if(const char* outdir = this->GetProperty(propertyName)) { // Use the user-specified output directory. cmGeneratorExpression ge; @@ -4820,7 +4916,7 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config, // specified as a relative path. Treat a relative path as // relative to the current output directory for this makefile. out = (cmSystemTools::CollapseFullPath - (out, this->Makefile->GetCurrentBinaryDirectory())); + (out, this->LocalGenerator->GetCurrentBinaryDirectory())); // The generator may add the configuration's subdirectory. if(!conf.empty()) @@ -4885,7 +4981,7 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind, // specified as a relative path. Treat a relative path as // relative to the current output directory for this makefile. out = (cmSystemTools::CollapseFullPath - (out, this->Makefile->GetCurrentBinaryDirectory())); + (out, this->LocalGenerator->GetCurrentBinaryDirectory())); // The generator may add the configuration's subdirectory. if(!conf.empty()) @@ -5061,7 +5157,7 @@ cmGeneratorTarget::GetImportLinkInterface(const std::string& config, cmGeneratorTarget const* headTarget, bool usage_requirements_only) const { - cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config); + cmGeneratorTarget::ImportInfo const* info = this->GetImportInfo(config); if(!info) { return 0; @@ -5099,6 +5195,223 @@ cmGeneratorTarget::GetImportLinkInterface(const std::string& config, return &iface; } +//---------------------------------------------------------------------------- +cmGeneratorTarget::ImportInfo const* +cmGeneratorTarget::GetImportInfo(const std::string& config) const +{ + // There is no imported information for non-imported targets. + if(!this->IsImported()) + { + return 0; + } + + // Lookup/compute/cache the import information for this + // configuration. + std::string config_upper; + if(!config.empty()) + { + config_upper = cmSystemTools::UpperCase(config); + } + else + { + config_upper = "NOCONFIG"; + } + + ImportInfoMapType::const_iterator i = + this->ImportInfoMap.find(config_upper); + if(i == this->ImportInfoMap.end()) + { + ImportInfo info; + this->ComputeImportInfo(config_upper, info); + ImportInfoMapType::value_type entry(config_upper, info); + i = this->ImportInfoMap.insert(entry).first; + } + + if(this->GetType() == cmState::INTERFACE_LIBRARY) + { + return &i->second; + } + // If the location is empty then the target is not available for + // this configuration. + if(i->second.Location.empty() && i->second.ImportLibrary.empty()) + { + return 0; + } + + // Return the import information. + return &i->second; +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, + ImportInfo& info) const +{ + // This method finds information about an imported target from its + // properties. The "IMPORTED_" namespace is reserved for properties + // defined by the project exporting the target. + + // Initialize members. + info.NoSOName = false; + + const char* loc = 0; + const char* imp = 0; + std::string suffix; + if (!this->Target->GetMappedConfig(desired_config, &loc, &imp, suffix)) + { + return; + } + + // Get the link interface. + { + std::string linkProp = "INTERFACE_LINK_LIBRARIES"; + const char *propertyLibs = this->GetProperty(linkProp); + + if (this->GetType() != cmState::INTERFACE_LIBRARY) + { + if(!propertyLibs) + { + linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES"; + linkProp += suffix; + propertyLibs = this->GetProperty(linkProp); + } + + if(!propertyLibs) + { + linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES"; + propertyLibs = this->GetProperty(linkProp); + } + } + if(propertyLibs) + { + info.LibrariesProp = linkProp; + info.Libraries = propertyLibs; + } + } + if(this->GetType() == cmState::INTERFACE_LIBRARY) + { + return; + } + + // A provided configuration has been chosen. Load the + // configuration's properties. + + // Get the location. + if(loc) + { + info.Location = loc; + } + else + { + std::string impProp = "IMPORTED_LOCATION"; + impProp += suffix; + if(const char* config_location = this->GetProperty(impProp)) + { + info.Location = config_location; + } + else if(const char* location = this->GetProperty("IMPORTED_LOCATION")) + { + info.Location = location; + } + } + + // Get the soname. + if(this->GetType() == cmState::SHARED_LIBRARY) + { + std::string soProp = "IMPORTED_SONAME"; + soProp += suffix; + if(const char* config_soname = this->GetProperty(soProp)) + { + info.SOName = config_soname; + } + else if(const char* soname = this->GetProperty("IMPORTED_SONAME")) + { + info.SOName = soname; + } + } + + // Get the "no-soname" mark. + if(this->GetType() == cmState::SHARED_LIBRARY) + { + std::string soProp = "IMPORTED_NO_SONAME"; + soProp += suffix; + if(const char* config_no_soname = this->GetProperty(soProp)) + { + info.NoSOName = cmSystemTools::IsOn(config_no_soname); + } + else if(const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME")) + { + info.NoSOName = cmSystemTools::IsOn(no_soname); + } + } + + // Get the import library. + if(imp) + { + info.ImportLibrary = imp; + } + else if(this->GetType() == cmState::SHARED_LIBRARY || + this->Target->IsExecutableWithExports()) + { + std::string impProp = "IMPORTED_IMPLIB"; + impProp += suffix; + if(const char* config_implib = this->GetProperty(impProp)) + { + info.ImportLibrary = config_implib; + } + else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB")) + { + info.ImportLibrary = implib; + } + } + + // Get the link dependencies. + { + std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES"; + linkProp += suffix; + if(const char* config_libs = this->GetProperty(linkProp)) + { + info.SharedDeps = config_libs; + } + else if(const char* libs = + this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES")) + { + info.SharedDeps = libs; + } + } + + // Get the link languages. + if(this->Target->LinkLanguagePropagatesToDependents()) + { + std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES"; + linkProp += suffix; + if(const char* config_libs = this->GetProperty(linkProp)) + { + info.Languages = config_libs; + } + else if(const char* libs = + this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES")) + { + info.Languages = libs; + } + } + + // Get the cyclic repetition count. + if(this->GetType() == cmState::STATIC_LIBRARY) + { + std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; + linkProp += suffix; + if(const char* config_reps = this->GetProperty(linkProp)) + { + sscanf(config_reps, "%u", &info.Multiplicity); + } + else if(const char* reps = + this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY")) + { + sscanf(reps, "%u", &info.Multiplicity); + } + } +} + cmHeadToLinkInterfaceMap& cmGeneratorTarget::GetHeadToLinkInterfaceMap(const std::string &config) const { @@ -5119,7 +5432,7 @@ const cmLinkImplementation * cmGeneratorTarget::GetLinkImplementation(const std::string& config) const { // There is no link implementation for imported targets. - if(this->Target->IsImported()) + if(this->IsImported()) { return 0; } @@ -5197,6 +5510,105 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles( } //---------------------------------------------------------------------------- +void cmGeneratorTarget::GetObjectLibrariesCMP0026( + std::vector<cmGeneratorTarget*>& objlibs) const +{ + // At configure-time, this method can be called as part of getting the + // LOCATION property or to export() a file to be include()d. However + // there is no cmGeneratorTarget at configure-time, so search the SOURCES + // for TARGET_OBJECTS instead for backwards compatibility with OLD + // behavior of CMP0024 and CMP0026 only. + cmStringRange rng = this->Target->GetSourceEntries(); + for(std::vector<std::string>::const_iterator + i = rng.begin(); i != rng.end(); ++i) + { + std::string const& entry = *i; + + std::vector<std::string> files; + cmSystemTools::ExpandListArgument(entry, files); + for (std::vector<std::string>::const_iterator + li = files.begin(); li != files.end(); ++li) + { + if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") && + (*li)[li->size() - 1] == '>') + { + std::string objLibName = li->substr(17, li->size()-18); + + if (cmGeneratorExpression::Find(objLibName) != std::string::npos) + { + continue; + } + cmGeneratorTarget *objLib = + this->LocalGenerator->FindGeneratorTargetToUse(objLibName); + if(objLib) + { + objlibs.push_back(objLib); + } + } + } + } +} + +//---------------------------------------------------------------------------- +std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const +{ + // Strip whitespace off the library names because we used to do this + // in case variables were expanded at generate time. We no longer + // do the expansion but users link to libraries like " ${VAR} ". + std::string lib = item; + std::string::size_type pos = lib.find_first_not_of(" \t\r\n"); + if(pos != lib.npos) + { + lib = lib.substr(pos, lib.npos); + } + pos = lib.find_last_not_of(" \t\r\n"); + if(pos != lib.npos) + { + lib = lib.substr(0, pos+1); + } + if(lib != item) + { + cmake* cm = this->LocalGenerator->GetCMakeInstance(); + switch(this->Target->GetPolicyStatusCMP0004()) + { + case cmPolicies::WARN: + { + std::ostringstream w; + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0004) << "\n" + << "Target \"" << this->GetName() << "\" links to item \"" + << item << "\" which has leading or trailing whitespace."; + cm->IssueMessage(cmake::AUTHOR_WARNING, w.str(), + this->Target->GetBacktrace()); + } + case cmPolicies::OLD: + break; + case cmPolicies::NEW: + { + std::ostringstream e; + e << "Target \"" << this->GetName() << "\" links to item \"" + << item << "\" which has leading or trailing whitespace. " + << "This is now an error according to policy CMP0004."; + cm->IssueMessage(cmake::FATAL_ERROR, e.str(), + this->Target->GetBacktrace()); + } + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + { + std::ostringstream e; + e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0004) << "\n" + << "Target \"" << this->GetName() << "\" links to item \"" + << item << "\" which has leading or trailing whitespace."; + cm->IssueMessage(cmake::FATAL_ERROR, e.str(), + this->Target->GetBacktrace()); + } + break; + } + } + return lib; +} + +//---------------------------------------------------------------------------- void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages, const std::string& config) const { @@ -5216,14 +5628,13 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages, std::vector<cmSourceFile const*> externalObjects; if (!this->GlobalGenerator->GetConfigureDoneCMP0026()) { - std::vector<cmTarget*> objectTargets; - this->Target->GetObjectLibrariesCMP0026(objectTargets); + std::vector<cmGeneratorTarget*> objectTargets; + this->GetObjectLibrariesCMP0026(objectTargets); objectLibraries.reserve(objectTargets.size()); - for (std::vector<cmTarget*>::const_iterator it = objectTargets.begin(); - it != objectTargets.end(); ++it) + for (std::vector<cmGeneratorTarget*>::const_iterator it = + objectTargets.begin(); it != objectTargets.end(); ++it) { - objectLibraries.push_back(this->GlobalGenerator - ->GetGeneratorTarget(*it)); + objectLibraries.push_back(*it); } } else @@ -5233,10 +5644,10 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages, i = externalObjects.begin(); i != externalObjects.end(); ++i) { std::string objLib = (*i)->GetObjectLibrary(); - if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib)) + if (cmGeneratorTarget* tgt = + this->LocalGenerator->FindGeneratorTargetToUse(objLib)) { - objectLibraries.push_back(this->GlobalGenerator - ->GetGeneratorTarget(tgt)); + objectLibraries.push_back(tgt); } } } @@ -5358,7 +5769,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( li != llibs.end(); ++li) { // Skip entries that resolve to the target itself or are empty. - std::string name = this->Target->CheckCMP0004(*li); + std::string name = this->CheckCMP0004(*li); if(name == this->GetName() || name.empty()) { if(name == this->GetName()) @@ -5424,7 +5835,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( { if(li->second != GENERAL_LibraryType && li->second != linkType) { - std::string name = this->Target->CheckCMP0004(li->first); + std::string name = this->CheckCMP0004(li->first); if(name == this->GetName() || name.empty()) { continue; @@ -5440,13 +5851,14 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( cmGeneratorTarget* cmGeneratorTarget::FindTargetToLink(std::string const& name) const { - cmTarget const* tgt = this->Makefile->FindTargetToUse(name); + cmGeneratorTarget* tgt = + this->LocalGenerator->FindGeneratorTargetToUse(name); // Skip targets that will not really be linked. This is probably a // name conflict between an external library and an executable // within the project. if(tgt && tgt->GetType() == cmState::EXECUTABLE && - !tgt->IsExecutableWithExports()) + !tgt->Target->IsExecutableWithExports()) { tgt = 0; } @@ -5459,17 +5871,13 @@ cmGeneratorTarget::FindTargetToLink(std::string const& name) const "allowed. " "One may link only to STATIC or SHARED libraries, or to executables " "with the ENABLE_EXPORTS property set."; - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = this->LocalGenerator->GetCMakeInstance(); cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->Target->GetBacktrace()); tgt = 0; } - if (!tgt) - { - return 0; - } - return this->GlobalGenerator->GetGeneratorTarget(tgt); + return tgt; } //---------------------------------------------------------------------------- @@ -5516,7 +5924,7 @@ bool cmGeneratorTarget::HasImportLibrary() const //---------------------------------------------------------------------------- std::string cmGeneratorTarget::GetSupportDirectory() const { - std::string dir = this->Makefile->GetCurrentBinaryDirectory(); + std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory(); dir += cmake::GetCMakeFilesDirectory(); dir += "/"; dir += this->GetName(); @@ -5527,3 +5935,45 @@ std::string cmGeneratorTarget::GetSupportDirectory() const #endif return dir; } + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::IsLinkable() const +{ + return (this->GetType() == cmState::STATIC_LIBRARY || + this->GetType() == cmState::SHARED_LIBRARY || + this->GetType() == cmState::MODULE_LIBRARY || + this->GetType() == cmState::UNKNOWN_LIBRARY || + this->GetType() == cmState::INTERFACE_LIBRARY || + this->Target->IsExecutableWithExports()); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::IsFrameworkOnApple() const +{ + return (this->GetType() == cmState::SHARED_LIBRARY && + this->Makefile->IsOn("APPLE") && + this->GetPropertyAsBool("FRAMEWORK")); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::IsAppBundleOnApple() const +{ + return (this->GetType() == cmState::EXECUTABLE && + this->Makefile->IsOn("APPLE") && + this->GetPropertyAsBool("MACOSX_BUNDLE")); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::IsXCTestOnApple() const +{ + return (this->IsCFBundleOnApple() && + this->GetPropertyAsBool("XCTEST")); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::IsCFBundleOnApple() const +{ + return (this->GetType() == cmState::MODULE_LIBRARY && + this->Makefile->IsOn("APPLE") && + this->GetPropertyAsBool("BUNDLE")); +} |