Browse Source

NMake with spaces in directories

Bill Hoffman 24 years ago
parent
commit
12551a33c3

+ 11 - 29
Source/cmCacheManager.cxx

@@ -248,39 +248,21 @@ bool cmCacheManager::LoadCache(const char* path,
     {
     std::string currentcwd = path;
     std::string oldcwd = this->GetCacheValue("CMAKE_CACHEFILE_DIR");
-#if defined(_WIN32) || defined(__CYGWIN__)
-    currentcwd = cmSystemTools::LowerCase(currentcwd);
-    oldcwd = cmSystemTools::LowerCase(oldcwd);
-#endif // _WIN32
     cmSystemTools::ConvertToUnixSlashes(currentcwd);
-    if(cmSystemTools::CollapseFullPath(oldcwd.c_str()) 
-       != cmSystemTools::CollapseFullPath(currentcwd.c_str()))
+    currentcwd += "/CMakeCache.txt";
+    oldcwd += "/CMakeCache.txt";
+    if(!cmSystemTools::SameFile(oldcwd.c_str(), currentcwd.c_str()))
       { 
-#if defined(_WIN32) || defined(__CYGWIN__)
-      char filename1[1024];
-      char filename2[1024];
-      GetShortPathName(cmSystemTools::CollapseFullPath(oldcwd.c_str()).c_str(),
-		       filename1, 1023);
-      GetShortPathName(cmSystemTools::CollapseFullPath(currentcwd.c_str()).c_str(),
-		       filename2, 1023);
-      if ( std::string(filename1) != std::string(filename2) )
-	{
-#endif // _WIN32
-	std::string message = 
-	  std::string("The current CMakeCache.txt directory ") +
-	  currentcwd + std::string(" is different than the directory ") + 
-	  std::string(this->GetCacheValue("CMAKE_CACHEFILE_DIR")) +
-	  std::string(" where CMackeCache.txt was created. This may result "
-		      "in binaries being created in the wrong place. If you "
-		      "are not sure, reedit the CMakeCache.txt");
-	cmSystemTools::Error(message.c_str());   
-#if defined(_WIN32) || defined(__CYGWIN__)
-	}
-#endif // _WIN32
+      std::string message = 
+        std::string("The current CMakeCache.txt directory ") +
+        currentcwd + std::string(" is different than the directory ") + 
+        std::string(this->GetCacheValue("CMAKE_CACHEFILE_DIR")) +
+        std::string(" where CMackeCache.txt was created. This may result "
+                    "in binaries being created in the wrong place. If you "
+                    "are not sure, reedit the CMakeCache.txt");
+      cmSystemTools::Error(message.c_str());   
       }
     }
-  
-
   return true;
 }
 

+ 1 - 1
Source/cmDSPWriter.cxx

@@ -170,7 +170,7 @@ void cmDSPWriter::AddDSPBuildRule(cmSourceGroup& sourceGroup)
   m_Makefile->ExpandVariablesInString(dsprule);
   dsprule = cmSystemTools::HandleNetworkPaths(dsprule.c_str());
   std::string args = makefileIn;
-  args += " -DSP -H\"";
+  args += " -H\"";
   args += cmSystemTools::HandleNetworkPaths(m_Makefile->GetHomeDirectory());
   args += "\" -S\"";
   args += cmSystemTools::HandleNetworkPaths(m_Makefile->GetStartDirectory());

+ 54 - 17
Source/cmNMakeMakefileGenerator.cxx

@@ -46,6 +46,34 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "cmMakeDepend.h"
 #include "cmCacheManager.h"
 #include "cmGeneratedFileStream.h"
+#include "windows.h"
+
+inline std::string ShortPath(const char* path)
+{
+  std::string ret = path;
+  // if there are no spaces in path, then just return path
+  if(ret.find(' ') == std::string::npos)
+    {
+    return ret;
+    }
+    
+  // if there are spaces then call GetShortPathName to get rid of them
+  char *buffer = new char[strlen(path)+1];
+  if(GetShortPathName(path, buffer, 
+                      strlen(path)+1) != 0)
+    {
+    ret = buffer;
+    }
+  else
+    {
+    // if GetShortPathName failed for some reason use
+    // EscapeSpaces instead
+    ret = cmSystemTools::EscapeSpaces(path);
+    }
+  delete [] buffer;
+  return ret;
+}
+
 
 cmNMakeMakefileGenerator::cmNMakeMakefileGenerator()
 {
@@ -76,6 +104,8 @@ void cmNMakeMakefileGenerator::ComputeSystemInfo()
   m_Makefile->ReadListFile(NULL,fpath.c_str());
 }
 
+
+  
 void cmNMakeMakefileGenerator::OutputMakeVariables(std::ostream& fout)
 {
   fout << "# NMake Makefile generated by cmake\n";
@@ -98,16 +128,16 @@ void cmNMakeMakefileGenerator::OutputMakeVariables(std::ostream& fout)
   std::string replaceVars = variables;
   m_Makefile->ExpandVariablesInString(replaceVars);
   fout << replaceVars.c_str();
-  fout << "CMAKE_CURRENT_SOURCE = " << 
-    cmSystemTools::EscapeSpaces(m_Makefile->GetStartDirectory() )
-        << "\n";
+  fout << "CMAKE_CURRENT_SOURCE = " 
+       << ShortPath(m_Makefile->GetStartDirectory() )
+       << "\n";
   fout << "CMAKE_CURRENT_BINARY = " 
-       << cmSystemTools::EscapeSpaces(m_Makefile->GetStartOutputDirectory())
+       << ShortPath(m_Makefile->GetStartOutputDirectory())
        << "\n";
-  fout << "CMAKE_SOURCE_DIR = " << 
-    cmSystemTools::EscapeSpaces(m_Makefile->GetHomeDirectory()) << "\n";
-  fout << "CMAKE_BINARY_DIR = " << 
-    cmSystemTools::EscapeSpaces(m_Makefile->GetHomeOutputDirectory() )
+  fout << "CMAKE_SOURCE_DIR = " 
+       << ShortPath(m_Makefile->GetHomeDirectory()) << "\n";
+  fout << "CMAKE_BINARY_DIR = " 
+       << ShortPath(m_Makefile->GetHomeOutputDirectory() )
        << "\n";
   // Output Include paths
   fout << "INCLUDE_FLAGS = ";
@@ -139,7 +169,8 @@ void cmNMakeMakefileGenerator::BuildInSubDirectory(std::ostream& fout,
     {
     std::string dir = directory;
     cmSystemTools::ConvertToWindowsSlashes(dir);
-    fout << "\tif not exist " << dir.c_str() << " " 
+    fout << "\tif not exist " << cmSystemTools::EscapeSpaces(dir.c_str())
+         << " " 
          << "$(MAKE) rebuild_cache\n"
          << "\tcd .\\" << directory << "\n"
          << "\t$(MAKE) -$(MAKEFLAGS) " << target1 << "\n";
@@ -150,7 +181,7 @@ void cmNMakeMakefileGenerator::BuildInSubDirectory(std::ostream& fout,
     }
   std::string currentDir = m_Makefile->GetCurrentOutputDirectory();
   cmSystemTools::ConvertToWindowsSlashes(currentDir);
-  fout << "\tcd " << currentDir.c_str() << "\n";
+  fout << "\tcd " << cmSystemTools::EscapeSpaces(currentDir.c_str()) << "\n";
 }
 
 // This needs to be overriden because nmake requires commands to be quoted
@@ -256,7 +287,8 @@ OutputBuildObjectFromSource(std::ostream& fout,
       compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
       }
     compileCommand += "$(INCLUDE_FLAGS) -c ";
-    compileCommand += source.GetFullPath();
+    compileCommand += 
+      cmSystemTools::EscapeSpaces(source.GetFullPath().c_str());
     compileCommand += " /Fo";
     compileCommand += objectFile;
     }
@@ -265,7 +297,8 @@ OutputBuildObjectFromSource(std::ostream& fout,
     compileCommand = "$(RC) /fo\"";
     compileCommand += objectFile;
     compileCommand += "\" ";
-    compileCommand += source.GetFullPath();
+    compileCommand += 
+      cmSystemTools::EscapeSpaces(source.GetFullPath().c_str());
     }
   else if (ext == "def")
     {
@@ -282,7 +315,8 @@ OutputBuildObjectFromSource(std::ostream& fout,
       compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
       }
     compileCommand += "$(INCLUDE_FLAGS) -c ";
-    compileCommand += source.GetFullPath();
+    compileCommand += 
+      cmSystemTools::EscapeSpaces(source.GetFullPath().c_str());
     compileCommand += " /Fo";
     compileCommand += objectFile;
     }
@@ -290,7 +324,8 @@ OutputBuildObjectFromSource(std::ostream& fout,
   this->OutputMakeRule(fout,
                        comment.c_str(),
                        objectFile.c_str(),
-                       source.GetFullPath().c_str(),
+                       cmSystemTools::EscapeSpaces(
+                         source.GetFullPath().c_str()).c_str(),
                        compileCommand.c_str());
 }
 
@@ -369,8 +404,10 @@ void cmNMakeMakefileGenerator::OutputExecutableRule(std::ostream& fout,
   std::string command = 
     "$(CMAKE_CXX_COMPILER) $(CMAKE_CXXFLAGS) ";
   command += "$(" + std::string(name) + "_SRC_OBJS) ";
-  command += " /Fe" + m_ExecutableOutputPath + name;
-  command += ".exe /link ";
+  std::string path = m_ExecutableOutputPath + name + ".exe";
+  command += " /Fe" + 
+    cmSystemTools::EscapeSpaces(path.c_str());
+  command += " /link ";
   if(t.GetType() == cmTarget::WIN32_EXECUTABLE)
     {
     command +=  " /subsystem:windows ";
@@ -405,7 +442,7 @@ void cmNMakeMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
   for(std::vector<std::string>::iterator libDir = libdirs.begin();
       libDir != libdirs.end(); ++libDir)
     { 
-    std::string libpath = cmSystemTools::EscapeSpaces(libDir->c_str());
+    std::string libpath = ShortPath(libDir->c_str());
     if(emitted.insert(libpath).second)
       {
       linkLibs += "-LIBPATH:";

+ 19 - 0
Source/cmSystemTools.cxx

@@ -397,6 +397,25 @@ std::string cmSystemTools::EscapeQuotes(const char* str)
   return result;
 }
 
+bool cmSystemTools::SameFile(const char* file1, const char* file2)
+{
+  struct stat fileStat1, fileStat2;
+  if (stat(file1, &fileStat1) == 0 && stat(file2, &fileStat2) == 0)
+    {
+    // see if the files are the same file
+    // check the device inode and size
+    if(fileStat2.st_dev == fileStat1.st_dev && 
+       fileStat2.st_ino == fileStat1.st_ino &&
+       fileStat2.st_size == fileStat1.st_size 
+      ) 
+      {
+      return true;
+      }
+    }
+  return false;
+}
+
+
 // return true if the file exists
 bool cmSystemTools::FileExists(const char* filename)
 {

+ 3 - 0
Source/cmSystemTools.h

@@ -204,6 +204,9 @@ public:
   ///! Compare the contents of two files.  Return true if different.
   static bool FilesDiffer(const char* source,
                           const char* destination);
+  ///! return true if the two files are the same file
+  static bool SameFile(const char* file1, const char* file2);
+
   ///! Copy a file.
   static void cmCopyFile(const char* source,
                        const char* destination);

+ 50 - 35
Source/cmUnixMakefileGenerator.cxx

@@ -235,11 +235,13 @@ void cmUnixMakefileGenerator::OutputMakefile(const char* file)
   for(std::vector<std::string>::const_iterator i = lfiles.begin();
       i !=  lfiles.end(); ++i)
     {
-    fout << " " << i->c_str();
+    fout << " " << cmSystemTools::EscapeSpaces(i->c_str());
     }
   // Add the cache to the list
-  fout << " " << m_Makefile->GetHomeOutputDirectory() << "/CMakeCache.txt\n";
-  fout << "\n\n";
+  std::string cacheFile = m_Makefile->GetHomeOutputDirectory();
+  cacheFile += "/CMakeCache.txt";
+  fout << " " << cmSystemTools::EscapeSpaces(cacheFile.c_str());
+  fout << "\n\n\n";
   this->OutputMakeVariables(fout);
   // Set up the default target as the VERY first target, so that make with no arguments will run it
   this->OutputMakeRule(fout, 
@@ -302,23 +304,26 @@ void cmUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
     {
     if (l->second.IsInAll())
       {
+      std::string path = m_LibraryOutputPath + m_LibraryPrefix;
       if(l->second.GetType() == cmTarget::STATIC_LIBRARY)
         {
-        fout << " \\\n" << m_LibraryOutputPath << m_LibraryPrefix
-             << l->first.c_str()
-             << m_StaticLibraryExtension;
+        path = path + l->first + m_StaticLibraryExtension;
+        fout << " \\\n" 
+             << cmSystemTools::EscapeSpaces(path.c_str());
         }
       else if(l->second.GetType() == cmTarget::SHARED_LIBRARY)
         {
-        fout << " \\\n" << m_LibraryOutputPath << m_LibraryPrefix
-             << l->first.c_str()
-             << m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
+        path = path + l->first + 
+          m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
+        fout << " \\\n" 
+             << cmSystemTools::EscapeSpaces(path.c_str());
         }
       else if(l->second.GetType() == cmTarget::MODULE_LIBRARY)
         {
-        fout << " \\\n" << m_LibraryOutputPath <<  m_LibraryPrefix 
-             << l->first.c_str()
-             << m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
+        path = path + l->first + 
+          m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
+        fout << " \\\n" 
+             << cmSystemTools::EscapeSpaces(path.c_str());
         }
       }
     }
@@ -330,8 +335,9 @@ void cmUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
          l->second.GetType() == cmTarget::WIN32_EXECUTABLE) &&
         l->second.IsInAll())
       {
-      fout << " \\\n" << m_ExecutableOutputPath << l->first.c_str() 
-           << m_ExecutableExtension;
+      std::string path = m_ExecutableOutputPath + l->first +
+        m_ExecutableExtension;
+      fout << " \\\n" << cmSystemTools::EscapeSpaces(path.c_str());
       }
     }
   // list utilities last
@@ -759,7 +765,7 @@ void cmUnixMakefileGenerator::OutputDependLibs(std::ostream& fout)
     if(cacheValue 
        && (strcmp(m_Makefile->GetCurrentOutputDirectory(), cacheValue) != 0))
       {
-      std::string library = "lib";
+      std::string library = m_LibraryPrefix;
       library += *lib;
       std::string libpath = cacheValue;
       // add the correct extension
@@ -776,7 +782,7 @@ void cmUnixMakefileGenerator::OutputDependLibs(std::ostream& fout)
 	}
       else
         {
-        library += ".a";
+        library += m_StaticLibraryExtension;
         }
       if(m_LibraryOutputPath.size())
         {
@@ -788,8 +794,8 @@ void cmUnixMakefileGenerator::OutputDependLibs(std::ostream& fout)
         }
       libpath += library;
       // put out a rule to build the library if it does not exist
-      fout << libpath.c_str()
-           << ":\n\tcd " << cacheValue 
+      fout << cmSystemTools::EscapeSpaces(libpath.c_str())
+           << ":\n\tcd " << cmSystemTools::EscapeSpaces(cacheValue)
            << "; $(MAKE) " << m_LibraryOutputPath << library.c_str() << "\n\n";
       }
     }
@@ -844,7 +850,7 @@ void cmUnixMakefileGenerator::OutputLibDepend(std::ostream& fout,
       {
       libpath += m_StaticLibraryExtension;
       }
-    fout << libpath << " ";
+    fout << cmSystemTools::EscapeSpaces(libpath.c_str()) << " ";
     }
 }
 
@@ -873,10 +879,11 @@ inline std::string FixDirectoryName(const char* dir)
 
 
 void cmUnixMakefileGenerator::BuildInSubDirectory(std::ostream& fout,
-                                                  const char* directory,
+                                                  const char* dir,
                                                   const char* target1,
                                                   const char* target2)
 {
+  std::string directory = cmSystemTools::EscapeSpaces(dir);
   if(target1)
     {
     fout << "\t@if test ! -d " << directory 
@@ -1187,15 +1194,20 @@ void cmUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout)
   
   m_Makefile->ExpandVariablesInString(replaceVars);
   fout << replaceVars.c_str();
-  fout << "CMAKE_CURRENT_SOURCE = " << m_Makefile->GetStartDirectory() << "\n";
-  fout << "CMAKE_CURRENT_BINARY = " << m_Makefile->GetStartOutputDirectory() << "\n";
-  fout << "CMAKE_SOURCE_DIR = " << m_Makefile->GetHomeDirectory() << "\n";
-  fout << "CMAKE_BINARY_DIR = " << m_Makefile->GetHomeOutputDirectory() << "\n";
+  fout << "CMAKE_CURRENT_SOURCE = " << 
+    cmSystemTools::EscapeSpaces(m_Makefile->GetStartDirectory()) << "\n";
+  fout << "CMAKE_CURRENT_BINARY = " << 
+    cmSystemTools::EscapeSpaces(m_Makefile->GetStartOutputDirectory()) << "\n";
+  fout << "CMAKE_SOURCE_DIR = " << 
+    cmSystemTools::EscapeSpaces(m_Makefile->GetHomeDirectory()) << "\n";
+  fout << "CMAKE_BINARY_DIR = " << 
+    cmSystemTools::EscapeSpaces(m_Makefile->GetHomeOutputDirectory()) << "\n";
   // Output Include paths
   fout << "INCLUDE_FLAGS = ";
   std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
   std::vector<std::string>::iterator i;
-  fout << "-I" << m_Makefile->GetStartDirectory() << " ";
+  fout << "-I" << 
+    cmSystemTools::EscapeSpaces(m_Makefile->GetStartDirectory()) << " ";
   for(i = includes.begin(); i != includes.end(); ++i)
     {
     std::string include = *i;
@@ -1395,26 +1407,26 @@ void cmUnixMakefileGenerator::OutputMakeRules(std::ostream& fout)
                        "$(CMAKE_MAKEFILE_SOURCES) ",
                        "$(CMAKE_COMMAND) "
                        "-S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
-                       "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");
+                       "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
   this->OutputMakeRule(fout, 
                        "Rule to force the build of cmake.depends",
                        "depend",
                        "$(SUBDIR_DEPEND)",
                        "$(CMAKE_COMMAND) "
                        "-S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
-                       "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");  
+                       "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");  
   this->OutputMakeRule(fout, 
                        "Rebuild CMakeCache.txt file",
                        "rebuild_cache",
-                       "${CMAKE_BINARY_DIR}/CMakeCache.txt",
+                       "$(CMAKE_BINARY_DIR)/CMakeCache.txt",
                        "$(CMAKE_COMMAND) "
-                       "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");
+                       "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
   this->OutputMakeRule(fout, 
                        "Create CMakeCache.txt file",
-                       "${CMAKE_BINARY_DIR}/CMakeCache.txt",
+                       "$(CMAKE_BINARY_DIR)/CMakeCache.txt",
                        0,
                        "$(CMAKE_COMMAND) "
-                       "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");
+                       "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
 
   this->OutputMakeRule(fout, 
                        "Rule to keep make from removing Makefiles "
@@ -1464,7 +1476,8 @@ OutputBuildObjectFromSource(std::ostream& fout,
       compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
       }
     compileCommand += "$(INCLUDE_FLAGS) -c ";
-    compileCommand += source.GetFullPath();
+    compileCommand += 
+      cmSystemTools::EscapeSpaces(source.GetFullPath().c_str());
     compileCommand += " -o ";
     compileCommand += objectFile;
     }
@@ -1477,14 +1490,16 @@ OutputBuildObjectFromSource(std::ostream& fout,
       compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
       }
     compileCommand += "$(INCLUDE_FLAGS) -c ";
-    compileCommand += source.GetFullPath();
+    compileCommand += 
+      cmSystemTools::EscapeSpaces(source.GetFullPath().c_str());
     compileCommand += " -o ";
     compileCommand += objectFile;
     }
   this->OutputMakeRule(fout,
                        comment.c_str(),
                        objectFile.c_str(),
-                       source.GetFullPath().c_str(),
+                       cmSystemTools::EscapeSpaces(source.GetFullPath().
+                                                   c_str()).c_str(),
                        compileCommand.c_str());
 }
 
@@ -1661,7 +1676,7 @@ void cmUnixMakefileGenerator::ComputeSystemInfo()
     // currently we run configure shell script here to determine the info
     std::string output;
     std::string cmd = "cd ";
-    cmd += m_Makefile->GetHomeOutputDirectory();
+    cmd += cmSystemTools::EscapeSpaces(m_Makefile->GetHomeOutputDirectory());
     cmd += "; ";
     const char* root
       = m_Makefile->GetDefinition("CMAKE_ROOT");

+ 0 - 1
Source/cmake.cxx

@@ -99,7 +99,6 @@ void cmake::SetCacheArgs(cmMakefile& builder, const std::vector<std::string>& ar
             cmSystemTools::EscapeSpaces(value.c_str()).c_str(),
             "No help, variable specified on the command line.",
             type);
-          std::cerr << "parse entry " << var.c_str()<< " " << value.c_str() << "\n";
         }
       else
         {

+ 6 - 2
Source/cmaketest.cxx

@@ -68,6 +68,10 @@ int main (int argc, char *argv[])
   cmListFileCache::GetInstance()->ClearCache();
   // now build the test
   std::string makeCommand = MAKEPROGRAM;
+  if(makeCommand.size() == 0)
+    {
+    std::cerr << "Error: cmaketest does not have a valid MAKEPROGRAM\n";
+    }
   std::string lowerCaseCommand = makeCommand;
   cmSystemTools::LowerCase(lowerCaseCommand);
   // if msdev is the make program then do the following
@@ -76,18 +80,18 @@ int main (int argc, char *argv[])
     // if there are spaces in the makeCommand, assume a full path
     // and convert it to a path with no spaces in it as the
     // RunCommand does not like spaces
+#if defined(_WIN32) && !defined(__CYGWIN__)      
     if(makeCommand.find(' ') != std::string::npos)
       {
       char *buffer = new char[makeCommand.size()+1];
-#if defined(_WIN32) && !defined(__CYGWIN__)      
       if(GetShortPathName(makeCommand.c_str(), buffer, 
                           makeCommand.size()+1) != 0)
         {
         makeCommand = buffer;
         }
-#endif
       delete [] buffer;\
       }
+#endif
     makeCommand += " ";
     makeCommand += executableName;
     makeCommand += ".dsw /MAKE \"ALL_BUILD - Debug\" /REBUILD";