From f27379e3f7291abd0c7f3706cd9e1202052c9889 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 23 Jan 2008 15:22:38 -0500 Subject: ENH: Added CMAKE_LINK_OLD_PATHS compatibility mode for linker search paths. --- Modules/VTKCompatibility.cmake | 5 ++++ Source/cmComputeLinkInformation.cxx | 49 +++++++++++++++++++++++++++++++++---- Source/cmComputeLinkInformation.h | 5 ++++ Source/cmDocumentVariables.cxx | 18 ++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/Modules/VTKCompatibility.cmake b/Modules/VTKCompatibility.cmake index 21d8aa0..8581f9a 100644 --- a/Modules/VTKCompatibility.cmake +++ b/Modules/VTKCompatibility.cmake @@ -31,6 +31,11 @@ SET(VTK_WGLEXT_FILE "${VTK_SOURCE_DIR}/Utilities/ParseOGLExt/headers/wglext.h" # work around an old bug in VTK SET(TIFF_RIGHT_VERSION 1) +# vtkRendering links to X11 with "-lXt ${X11_LIBRARIES}" because CMake +# 2.4 and below did not provide the X11_Xt_LIB variable. We need the +# linker search path compatiblity feature. +SET(CMAKE_LINK_OLD_PATHS 1) + # for very old VTK (versions prior to 4.2) MACRO(SOURCE_FILES) message (FATAL_ERROR "You are trying to build a very old version of VTK (prior to VTK 4.2). To do this you need to use CMake 2.0 as it was the last version of CMake to support VTK 4.0.") diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index a4d4c98..5414041 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -203,6 +203,26 @@ cmComputeLinkInformation // Initial state. this->RuntimeSearchPathComputed = false; + this->HaveUserFlagItem = false; + + // Decide whether to enable compatible library search path mode. + // There exists code that effectively does + // + // /path/to/libA.so -lB + // + // where -lB is meant to link to /path/to/libB.so. This is broken + // because it specified -lB without specifying a link directory (-L) + // in which to search for B. This worked in CMake 2.4 and below + // because -L/path/to would be added by the -L/-l split for A. In + // order to support such projects we need to add the directories + // containing libraries linked with a full path to the -L path. + this->OldLinkDirMode = false; + if(this->Makefile->IsOn("CMAKE_LINK_OLD_PATHS") || + this->Makefile->GetLocalGenerator() + ->NeedBackwardsCompatibility(2, 4)) + { + this->OldLinkDirMode = true; + } } //---------------------------------------------------------------------------- @@ -658,6 +678,13 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item) } } + // Record the directory in which the library appears because CMake + // 2.4 in below added these as -L paths. + if(this->OldLinkDirMode) + { + this->OldLinkDirs.push_back(cmSystemTools::GetFilenamePath(item)); + } + // If this platform wants a flag before the full path, add it. if(!this->LibLinkFileFlag.empty()) { @@ -738,8 +765,11 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item) } else if(item[0] == '-' || item[0] == '$' || item[0] == '`') { - // This is a linker option provided by the user. Restore the - // target link type since this item does not specify one. + // This is a linker option provided by the user. + this->HaveUserFlagItem = true; + + // Restore the target link type since this item does not specify + // one. this->SetCurrentLinkType(this->StartLinkType); // Use the item verbatim. @@ -748,9 +778,12 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item) } else { - // This is a name specified by the user. We must ask the linker - // to search for a library with this name. Restore the target - // link type since this item does not specify one. + // This is a name specified by the user. + this->HaveUserFlagItem = true; + + // We must ask the linker to search for a library with this name. + // Restore the target link type since this item does not specify + // one. this->SetCurrentLinkType(this->StartLinkType); lib = item; } @@ -872,6 +905,12 @@ void cmComputeLinkInformation::ComputeLinkerSearchDirectories() // Get the search path entries requested by the user. this->AddLinkerSearchDirectories(this->Target->GetLinkDirectories()); + + // Support broken projects if necessary. + if(this->HaveUserFlagItem && this->OldLinkDirMode) + { + this->AddLinkerSearchDirectories(this->OldLinkDirs); + } } //---------------------------------------------------------------------------- diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index f082e09..9f86c7d 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -121,6 +121,11 @@ private: void AddLinkerSearchDirectories(std::vector const& dirs); std::set DirectoriesEmmitted; + // Linker search path compatibility mode. + std::vector OldLinkDirs; + bool OldLinkDirMode; + bool HaveUserFlagItem; + // Runtime path computation. struct LibraryRuntimeEntry { diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 33b0a6e..4c33014 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -784,6 +784,24 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "This is needed only on very few platforms.", false, "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_LINK_OLD_PATHS", cmProperty::VARIABLE, + "Enable linker search path compatibility mode.", + "This option enables linking compatibility mode for broken projects. " + "There exists code that effectively does\n" + " target_link_libraries(myexe /path/to/libA.so -lB)\n" + "where -lB is meant to link to /path/to/libB.so. This is broken " + "because it specifies -lB without adding \"/path/to\" to the linker " + "search path with the link_directories command. With CMake 2.4 and " + "below the code worked accidentally because \"/path/to\" would be " + "added to the linker search path by its implementation of linking to " + "/path/to/libA.so (which passed -L/path/to -lA to the linker). " + "This option tells CMake to add the directories containing libraries " + "specified with a full path to the linker search path if the link " + "line contains any items like -lB. " + "The behavior is also enabled if CMAKE_BACKWARDS_COMPATIBILITY is " + "set to 2.4 or lower.", false, + "Variables that Control the Build"); + cm->DefineProperty ("CMAKE_USE_RELATIVE_PATHS", cmProperty::VARIABLE, "Use relative paths (May not work!).", "If this is set to TRUE, then the CMake will use " -- cgit v0.12