diff options
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r-- | Source/cmSystemTools.cxx | 116 |
1 files changed, 90 insertions, 26 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 63c1452e6..eeb73c3ee 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -3,6 +3,7 @@ #include "cmSystemTools.h" #include "cmAlgorithms.h" +#include "cmDuration.h" #include "cmProcessOutput.h" #include "cm_sys_stat.h" @@ -50,6 +51,10 @@ #include <windows.h> // include wincrypt.h after windows.h #include <wincrypt.h> + +#include <fcntl.h> /* _O_TEXT */ + +#include "cm_uv.h" #else #include <sys/time.h> #include <unistd.h> @@ -545,12 +550,13 @@ std::vector<std::string> cmSystemTools::ParseArguments(const char* command) bool win_path = false; - if ((command[0] != '/' && command[1] == ':' && command[2] == '\\') || - (command[0] == '\"' && command[1] != '/' && command[2] == ':' && - command[3] == '\\') || - (command[0] == '\'' && command[1] != '/' && command[2] == ':' && - command[3] == '\\') || - (command[0] == '\\' && command[1] == '\\')) { + if (command[0] && command[1] && + ((command[0] != '/' && command[1] == ':' && command[2] == '\\') || + (command[0] == '\"' && command[1] != '/' && command[2] == ':' && + command[3] == '\\') || + (command[0] == '\'' && command[1] != '/' && command[2] == ':' && + command[3] == '\\') || + (command[0] == '\\' && command[1] == '\\'))) { win_path = true; } // Split the command into an argv array. @@ -697,7 +703,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command, std::string* captureStdOut, std::string* captureStdErr, int* retVal, const char* dir, OutputOption outputflag, - double timeout, Encoding encoding) + cmDuration timeout, Encoding encoding) { std::vector<const char*> argv; argv.reserve(command.size() + 1); @@ -725,7 +731,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command, } assert(!captureStdErr || captureStdErr != captureStdOut); - cmsysProcess_SetTimeout(cp, timeout); + cmsysProcess_SetTimeout(cp, timeout.count()); cmsysProcess_Execute(cp); std::vector<char> tempStdOut; @@ -838,7 +844,7 @@ bool cmSystemTools::RunSingleCommand(const char* command, std::string* captureStdOut, std::string* captureStdErr, int* retVal, const char* dir, OutputOption outputflag, - double timeout) + cmDuration timeout) { if (s_DisableRunCommandOutput) { outputflag = OUTPUT_NONE; @@ -872,7 +878,7 @@ bool cmSystemTools::DoesFileExistWithExtensions( hname = name; hname += "."; hname += headerExt; - if (cmSystemTools::FileExists(hname.c_str())) { + if (cmSystemTools::FileExists(hname)) { return true; } } @@ -890,7 +896,7 @@ std::string cmSystemTools::FileExistsInParentDirectories(const char* fname, std::string prevDir; while (dir != prevDir) { std::string path = dir + "/" + file; - if (cmSystemTools::FileExists(path.c_str())) { + if (cmSystemTools::FileExists(path)) { return path; } if (dir.size() < strlen(toplevel)) { @@ -943,7 +949,55 @@ cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsFileRetry() } return retry; } + +std::string cmSystemTools::GetRealPath(const std::string& path, + std::string* errorMessage) +{ + // uv_fs_realpath uses Windows Vista API so fallback to kwsys if not found + std::string resolved_path; + uv_fs_t req; + int err = uv_fs_realpath(NULL, &req, path.c_str(), NULL); + if (!err) { + resolved_path = std::string((char*)req.ptr); + cmSystemTools::ConvertToUnixSlashes(resolved_path); + // Normalize to upper-case drive letter as GetActualCaseForPath does. + if (resolved_path.size() > 1 && resolved_path[1] == ':') { + resolved_path[0] = toupper(resolved_path[0]); + } + } else if (err == UV_ENOSYS) { + resolved_path = cmsys::SystemTools::GetRealPath(path, errorMessage); + } else if (errorMessage) { + LPSTR message = NULL; + DWORD size = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message, 0, + NULL); + *errorMessage = std::string(message, size); + LocalFree(message); + + resolved_path = ""; + } else { + resolved_path = path; + } + return resolved_path; +} +#endif + +void cmSystemTools::InitializeLibUV() +{ +#if defined(_WIN32) + // Perform libuv one-time initialization now, and then un-do its + // global _fmode setting so that using libuv does not change the + // default file text/binary mode. See libuv issue 840. + uv_loop_close(uv_default_loop()); +#ifdef _MSC_VER + _set_fmode(_O_TEXT); +#else + _fmode = _O_TEXT; +#endif #endif +} bool cmSystemTools::RenameFile(const char* oldname, const char* newname) { @@ -1101,7 +1155,7 @@ void cmSystemTools::Glob(const std::string& directory, for (i = 0; i < numf; i++) { std::string fname = d.GetFile(i); if (reg.find(fname)) { - files.push_back(fname); + files.push_back(std::move(fname)); } } } @@ -1273,6 +1327,9 @@ cmSystemTools::FileFormat cmSystemTools::GetFileFormat(const char* cext) if (ext == "java" || ext == ".java") { return cmSystemTools::JAVA_FILE_FORMAT; } + if (ext == "cu" || ext == ".cu") { + return cmSystemTools::CUDA_FILE_FORMAT; + } if (ext == "H" || ext == ".H" || ext == "h" || ext == ".h" || ext == "h++" || ext == ".h++" || ext == "hm" || ext == ".hm" || ext == "hpp" || ext == ".hpp" || ext == "hxx" || ext == ".hxx" || ext == "in" || @@ -1315,7 +1372,7 @@ bool cmSystemTools::Split(const char* s, std::vector<std::string>& l) return res; } -std::string cmSystemTools::ConvertToOutputPath(const char* path) +std::string cmSystemTools::ConvertToOutputPath(std::string const& path) { #if defined(_WIN32) && !defined(__CYGWIN__) if (s_ForceUnixPaths) { @@ -1352,15 +1409,16 @@ std::string cmSystemTools::ConvertToRunCommandPath(const char* path) } // compute the relative path from here to there -std::string cmSystemTools::RelativePath(const char* local, const char* remote) +std::string cmSystemTools::RelativePath(std::string const& local, + std::string const& remote) { if (!cmSystemTools::FileIsFullPath(local)) { cmSystemTools::Error("RelativePath must be passed a full path to local: ", - local); + local.c_str()); } if (!cmSystemTools::FileIsFullPath(remote)) { cmSystemTools::Error("RelativePath must be passed a full path to remote: ", - remote); + remote.c_str()); } return cmsys::SystemTools::RelativePath(local, remote); } @@ -1514,9 +1572,9 @@ bool cmSystemTools::CreateTar(const char* outFileName, a.SetMTime(mtime); a.SetVerbose(verbose); for (auto path : files) { - if (cmSystemTools::FileIsFullPath(path.c_str())) { + if (cmSystemTools::FileIsFullPath(path)) { // Get the relative path to the file. - path = cmSystemTools::RelativePath(cwd.c_str(), path.c_str()); + path = cmSystemTools::RelativePath(cwd, path); } if (!a.Add(path)) { break; @@ -1773,7 +1831,7 @@ bool cmSystemTools::ListTar(const char* outFileName, bool verbose) } int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line, - double timeout, std::vector<char>& out, + cmDuration timeout, std::vector<char>& out, std::vector<char>& err) { line.clear(); @@ -1821,7 +1879,9 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line, // No newlines found. Wait for more data from the process. int length; char* data; - int pipe = cmsysProcess_WaitForData(process, &data, &length, &timeout); + double timeoutAsDbl = timeout.count(); + int pipe = + cmsysProcess_WaitForData(process, &data, &length, &timeoutAsDbl); if (pipe == cmsysProcess_Pipe_Timeout) { // Timeout has been exceeded. return pipe; @@ -2052,8 +2112,12 @@ void cmSystemTools::FindCMakeResources(const char* argv0) (void)argv0; // ignore this on windows wchar_t modulepath[_MAX_PATH]; ::GetModuleFileNameW(NULL, modulepath, sizeof(modulepath)); - exe_dir = - cmSystemTools::GetFilenamePath(cmsys::Encoding::ToNarrow(modulepath)); + std::string path = cmsys::Encoding::ToNarrow(modulepath); + std::string realPath = cmSystemTools::GetRealPath(path, NULL); + if (realPath.empty()) { + realPath = path; + } + exe_dir = cmSystemTools::GetFilenamePath(realPath); #elif defined(__APPLE__) (void)argv0; // ignore this on OS X #define CM_EXE_PATH_LOCAL_SIZE 16384 @@ -2115,19 +2179,19 @@ void cmSystemTools::FindCMakeResources(const char* argv0) cmSystemToolsCMakeGUICommand = exe_dir; cmSystemToolsCMakeGUICommand += "/cmake-gui"; cmSystemToolsCMakeGUICommand += cmSystemTools::GetExecutableExtension(); - if (!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand.c_str())) { + if (!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand)) { cmSystemToolsCMakeGUICommand.clear(); } cmSystemToolsCMakeCursesCommand = exe_dir; cmSystemToolsCMakeCursesCommand += "/ccmake"; cmSystemToolsCMakeCursesCommand += cmSystemTools::GetExecutableExtension(); - if (!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand.c_str())) { + if (!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand)) { cmSystemToolsCMakeCursesCommand.clear(); } cmSystemToolsCMClDepsCommand = exe_dir; cmSystemToolsCMClDepsCommand += "/cmcldeps"; cmSystemToolsCMClDepsCommand += cmSystemTools::GetExecutableExtension(); - if (!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand.c_str())) { + if (!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand)) { cmSystemToolsCMClDepsCommand.clear(); } @@ -2142,7 +2206,7 @@ void cmSystemTools::FindCMakeResources(const char* argv0) } if (cmSystemToolsCMakeRoot.empty() || !cmSystemTools::FileExists( - (cmSystemToolsCMakeRoot + "/Modules/CMake.cmake").c_str())) { + (cmSystemToolsCMakeRoot + "/Modules/CMake.cmake"))) { // Build tree has "<build>/bin[/<config>]/cmake" and // "<build>/CMakeFiles/CMakeSourceDir.txt". std::string dir = cmSystemTools::GetFilenamePath(exe_dir); |