diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index a824fe42d6..1dee2a2b3c 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 d7821c6060..1fafc13c31 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 f95c68a399..fd5765db42 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -369,6 +369,15 @@ cmOrderDirectories extra.begin(), extra.end()); } +//---------------------------------------------------------------------------- +void +cmOrderDirectories +::AddLanguageDirectories(std::vector const& dirs) +{ + this->LanguageDirectories.insert(this->LanguageDirectories.end(), + dirs.begin(), dirs.end()); +} + //---------------------------------------------------------------------------- void cmOrderDirectories @@ -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 6d05f93277..8091a99011 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;