Browse Source

ENH: Improved computation of RelativePathTopSource and RelativePathTopBinary to use higher relative path tops when the source directories jump around in a tree below the original source top.

Brad King 18 years ago
parent
commit
4036627487
2 changed files with 37 additions and 31 deletions
  1. 35 31
      Source/cmLocalGenerator.cxx
  2. 2 0
      Source/cmLocalGenerator.h

+ 35 - 31
Source/cmLocalGenerator.cxx

@@ -2084,54 +2084,58 @@ std::string cmLocalGenerator::Convert(const char* source,
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-void cmLocalGenerator::ConfigureRelativePaths()
+std::string cmLocalGenerator::FindRelativePathTopSource()
 {
 {
-  // Find the highest parent source directory containing the local
-  // source directory.  This is the top of safe relative path
-  // conversion.
-  cmLocalGenerator* srcTop = this;
-  while(cmLocalGenerator* next = srcTop->GetParent())
+  // Relative path conversion within a single tree managed by CMake is
+  // safe.  We can use our parent relative path top if and only if
+  // this is a subdirectory of that top.
+  if(cmLocalGenerator* parent = this->GetParent())
     {
     {
+    std::string parentTop = parent->FindRelativePathTopSource();
     if(cmSystemTools::IsSubDirectory(
     if(cmSystemTools::IsSubDirectory(
-         this->Makefile->GetStartDirectory(),
-         next->Makefile->GetStartDirectory()))
+         this->Makefile->GetStartDirectory(), parentTop.c_str()))
       {
       {
-      srcTop = next;
-      }
-    else
-      {
-      break;
+      return parentTop;
       }
       }
     }
     }
 
 
-  // Relative path conversion inside the source tree is not used to
-  // construct relative paths passed to build tools so it is safe to
-  // even when the source is a network path.
-  std::string source = srcTop->Makefile->GetStartDirectory();
-  this->RelativePathTopSource = source;
+  // Otherwise this directory itself is the new top.
+  return this->Makefile->GetStartDirectory();
+}
 
 
-  // Find the highest parent binary directory containing the local
-  // binary directory.  This is the top of safe relative path
-  // conversion.
-  cmLocalGenerator* binTop = this;
-  while(cmLocalGenerator* next = binTop->GetParent())
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::FindRelativePathTopBinary()
+{
+  // Relative path conversion within a single tree managed by CMake is
+  // safe.  We can use our parent relative path top if and only if
+  // this is a subdirectory of that top.
+  if(cmLocalGenerator* parent = this->GetParent())
     {
     {
+    std::string parentTop = parent->FindRelativePathTopBinary();
     if(cmSystemTools::IsSubDirectory(
     if(cmSystemTools::IsSubDirectory(
-         this->Makefile->GetStartOutputDirectory(),
-         next->Makefile->GetStartOutputDirectory()))
-      {
-      binTop = next;
-      }
-    else
+         this->Makefile->GetStartOutputDirectory(), parentTop.c_str()))
       {
       {
-      break;
+      return parentTop;
       }
       }
     }
     }
 
 
+  // Otherwise this directory itself is the new top.
+  return this->Makefile->GetStartOutputDirectory();
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::ConfigureRelativePaths()
+{
+  // Relative path conversion inside the source tree is not used to
+  // construct relative paths passed to build tools so it is safe to
+  // even when the source is a network path.
+  std::string source = this->FindRelativePathTopSource();
+  this->RelativePathTopSource = source;
+
   // The current working directory on Windows cannot be a network
   // The current working directory on Windows cannot be a network
   // path.  Therefore relative paths cannot work when the binary tree
   // path.  Therefore relative paths cannot work when the binary tree
   // is a network path.
   // is a network path.
-  std::string binary = binTop->Makefile->GetStartOutputDirectory();
+  std::string binary = this->FindRelativePathTopBinary();
   if(binary.size() < 2 || binary.substr(0, 2) != "//")
   if(binary.size() < 2 || binary.substr(0, 2) != "//")
     {
     {
     this->RelativePathTopBinary = binary;
     this->RelativePathTopBinary = binary;

+ 2 - 0
Source/cmLocalGenerator.h

@@ -277,6 +277,8 @@ protected:
   std::string& CreateSafeUniqueObjectFileName(const char* sin);
   std::string& CreateSafeUniqueObjectFileName(const char* sin);
 
 
   void ConfigureRelativePaths();
   void ConfigureRelativePaths();
+  std::string FindRelativePathTopSource();
+  std::string FindRelativePathTopBinary();
 
 
   cmMakefile *Makefile;
   cmMakefile *Makefile;
   cmGlobalGenerator *GlobalGenerator;
   cmGlobalGenerator *GlobalGenerator;