From 0de8be8b49fd073d3746095e4e9ed96155a5edc1 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 27 Jul 2009 12:43:17 -0400 Subject: ENH: Link runtime libraries of all languages This adds implicit libraries and search directories for languages linked into a target other than the linker language to its link line. For example, when linking an executable containing both C++ and Fortran code the C++ linker is used but we need to add the Fortran libraries. The variables CMAKE__IMPLICIT_LINK_LIBRARIES CMAKE__IMPLICIT_LINK_DIRECTORIES contain the implicit libraries and directories for each language. Entries for the linker language are known to be implicit in the generated link line. Entries for other languages that do not appear in the known implicit set are listed explicitly at the end of the link line. --- Source/cmComputeLinkInformation.cxx | 69 +++++++++++++++++++++++++++++++++++++ Source/cmComputeLinkInformation.h | 3 ++ Source/cmOrderDirectories.cxx | 12 +++++++ Source/cmOrderDirectories.h | 2 ++ 4 files changed, 86 insertions(+) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index a824fe4..1dee2a2 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -552,6 +552,47 @@ bool cmComputeLinkInformation::Compute() return false; } + // Add implicit language runtime libraries and directories. + cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config); + for(std::vector::const_iterator li = lc->Languages.begin(); + li != lc->Languages.end(); ++li) + { + // Skip those of the linker language. They are implicit. + if(*li != this->LinkLanguage) + { + // Add libraries for this language that are not implied by the + // linker language. + std::string libVar = "CMAKE_"; + libVar += *li; + libVar += "_IMPLICIT_LINK_LIBRARIES"; + if(const char* libs = this->Makefile->GetDefinition(libVar.c_str())) + { + std::vector libsVec; + cmSystemTools::ExpandListArgument(libs, libsVec); + for(std::vector::const_iterator i = libsVec.begin(); + i != libsVec.end(); ++i) + { + if(this->ImplicitLinkLibs.find(*i) == this->ImplicitLinkLibs.end()) + { + this->AddItem(i->c_str(), 0); + } + } + } + + // Add linker search paths for this language that are not + // implied by the linker language. + std::string dirVar = "CMAKE_"; + dirVar += *li; + dirVar += "_IMPLICIT_LINK_DIRECTORIES"; + if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str())) + { + std::vector dirsVec; + cmSystemTools::ExpandListArgument(dirs, dirsVec); + this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec); + } + } + } + return true; } @@ -1551,12 +1592,40 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec); } + // Get language-specific implicit directories. + std::string implicitDirVar = "CMAKE_"; + implicitDirVar += this->LinkLanguage; + implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES"; + if(const char* implicitDirs = + this->Makefile->GetDefinition(implicitDirVar.c_str())) + { + cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec); + } + // Store implicit link directories. for(std::vector::const_iterator i = implicitDirVec.begin(); i != implicitDirVec.end(); ++i) { this->ImplicitLinkDirs.insert(*i); } + + // Get language-specific implicit libraries. + std::vector implicitLibVec; + std::string implicitLibVar = "CMAKE_"; + implicitLibVar += this->LinkLanguage; + implicitLibVar += "_IMPLICIT_LINK_LIBRARIES"; + if(const char* implicitLibs = + this->Makefile->GetDefinition(implicitLibVar.c_str())) + { + cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec); + } + + // Store implicit link libraries. + for(std::vector::const_iterator i = implicitLibVec.begin(); + i != implicitLibVec.end(); ++i) + { + this->ImplicitLinkLibs.insert(*i); + } } //---------------------------------------------------------------------------- diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index d7821c6..1fafc13 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -160,8 +160,11 @@ private: cmOrderDirectories* OrderLinkerSearchPath; bool FinishLinkerSearchDirectories(); void PrintLinkPolicyDiagnosis(std::ostream&); + + // Implicit link libraries and directories for linker language. void LoadImplicitLinkInfo(); std::set ImplicitLinkDirs; + std::set ImplicitLinkLibs; // Linker search path compatibility mode. std::set OldLinkDirMask; diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index f95c68a..fd5765d 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -372,6 +372,15 @@ cmOrderDirectories //---------------------------------------------------------------------------- void cmOrderDirectories +::AddLanguageDirectories(std::vector const& dirs) +{ + this->LanguageDirectories.insert(this->LanguageDirectories.end(), + dirs.begin(), dirs.end()); +} + +//---------------------------------------------------------------------------- +void +cmOrderDirectories ::SetImplicitDirectories(std::set const& implicitDirs) { this->ImplicitDirectories = implicitDirs; @@ -400,6 +409,9 @@ void cmOrderDirectories::CollectOriginalDirectories() { this->ConstraintEntries[i]->AddDirectory(); } + + // Add language runtime directories last. + this->AddOriginalDirectories(this->LanguageDirectories); } //---------------------------------------------------------------------------- diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index 6d05f93..8091a99 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -38,6 +38,7 @@ public: void AddRuntimeLibrary(std::string const& fullPath, const char* soname = 0); void AddLinkLibrary(std::string const& fullPath); void AddUserDirectories(std::vector const& extra); + void AddLanguageDirectories(std::vector const& dirs); void SetImplicitDirectories(std::set const& implicitDirs); void SetLinkExtensionInfo(std::vector const& linkExtensions, std::string const& removeExtRegex); @@ -56,6 +57,7 @@ private: std::vector ConstraintEntries; std::vector ImplicitDirEntries; std::vector UserDirectories; + std::vector LanguageDirectories; cmsys::RegularExpression RemoveLibraryExtension; std::vector LinkExtensions; std::set ImplicitDirectories; -- cgit v0.12