[Cmake-commits] [cmake-commits] king committed cmComputeLinkInformation.cxx 1.24 1.25 cmComputeLinkInformation.h 1.15 1.16 cmDocumentVariables.cxx 1.18 1.19 cmPolicies.cxx 1.20 1.21 cmPolicies.h 1.10 1.11 cmTarget.cxx 1.207 1.208 cmTarget.h 1.109 1.110

cmake-commits at cmake.org cmake-commits at cmake.org
Thu Mar 13 16:23:20 EDT 2008


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv16290/Source

Modified Files:
	cmComputeLinkInformation.cxx cmComputeLinkInformation.h 
	cmDocumentVariables.cxx cmPolicies.cxx cmPolicies.h 
	cmTarget.cxx cmTarget.h 
Log Message:
ENH: Convert CMAKE_LINK_OLD_PATHS to policy CMP0003.

  - Policy is WARN by default so projects will build
    as they did in 2.4 without user intervention
  - Remove CMAKE_LINK_OLD_PATHS variable since it was
    never in a release and the policy supercedes it
  - Report target creation backtrace in warning message
    since policy should be set by that point


Index: cmPolicies.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -C 2 -d -r1.10 -r1.11
*** cmPolicies.h	13 Mar 2008 15:38:46 -0000	1.10
--- cmPolicies.h	13 Mar 2008 20:23:18 -0000	1.11
***************
*** 44,47 ****
--- 44,48 ----
      CMP0001, // Ignore old compatibility variable
      CMP0002, // Target names must be unique
+     CMP0003, // Linking does not include extra -L paths
  
      // Always the last entry.  Useful mostly to avoid adding a comma

Index: cmPolicies.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.cxx,v
retrieving revision 1.20
retrieving revision 1.21
diff -C 2 -d -r1.20 -r1.21
*** cmPolicies.cxx	13 Mar 2008 19:01:58 -0000	1.20
--- cmPolicies.cxx	13 Mar 2008 20:23:18 -0000	1.21
***************
*** 140,143 ****
--- 140,204 ----
      2,6,0, cmPolicies::WARN
      );
+ 
+   this->DefinePolicy(
+     CMP0003, "CMP0003",
+     "Libraries linked via full path no longer produce linker search paths.",
+     "This policy affects how libraries whose full paths are NOT known "
+     "are found at link time, but was created due to a change in how CMake "
+     "deals with libraries whose full paths are known.  "
+     "Consider the code\n"
+     "  target_link_libraries(myexe /path/to/libA.so)\n"
+     "CMake 2.4 and below implemented linking to libraries whose full paths "
+     "are known by splitting them on the link line into separate components "
+     "consisting of the linker search path and the library name.  "
+     "The example code might have produced something like\n"
+     "  ... -L/path/to -lA ...\n"
+     "in order to link to library A.  "
+     "An analysis was performed to order multiple link directories such that "
+     "the linker would find library A in the desired location, but there "
+     "are cases in which this does not work.  "
+     "CMake versions 2.6 and above use the more reliable approach of passing "
+     "the full path to libraries directly to the linker in most cases.  "
+     "The example code now produces something like\n"
+     "  ... /path/to/libA.so ....\n"
+     "Unfortunately this change can break code like\n"
+     "  target_link_libraries(myexe /path/to/libA.so B)\n"
+     "where \"B\" is meant to find \"/path/to/libB.so\".  "
+     "This code is wrong because the user is asking the linker to find "
+     "library B but has not provided a linker search path (which may be "
+     "added with the link_directories command).  "
+     "However, with the old linking implementation the code would work "
+     "accidentally because the linker search path added for library A "
+     "allowed library B to be found."
+     "\n"
+     "In order to support projects depending on linker search paths "
+     "added by linking to libraries with known full paths, the OLD "
+     "behavior for this policy will add the linker search paths even "
+     "though they are not needed for their own libraries.  "
+     "When this policy is set to OLD, CMake will produce a link line such as\n"
+     "  ... -L/path/to /path/to/libA.so -lB ...\n"
+     "which will allow library B to be found as it was previously.  "
+     "When this policy is set to NEW, CMake will produce a link line such as\n"
+     "  ... /path/to/libA.so -lB ...\n"
+     "which more accurately matches what the project specified."
+     "\n"
+     "The setting for this policy used when generating the link line is that "
+     "in effect when the target is created by an add_executable or "
+     "add_library command.  For the example described above, the code\n"
+     "  cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)\n"
+     "  add_executable(myexe myexe.c)\n"
+     "  target_link_libraries(myexe /path/to/libA.so B)\n"
+     "will work and suppress the warning for this policy.  "
+     "It may also be updated to work with the corrected linking approach:\n"
+     "  cmake_policy(SET CMP0003 NEW) # or cmake_policy(VERSION 2.6)\n"
+     "  link_directories(/path/to) # needed to find library B\n"
+     "  add_executable(myexe myexe.c)\n"
+     "  target_link_libraries(myexe /path/to/libA.so B)\n"
+     "Even better, library B may be specified with a full path:\n"
+     "  add_executable(myexe myexe.c)\n"
+     "  target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)\n"
+     "When all items on the link line have known paths CMake does not check "
+     "this policy so it has no effect.",
+     2,6,0, cmPolicies::WARN);
  }
  

Index: cmComputeLinkInformation.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmComputeLinkInformation.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -C 2 -d -r1.15 -r1.16
*** cmComputeLinkInformation.h	1 Mar 2008 17:51:07 -0000	1.15
--- cmComputeLinkInformation.h	13 Mar 2008 20:23:18 -0000	1.16
***************
*** 154,164 ****
    // Linker search path computation.
    cmOrderDirectories* OrderLinkerSearchPath;
!   void FinishLinkerSearchDirectories();
    std::set<cmStdString> ImplicitLinkDirs;
  
    // Linker search path compatibility mode.
    std::vector<std::string> OldLinkDirItems;
    bool OldLinkDirMode;
-   bool HaveUserFlagItem;
  
    // Runtime path computation.
--- 154,166 ----
    // Linker search path computation.
    cmOrderDirectories* OrderLinkerSearchPath;
!   bool FinishLinkerSearchDirectories();
!   void PrintLinkPolicyDiagnosis(std::ostream&);
    std::set<cmStdString> ImplicitLinkDirs;
  
    // Linker search path compatibility mode.
+   std::set<cmStdString> OldLinkDirMask;
    std::vector<std::string> OldLinkDirItems;
+   std::vector<std::string> OldUserFlagItems;
    bool OldLinkDirMode;
  
    // Runtime path computation.

Index: cmComputeLinkInformation.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmComputeLinkInformation.cxx,v
retrieving revision 1.24
retrieving revision 1.25
diff -C 2 -d -r1.24 -r1.25
*** cmComputeLinkInformation.cxx	2 Mar 2008 19:35:23 -0000	1.24
--- cmComputeLinkInformation.cxx	13 Mar 2008 20:23:18 -0000	1.25
***************
*** 397,403 ****
      }
  
-   // Initial state.
-   this->HaveUserFlagItem = false;
- 
    // Decide whether to enable compatible library search path mode.
    // There exists code that effectively does
--- 397,400 ----
***************
*** 411,420 ****
    // 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;
      }
  }
--- 408,423 ----
    // order to support such projects we need to add the directories
    // containing libraries linked with a full path to the -L path.
!   this->OldLinkDirMode =
!     this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
!   if(this->OldLinkDirMode)
      {
!     // Construct a mask to not bother with this behavior for link
!     // directories already specified by the user.
!     std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
!     for(std::vector<std::string>::const_iterator di = dirs.begin();
!         di != dirs.end(); ++di)
!       {
!       this->OldLinkDirMask.insert(*di);
!       }
      }
  }
***************
*** 538,542 ****
  
    // Finish setting up linker search directories.
!   this->FinishLinkerSearchDirectories();
  
    return true;
--- 541,548 ----
  
    // Finish setting up linker search directories.
!   if(!this->FinishLinkerSearchDirectories())
!     {
!     return false;
!     }
  
    return true;
***************
*** 1038,1042 ****
    // For compatibility with CMake 2.4 include the item's directory in
    // the linker search path.
!   if(this->OldLinkDirMode)
      {
      this->OldLinkDirItems.push_back(item);
--- 1044,1050 ----
    // For compatibility with CMake 2.4 include the item's directory in
    // the linker search path.
!   if(this->OldLinkDirMode &&
!      this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
!      this->OldLinkDirMask.end())
      {
      this->OldLinkDirItems.push_back(item);
***************
*** 1162,1166 ****
      {
      // This is a linker option provided by the user.
!     this->HaveUserFlagItem = true;
  
      // Restore the target link type since this item does not specify
--- 1170,1174 ----
      {
      // This is a linker option provided by the user.
!     this->OldUserFlagItems.push_back(item);
  
      // Restore the target link type since this item does not specify
***************
*** 1175,1179 ****
      {
      // This is a name specified by the user.
!     this->HaveUserFlagItem = true;
  
      // We must ask the linker to search for a library with this name.
--- 1183,1187 ----
      {
      // This is a name specified by the user.
!     this->OldUserFlagItems.push_back(item);
  
      // We must ask the linker to search for a library with this name.
***************
*** 1305,1320 ****
  
  //----------------------------------------------------------------------------
! void cmComputeLinkInformation::FinishLinkerSearchDirectories()
  {
    // Support broken projects if necessary.
!   if(this->HaveUserFlagItem && this->OldLinkDirMode)
      {
!     for(std::vector<std::string>::const_iterator
!           i = this->OldLinkDirItems.begin();
!         i != this->OldLinkDirItems.end(); ++i)
        {
!       this->OrderLinkerSearchPath->AddLinkLibrary(*i);
        }
      }
  }
  
--- 1313,1425 ----
  
  //----------------------------------------------------------------------------
! bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
  {
    // Support broken projects if necessary.
!   if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
!      !this->OldLinkDirMode)
      {
!     return true;
!     }
! 
!   // Enforce policy constraints.
!   switch(this->Target->GetPolicyStatusCMP0003())
!     {
!     case cmPolicies::WARN:
        {
!       cmOStringStream w;
!       w << (this->Makefile->GetPolicies()
!             ->GetPolicyWarning(cmPolicies::CMP0003)) << "\n";
!       this->PrintLinkPolicyDiagnosis(w);
!       this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
!                                         this->Target->GetBacktrace());
        }
+     case cmPolicies::OLD:
+       // OLD behavior is to add the paths containing libraries with
+       // known full paths as link directories.
+       break;
+     case cmPolicies::NEW:
+       // Should never happen due to assignment of OldLinkDirMode
+       return true;
+       break;
+     case cmPolicies::REQUIRED_IF_USED:
+     case cmPolicies::REQUIRED_ALWAYS:
+       {
+       cmOStringStream e;
+       e << (this->Makefile->GetPolicies()->
+             GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
+       this->PrintLinkPolicyDiagnosis(e);
+       this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
+                                         this->Target->GetBacktrace());
+       return false;
+       }
+       break;
+     }
+ 
+   // Add the link directories for full path items.
+   for(std::vector<std::string>::const_iterator
+         i = this->OldLinkDirItems.begin();
+       i != this->OldLinkDirItems.end(); ++i)
+     {
+     this->OrderLinkerSearchPath->AddLinkLibrary(*i);
+     }
+   return true;
+ }
+ 
+ //----------------------------------------------------------------------------
+ void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
+ {
+   // Name the target.
+   os << "Target \"" << this->Target->GetName() << "\" ";
+ 
+   // List the items that would add paths in old behavior.
+   os << " links to some items with known full path:\n";
+   for(std::vector<std::string>::const_iterator
+         i = this->OldLinkDirItems.begin();
+       i != this->OldLinkDirItems.end(); ++i)
+     {
+     os << "  " << *i << "\n";
+     }
+ 
+   // List the items that might need the old-style paths.
+   os << "and to some items with no path known:\n";
+   {
+   // Format the list of unknown items to be as short as possible while
+   // still fitting in the allowed width (a true solution would be the
+   // bin packing problem if we were allowed to change the order).
+   std::string::size_type max_size = 76;
+   std::string line;
+   const char* sep = "  ";
+   for(std::vector<std::string>::const_iterator
+         i = this->OldUserFlagItems.begin();
+       i != this->OldUserFlagItems.end(); ++i)
+     {
+     // If the addition of another item will exceed the limit then
+     // output the current line and reset it.  Note that the separator
+     // is either " " or ", " which is always 2 characters.
+     if(!line.empty() && (line.size() + i->size() + 2) > max_size)
+       {
+       os << line << "\n";
+       sep = "  ";
+       line = "";
+       }
+     line += sep;
+     line += *i;
+ 
+     // Convert to the other separator.
+     sep = ", ";
      }
+   if(!line.empty())
+     {
+     os << line << "\n";
+     }
+   }
+ 
+   // Tell the user what is wrong.
+   os << "The linker will search for libraries in the second list.  "
+      << "Finding them may depend on linker search paths earlier CMake "
+      << "versions added as an implementation detail for linking to the "
+      << "libraries in the first list.  "
+      << "For compatibility CMake is including the extra linker search "
+      << "paths, but policy CMP0003 should be set by the project.";
  }
  

Index: cmDocumentVariables.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDocumentVariables.cxx,v
retrieving revision 1.18
retrieving revision 1.19
diff -C 2 -d -r1.18 -r1.19
*** cmDocumentVariables.cxx	4 Mar 2008 14:40:38 -0000	1.18
--- cmDocumentVariables.cxx	13 Mar 2008 20:23:18 -0000	1.19
***************
*** 785,806 ****
       "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!).",
--- 785,788 ----

Index: cmTarget.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.h,v
retrieving revision 1.109
retrieving revision 1.110
diff -C 2 -d -r1.109 -r1.110
*** cmTarget.h	13 Mar 2008 17:48:57 -0000	1.109
--- cmTarget.h	13 Mar 2008 20:23:18 -0000	1.110
***************
*** 20,23 ****
--- 20,24 ----
  #include "cmCustomCommand.h"
  #include "cmPropertyMap.h"
+ #include "cmPolicies.h"
  
  class cmake;
***************
*** 106,109 ****
--- 107,114 ----
    cmMakefile *GetMakefile() const { return this->Makefile;};
  
+   /** Get the status of policy CMP0003 when the target was created.  */
+   cmPolicies::PolicyStatus GetPolicyStatusCMP0003() const
+     { return this->PolicyStatusCMP0003; }
+ 
    /**
     * Get the list of the custom commands for this target
***************
*** 531,534 ****
--- 536,542 ----
    cmMakefile* Makefile;
  
+   // Policy status recorded when target was created.
+   cmPolicies::PolicyStatus PolicyStatusCMP0003;
+ 
    // Internal representation details.
    friend class cmTargetInternals;

Index: cmTarget.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.cxx,v
retrieving revision 1.207
retrieving revision 1.208
diff -C 2 -d -r1.207 -r1.208
*** cmTarget.cxx	13 Mar 2008 17:48:57 -0000	1.207
--- cmTarget.cxx	13 Mar 2008 20:23:18 -0000	1.208
***************
*** 54,57 ****
--- 54,58 ----
  {
    this->Makefile = 0;
+   this->PolicyStatusCMP0003 = cmPolicies::WARN;
    this->LinkLibrariesAnalyzed = false;
    this->HaveInstallRule = false;
***************
*** 727,730 ****
--- 728,735 ----
    // Save the backtrace of target construction.
    this->Makefile->GetBacktrace(this->Internal->Backtrace);
+ 
+   // Record current policies for later use.
+   this->PolicyStatusCMP0003 =
+     this->Makefile->GetPolicyStatus(cmPolicies::CMP0003);
  }
  



More information about the Cmake-commits mailing list