From 2bc22bdaacfc0f0f91c229685dc5dbadd0267601 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 7 Dec 2012 13:06:20 -0500 Subject: [PATCH 1/2] Xcode: Add frameworks search paths from link dependeny closure (#13397) The Xcode generator produces FRAMEWORK_SEARCH_PATHS from: (1) Include directories of the form /path/to/Foo.framework become -F/path/to so '#include ' can find H in the framework. (2) Linked frameworks of the form /path/to/Foo.framework become -F/path/to -framework Foo so the linker can find the framework. Originally commit 82bb6fae (add framework support to FIND_FILE, 2005-12-27) added these and used the (then current) old-style link dependency analysis results to get the frameworks. Later a second setting was added by commit 2ed6191f (add initial xcode framework stuff, 2007-05-08) to transform -F/path/to linker options produced by the old link line generation into entries appended to FRAMEWORK_SEARCH_PATHS. Then commit 96fd5909 (Implement linking with paths to library files, 2008-01-22) updated the second setting to directly use the results of full modern link dependency analysis, but forgot to remove the use of old-style link results from the original setting location. The two settings worked together for a while, with the second one appending to the first. Then commit f33a27ab (Generate native Xcode 3.0 and 3.1 projects, 2009-06-29) changed the internal representation format produced by the first setting but did not update the second setting to append to the new representation. As a result, if the first setting added any paths (usually via the old-style link analysis) then the second setting containing the modern link analysis results would not be applied at all. Fix this by removing use of the old-style link analysis results. Replace it using the modern link dependencies and remove the second setting altogether. Now all values for FRAMEWORK_SEARCH_PATHS are collected in one place so no special append logic is needed. --- Source/cmGlobalXCodeGenerator.cxx | 36 ++++++++++--------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 9bbeeaf6f..b2d325c8a 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1997,15 +1997,20 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, dirs.Add(incpath.c_str()); } } - std::vector& frameworks = target.GetFrameworks(); - if(frameworks.size()) + if(target.GetType() != cmTarget::OBJECT_LIBRARY && + target.GetType() != cmTarget::STATIC_LIBRARY) { - for(std::vector::iterator fmIt = frameworks.begin(); - fmIt != frameworks.end(); ++fmIt) + // Add framework search paths needed for linking. + if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName)) { - if(emitted.insert(*fmIt).second) + std::vector const& fwDirs = cli->GetFrameworkPaths(); + for(std::vector::const_iterator fdi = fwDirs.begin(); + fdi != fwDirs.end(); ++fdi) { - fdirs.Add(this->XCodeEscapePath(fmIt->c_str()).c_str()); + if(emitted.insert(*fdi).second) + { + fdirs.Add(this->XCodeEscapePath(fdi->c_str()).c_str()); + } } } } @@ -2691,25 +2696,6 @@ void cmGlobalXCodeGenerator linkDirs.c_str(), configName); } - // add the framework search paths - { - const char* sep = ""; - std::string fdirs; - std::vector const& fwDirs = cli.GetFrameworkPaths(); - for(std::vector::const_iterator fdi = fwDirs.begin(); - fdi != fwDirs.end(); ++fdi) - { - fdirs += sep; - sep = " "; - fdirs += this->XCodeEscapePath(fdi->c_str()); - } - if(!fdirs.empty()) - { - this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS", - fdirs.c_str(), configName); - } - } - // now add the link libraries { std::string linkLibs; From f0d938549eead63fb86bec28c299a1bceacbdd6b Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 7 Dec 2012 13:27:52 -0500 Subject: [PATCH 2/2] Makefile: Use modern link information for framework search paths Use cmComputeLinkInformation::GetFrameworkPaths to get the list of framework paths needed by the linker. Drop the now unused framework information from the old-style cmTarget link dependency analysis. --- Source/cmMakefileTargetGenerator.cxx | 26 +++++++++++++++----------- Source/cmTarget.cxx | 21 --------------------- Source/cmTarget.h | 5 ----- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 2b89c794b..9bf6b7d9e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1550,10 +1550,10 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget, "C", config); - std::vector::iterator i; // check all include directories for frameworks as this // will already have added a -F for the framework - for(i = includes.begin(); i != includes.end(); ++i) + for(std::vector::iterator i = includes.begin(); + i != includes.end(); ++i) { if(this->Target->NameResolvesToFramework(i->c_str())) { @@ -1565,17 +1565,21 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() } std::string flags; - std::vector& frameworks = this->Target->GetFrameworks(); - for(i = frameworks.begin(); - i != frameworks.end(); ++i) + const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); + if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) { - if(emitted.insert(*i).second) + std::vector const& frameworks = cli->GetFrameworkPaths(); + for(std::vector::const_iterator i = frameworks.begin(); + i != frameworks.end(); ++i) { - flags += "-F"; - flags += this->Convert(i->c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL, true); - flags += " "; + if(emitted.insert(*i).second) + { + flags += "-F"; + flags += this->Convert(i->c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL, true); + flags += " "; + } } } return flags; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index be20464da..de3b23c78 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2092,26 +2092,6 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname) NameResolvesToFramework(libname); } -//---------------------------------------------------------------------------- -bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType) -{ - if(this->NameResolvesToFramework(libname.c_str())) - { - std::string frameworkDir = libname; - frameworkDir += "/../"; - frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str()); - std::vector::iterator i = - std::find(this->Frameworks.begin(), - this->Frameworks.end(), frameworkDir); - if(i == this->Frameworks.end()) - { - this->Frameworks.push_back(frameworkDir); - } - return true; - } - return false; -} - //---------------------------------------------------------------------------- void cmTarget::AddLinkLibrary(cmMakefile& mf, const char *target, const char* lib, @@ -2122,7 +2102,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, { return; } - this->AddFramework(lib, llt); cmTarget::LibraryID tmp; tmp.first = lib; tmp.second = llt; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 9efd638f8..0dfbc68a1 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -109,9 +109,6 @@ public: std::vector &GetPostBuildCommands() {return this->PostBuildCommands;} - ///! Return the list of frameworks being linked to this target - std::vector &GetFrameworks() {return this->Frameworks;} - /** * Get the list of the source files used by this target */ @@ -179,7 +176,6 @@ public: // Check to see if a library is a framework and treat it different on Mac bool NameResolvesToFramework(const std::string& libname); - bool AddFramework(const std::string& lib, LinkLibraryType llt); void AddLinkLibrary(cmMakefile& mf, const char *target, const char* lib, LinkLibraryType llt); @@ -569,7 +565,6 @@ private: LinkLibraryVectorType LinkLibraries; LinkLibraryVectorType PrevLinkedLibraries; bool LinkLibrariesAnalyzed; - std::vector Frameworks; std::vector LinkDirectories; std::set LinkDirectoriesEmmitted; bool HaveInstallRule;