From bc43b0f2a4dcecaaf653bb2d8b2bc13b4245f4d6 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 20 Oct 2009 16:38:37 -0400 Subject: [PATCH] Do not link library dependencies in VS solutions In VS 8 and greater this commit implements add_dependencies(myexe mylib) # depend without linking by adding the LinkLibraryDependencies="false" option to project files. Previously the above code would cause myexe to link to mylib in VS 8 and greater. This option prevents dependencies specified only in the solution from being linked. We already specify the real link library dependencies in the project files, and any project depending on this to link would not have worked in Makefile generators. We were already avoiding this problem in VS 7.1 and below by inserting intermediate mylib_UTILITY targets. It was more important for those versions because if a static library depended on another library the librarian would copy the dependees into the depender! This is no longer the case with VS 8 and above so we do not need that workaround. See issue #9732. --- Source/cmGlobalVisualStudio7Generator.h | 4 ++++ Source/cmGlobalVisualStudio8Generator.cxx | 23 ++++++++++++++++++++++ Source/cmGlobalVisualStudio8Generator.h | 4 ++++ Source/cmGlobalVisualStudioGenerator.h | 3 ++- Source/cmLocalVisualStudio7Generator.cxx | 10 ++++++++++ Source/cmVisualStudio10TargetGenerator.cxx | 7 +++++++ 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 363489ef9..85ba24495 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -92,6 +92,10 @@ public: ///! What is the configurations directory variable called? virtual const char* GetCMakeCFGInitDirectory() { return "$(OutDir)"; } + /** Return true if the target project file should have the option + LinkLibraryDependencies and link to .sln dependencies. */ + virtual bool NeedLinkLibraryDependencies(cmTarget&) { return false; } + protected: virtual const char* GetIDEVersion() { return "7.0"; } diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index e8b8782bb..8aec865b6 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -280,6 +280,29 @@ cmGlobalVisualStudio8Generator } } +//---------------------------------------------------------------------------- +bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies( + cmTarget& target) +{ + // Look for utility dependencies that magically link. + for(std::set::const_iterator ui = + target.GetUtilities().begin(); + ui != target.GetUtilities().end(); ++ui) + { + if(cmTarget* depTarget = this->FindTarget(0, ui->c_str())) + { + if(depTarget->GetProperty("EXTERNAL_MSPROJECT")) + { + // This utility dependency names an external .vcproj target. + // We use LinkLibraryDependencies="true" to link to it without + // predicting the .lib file location or name. + return true; + } + } + } + return false; +} + //---------------------------------------------------------------------------- static cmVS7FlagTable cmVS8ExtraFlagTable[] = { diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 55e2880e9..7370ef6f3 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -58,6 +58,10 @@ public: */ virtual std::string GetUserMacrosRegKeyBase(); + /** Return true if the target project file should have the option + LinkLibraryDependencies and link to .sln dependencies. */ + virtual bool NeedLinkLibraryDependencies(cmTarget& target); + protected: virtual const char* GetIDEVersion() { return "8.0"; } diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index d799485c8..0c7cf7fed 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -88,10 +88,11 @@ protected: virtual void GetTargetSets(TargetDependSet& projectTargets, TargetDependSet& originalTargets, cmLocalGenerator* root, GeneratorVector const&); + + bool CheckTargetLinks(cmTarget& target, const char* name); private: void FixUtilityDependsForTarget(cmTarget& target); void CreateUtilityDependTarget(cmTarget& target); - bool CheckTargetLinks(cmTarget& target, const char* name); }; #endif diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index fe91ff980..208480891 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -846,6 +846,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, cmTarget &target, bool isDebug) { + cmGlobalVisualStudio7Generator* gg = + static_cast(this->GlobalGenerator); std::string temp; std::string extraLinkOptions; if(target.GetType() == cmTarget::EXECUTABLE) @@ -949,6 +951,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } fout << "\t\t\tNeedLinkLibraryDependencies(target)) + { + fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n"; + } linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n"); // Use the NOINHERIT macro to avoid getting VS project default // libraries which may be set by the user to something bad. @@ -1021,6 +1027,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } fout << "\t\t\tNeedLinkLibraryDependencies(target)) + { + fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n"; + } linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n"); // Use the NOINHERIT macro to avoid getting VS project default // libraries which may be set by the user to something bad. diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index e7a8784f0..43a78ca0e 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1134,6 +1134,13 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& linkOptions.OutputFlagMap(*this->BuildFileStream, " "); this->WriteString("\n", 2); + if(!this->GlobalGenerator->NeedLinkLibraryDependencies(*this->Target)) + { + this->WriteString("\n", 2); + this->WriteString( + " false\n", 2); + this->WriteString("\n", 2); + } } void cmVisualStudio10TargetGenerator::AddLibraries(