Browse Source

BUG: Fix to build rule generation with relative paths.

Brad King 22 years ago
parent
commit
ed1c2573aa

+ 4 - 12
Source/cmLocalGenerator.cxx

@@ -183,8 +183,11 @@ std::string cmLocalGenerator::ConvertToRelativeOutputPath(const char* p)
     {
     ret = relpath;
     }
+
+  // Relative paths should always start in a '.', so add a './' if
+  // necessary.
   if(ret.size()
-     && ret[0] != '\"' && ret[0] != '/' && ret[0] != '.')
+     && ret[0] != '\"' && ret[0] != '/' && ret[0] != '.' && ret[0] != '$')
     {
     if(ret.size() > 1 && ret[1] != ':')
       {
@@ -192,16 +195,5 @@ std::string cmLocalGenerator::ConvertToRelativeOutputPath(const char* p)
       }
     }
   ret = cmSystemTools::ConvertToOutputPath(ret.c_str());
-  if(ret.size() > 2 &&
-     (ret[0] == '.') &&
-     ( (ret[1] == '/') || ret[1] == '\\'))
-    {
-    std::string upath = ret;
-    cmSystemTools::ConvertToUnixSlashes(upath);
-    if(upath.find(2, '/') == upath.npos)
-      {
-      ret = ret.substr(2, ret.size()-2);
-      }
-    }
   return ret;
 }

+ 30 - 10
Source/cmLocalUnixMakefileGenerator.cxx

@@ -1183,9 +1183,10 @@ void cmLocalUnixMakefileGenerator::OutputLibraryRule(std::ostream& fout,
                        depend.c_str(),
                        commands);
   depend = targetFullPath;
-  targetFullPath = this->ConvertToRelativeOutputPath(targetFullPath.c_str());
-  cmSystemTools::ConvertToUnixSlashes(targetFullPath);
-  if(targetFullPath.find('/', 0) != targetFullPath.npos)
+  std::string tgt = this->ConvertToRelativeOutputPath(targetFullPath.c_str());
+  tgt = this->ConvertToMakeTarget(tgt.c_str());
+  cmSystemTools::ConvertToUnixSlashes(tgt);
+  if(tgt.find('/', 0) != tgt.npos)
     {
     // we need a local target
     depend = this->ConvertToRelativeOutputPath(depend.c_str());
@@ -1339,7 +1340,8 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
   target = this->ConvertToRelativeOutputPath(target.c_str());
   cmSystemTools::ConvertToUnixSlashes(target);
   bool needsLocalTarget = false;
-  if(target.find('/', 0) != target.npos)
+  std::string tgt = this->ConvertToMakeTarget(target.c_str());
+  if(tgt.find('/', 0) != tgt.npos)
     {
     needsLocalTarget = true;
     }
@@ -1935,7 +1937,6 @@ BuildInSubDirectoryWindows(std::ostream& fout,
       }
     }
   fout << "\tcd " << this->ConvertToOutputForExisting(cdback.c_str()) << "\n\n";
-  
 }
 
 
@@ -2208,7 +2209,7 @@ void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
       command += " ";
       // now add the arguments
       command += c->GetArguments();
-      std::string depends;
+      std::vector<std::string> depends;
       // Collect out all the dependencies for this rule.
       for(std::vector<std::string>::const_iterator d =
             c->GetDepends().begin();
@@ -2236,16 +2237,15 @@ void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
         cmSystemTools::ReplaceString(dep, "/./", "/");
         cmSystemTools::ReplaceString(dep, "/$(IntDir)/", "/");
         dep = this->ConvertToRelativeOutputPath(dep.c_str());
-        depends += " ";
-        depends += dep;
-        } 
+        depends.push_back(dep.c_str());
+        }
       // output rule
       if (processedOutputs.find(c->GetOutput()) == processedOutputs.end())
         {
         this->OutputMakeRule(fout,
                              (comment.size()?comment.c_str():"Custom command"),
                              c->GetOutput().c_str(),
-                             depends.c_str(),
+                             depends,
                              command.c_str());
         processedOutputs.insert(c->GetOutput());
         }
@@ -3013,6 +3013,7 @@ void cmLocalUnixMakefileGenerator::OutputMakeRule(std::ostream& fout,
   m_Makefile->ExpandVariablesInString(replace);
   
   std::string tgt = this->ConvertToRelativeOutputPath(replace.c_str());
+  tgt = this->ConvertToMakeTarget(tgt.c_str());
   if(depends.empty())
     {
     fout << tgt.c_str() << ":\n";
@@ -3026,6 +3027,7 @@ void cmLocalUnixMakefileGenerator::OutputMakeRule(std::ostream& fout,
       {
       replace = *dep;
       m_Makefile->ExpandVariablesInString(replace);
+      replace = this->ConvertToMakeTarget(replace.c_str());
       fout << tgt.c_str() << ": " << replace.c_str() << "\n";
       }
     }
@@ -3212,3 +3214,21 @@ void cmLocalUnixMakefileGenerator::GetLibraryNames(const char* n,
   baseName = this->GetBaseTargetName(n, t);
 }
 
+std::string cmLocalUnixMakefileGenerator::ConvertToMakeTarget(const char* tgt)
+{
+  // Make targets should not have a leading './' for a file in the
+  // directory containing the makefile.
+  std::string ret = tgt;
+  if(ret.size() > 2 &&
+     (ret[0] == '.') &&
+     ( (ret[1] == '/') || ret[1] == '\\'))
+    {
+    std::string upath = ret;
+    cmSystemTools::ConvertToUnixSlashes(upath);
+    if(upath.find(2, '/') == upath.npos)
+      {
+      ret = ret.substr(2, ret.size()-2);
+      }
+    }
+  return ret;
+}

+ 6 - 1
Source/cmLocalUnixMakefileGenerator.h

@@ -197,6 +197,7 @@ protected:
                                       const char* path,
                                       const char* library,
                                       const char* fullpath);
+
   ///! return true if the two paths are the same
   virtual bool SamePath(const char* path1, const char* path2);
   virtual std::string GetOutputExtension(const char* sourceExtension);
@@ -213,7 +214,11 @@ protected:
 
   ///! for existing files convert to output path and short path if spaces
   std::string ConvertToOutputForExisting(const char*);
-  
+
+  /** Convert path to a format vaild for the left or right side of a
+      target: dependencies line in a makefile.  */
+  virtual std::string ConvertToMakeTarget(const char*);
+
   /** Get the full name of the target's file, without path.  */
   std::string GetFullTargetName(const char* n, const cmTarget& t);