From 12551a33c394cd06a082f2df2ad550e38d762a98 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Wed, 21 Nov 2001 17:45:01 -0500 Subject: NMake with spaces in directories --- Source/cmCacheManager.cxx | 40 +++++------------ Source/cmDSPWriter.cxx | 2 +- Source/cmNMakeMakefileGenerator.cxx | 71 +++++++++++++++++++++++-------- Source/cmSystemTools.cxx | 19 +++++++++ Source/cmSystemTools.h | 3 ++ Source/cmUnixMakefileGenerator.cxx | 85 ++++++++++++++++++++++--------------- Source/cmake.cxx | 1 - Source/cmaketest.cxx | 8 +++- 8 files changed, 144 insertions(+), 85 deletions(-) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 9ba01db..f784301 100644 --- a/Source/cmCacheManager.cxx +++ b/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; } diff --git a/Source/cmDSPWriter.cxx b/Source/cmDSPWriter.cxx index 8da1c17..5e684fd 100644 --- a/Source/cmDSPWriter.cxx +++ b/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()); diff --git a/Source/cmNMakeMakefileGenerator.cxx b/Source/cmNMakeMakefileGenerator.cxx index 40b5134..224e1ac 100644 --- a/Source/cmNMakeMakefileGenerator.cxx +++ b/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::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:"; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 517d500..6e6abfe 100644 --- a/Source/cmSystemTools.cxx +++ b/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) { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index b24e681..be952fc 100644 --- a/Source/cmSystemTools.h +++ b/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); diff --git a/Source/cmUnixMakefileGenerator.cxx b/Source/cmUnixMakefileGenerator.cxx index b0584df..340705e 100644 --- a/Source/cmUnixMakefileGenerator.cxx +++ b/Source/cmUnixMakefileGenerator.cxx @@ -235,11 +235,13 @@ void cmUnixMakefileGenerator::OutputMakefile(const char* file) for(std::vector::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& includes = m_Makefile->GetIncludeDirectories(); std::vector::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"); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 0b82167..8b15357 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -99,7 +99,6 @@ void cmake::SetCacheArgs(cmMakefile& builder, const std::vector& 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 { diff --git a/Source/cmaketest.cxx b/Source/cmaketest.cxx index 8c5fa8d..95a2787 100644 --- a/Source/cmaketest.cxx +++ b/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"; -- cgit v0.12