[pkg-d-commits] [ldc] 49/95: Move MSVC environment setup to driver/tool.cpp [NFC]

Matthias Klumpp mak at moszumanska.debian.org
Thu Jul 13 20:53:59 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.3.0-beta1
in repository ldc.

commit 0842277572865d8274cd71a43df144f1870a0dc0
Author: Martin <noone at nowhere.com>
Date:   Mon Mar 13 23:03:33 2017 +0100

    Move MSVC environment setup to driver/tool.cpp [NFC]
---
 driver/linker.cpp | 205 -----------------------------------------------------
 driver/tool.cpp   | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 driver/tool.h     |  15 +++-
 3 files changed, 218 insertions(+), 208 deletions(-)

diff --git a/driver/linker.cpp b/driver/linker.cpp
index 5d0673b..f9d6db0 100644
--- a/driver/linker.cpp
+++ b/driver/linker.cpp
@@ -25,16 +25,10 @@
 #include "llvm/Linker/Linker.h"
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Program.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
-#if _WIN32
-#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/ConvertUTF.h"
-#include <Windows.h>
-#endif
 
 #include <algorithm>
 
@@ -498,205 +492,6 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
 
 //////////////////////////////////////////////////////////////////////////////
 
-#ifdef _WIN32
-
-namespace windows {
-
-bool needsQuotes(const llvm::StringRef &arg) {
-  return // not already quoted
-      !(arg.size() > 1 && arg[0] == '"' &&
-        arg.back() == '"') && // empty or min 1 space or min 1 double quote
-      (arg.empty() || arg.find(' ') != arg.npos || arg.find('"') != arg.npos);
-}
-
-size_t countPrecedingBackslashes(llvm::StringRef arg, size_t index) {
-  size_t count = 0;
-
-  for (size_t i = index - 1; i >= 0; --i) {
-    if (arg[i] != '\\')
-      break;
-    ++count;
-  }
-
-  return count;
-}
-
-std::string quoteArg(llvm::StringRef arg) {
-  if (!needsQuotes(arg))
-    return arg;
-
-  std::string quotedArg;
-  quotedArg.reserve(3 + 2 * arg.size()); // worst case
-
-  quotedArg.push_back('"');
-
-  const size_t argLength = arg.size();
-  for (size_t i = 0; i < argLength; ++i) {
-    if (arg[i] == '"') {
-      // Escape all preceding backslashes (if any).
-      // Note that we *don't* need to escape runs of backslashes that don't
-      // precede a double quote! See MSDN:
-      // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
-      quotedArg.append(countPrecedingBackslashes(arg, i), '\\');
-
-      // Escape the double quote.
-      quotedArg.push_back('\\');
-    }
-
-    quotedArg.push_back(arg[i]);
-  }
-
-  // Make sure our final double quote doesn't get escaped by a trailing
-  // backslash.
-  quotedArg.append(countPrecedingBackslashes(arg, argLength), '\\');
-  quotedArg.push_back('"');
-
-  return quotedArg;
-}
-
-int executeAndWait(const char *commandLine) {
-  STARTUPINFO si;
-  ZeroMemory(&si, sizeof(si));
-  si.cb = sizeof(si);
-
-  PROCESS_INFORMATION pi;
-  ZeroMemory(&pi, sizeof(pi));
-
-  DWORD exitCode;
-
-#if UNICODE
-  std::wstring wcommandLine;
-  if (!llvm::ConvertUTF8toWide(commandLine, wcommandLine))
-    return -3;
-  auto cmdline = const_cast<wchar_t *>(wcommandLine.data());
-#else
-  auto cmdline = const_cast<char *>(commandLine);
-#endif
-  // according to MSDN, only CreateProcessW (unicode) may modify the passed
-  // command line
-  if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0,
-                     NULL, NULL, &si, &pi)) {
-    exitCode = -1;
-  } else {
-    if (WaitForSingleObject(pi.hProcess, INFINITE) != 0 ||
-        !GetExitCodeProcess(pi.hProcess, &exitCode))
-      exitCode = -2;
-
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
-  }
-
-  return exitCode;
-}
-
-bool setupMsvcEnvironment() {
-  if (getenv("VSINSTALLDIR"))
-    return true;
-
-  llvm::SmallString<128> tmpFilePath;
-  if (llvm::sys::fs::createTemporaryFile("ldc_dumpEnv", "", tmpFilePath))
-    return false;
-
-  /* Run `%ComSpec% /s /c "...\dumpEnv.bat <x86|amd64> > <tmpFilePath>"` to dump
-   * the MSVC environment to the temporary file.
-   *
-   * cmd.exe /c treats the following string argument (the command)
-   * in a very peculiar way if it starts with a double-quote.
-   * By adding /s and enclosing the command in extra double-quotes
-   * (WITHOUT additionally escaping the command), the command will
-   * be parsed properly.
-   */
-
-  auto comspecEnv = getenv("ComSpec");
-  if (!comspecEnv) {
-    warning(Loc(),
-            "'ComSpec' environment variable is not set, assuming 'cmd.exe'.");
-    comspecEnv = "cmd.exe";
-  }
-  std::string cmdExecutable = comspecEnv;
-  std::string batchFile = exe_path::prependBinDir("dumpEnv.bat");
-  std::string arch =
-      global.params.targetTriple->isArch64Bit() ? "amd64" : "x86";
-
-  llvm::SmallString<512> commandLine;
-  commandLine += quoteArg(cmdExecutable);
-  commandLine += " /s /c \"";
-  commandLine += quoteArg(batchFile);
-  commandLine += ' ';
-  commandLine += arch;
-  commandLine += " > ";
-  commandLine += quoteArg(tmpFilePath);
-  commandLine += '"';
-
-  const int exitCode = executeAndWait(commandLine.c_str());
-  if (exitCode != 0) {
-    error(Loc(), "`%s` failed with status: %d", commandLine.c_str(), exitCode);
-    llvm::sys::fs::remove(tmpFilePath);
-    return false;
-  }
-
-  auto fileBuffer = llvm::MemoryBuffer::getFile(tmpFilePath);
-  llvm::sys::fs::remove(tmpFilePath);
-  if (fileBuffer.getError())
-    return false;
-
-  const auto contents = (*fileBuffer)->getBuffer();
-  const auto size = contents.size();
-
-  // Parse the file.
-  std::vector<std::pair<llvm::StringRef, llvm::StringRef>> env;
-
-  size_t i = 0;
-  // for each line
-  while (i < size) {
-    llvm::StringRef key, value;
-
-    for (size_t j = i; j < size; ++j) {
-      const char c = contents[j];
-      if (c == '=' && key.empty()) {
-        key = contents.slice(i, j);
-        i = j + 1;
-      } else if (c == '\n' || c == '\r' || c == '\0') {
-        if (!key.empty()) {
-          value = contents.slice(i, j);
-        }
-        // break and continue with next line
-        i = j + 1;
-        break;
-      }
-    }
-
-    if (!key.empty() && !value.empty())
-      env.emplace_back(key, value);
-  }
-
-  if (global.params.verbose)
-    fprintf(global.stdmsg, "Applying environment variables:\n");
-
-  bool haveVsInstallDir = false;
-
-  for (const auto &pair : env) {
-    const std::string key = pair.first.str();
-    const std::string value = pair.second.str();
-
-    if (global.params.verbose)
-      fprintf(global.stdmsg, "  %s=%s\n", key.c_str(), value.c_str());
-
-    SetEnvironmentVariableA(key.c_str(), value.c_str());
-
-    if (key == "VSINSTALLDIR")
-      haveVsInstallDir = true;
-  }
-
-  return haveVsInstallDir;
-}
-
-} // namespace windows
-
-#endif
-
-//////////////////////////////////////////////////////////////////////////////
-
 static int linkObjToBinaryMSVC(bool sharedLib) {
   Logger::println("*** Linking executable ***");
 
diff --git a/driver/tool.cpp b/driver/tool.cpp
index 2f33084..c409210 100644
--- a/driver/tool.cpp
+++ b/driver/tool.cpp
@@ -9,7 +9,14 @@
 
 #include "driver/tool.h"
 #include "mars.h"
+#include "driver/exe_path.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Program.h"
+#ifdef _WIN32
+#include <Windows.h>
+#endif
 
 int executeToolAndWait(const std::string &tool_,
                        std::vector<std::string> const &args, bool verbose) {
@@ -53,3 +60,202 @@ int executeToolAndWait(const std::string &tool_,
   }
   return 0;
 }
+
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef _WIN32
+
+namespace windows {
+
+bool needsQuotes(const llvm::StringRef &arg) {
+  return // not already quoted
+      !(arg.size() > 1 && arg[0] == '"' &&
+        arg.back() == '"') && // empty or min 1 space or min 1 double quote
+      (arg.empty() || arg.find(' ') != arg.npos || arg.find('"') != arg.npos);
+}
+
+size_t countPrecedingBackslashes(llvm::StringRef arg, size_t index) {
+  size_t count = 0;
+
+  for (size_t i = index - 1; i >= 0; --i) {
+    if (arg[i] != '\\')
+      break;
+    ++count;
+  }
+
+  return count;
+}
+
+std::string quoteArg(llvm::StringRef arg) {
+  if (!needsQuotes(arg))
+    return arg;
+
+  std::string quotedArg;
+  quotedArg.reserve(3 + 2 * arg.size()); // worst case
+
+  quotedArg.push_back('"');
+
+  const size_t argLength = arg.size();
+  for (size_t i = 0; i < argLength; ++i) {
+    if (arg[i] == '"') {
+      // Escape all preceding backslashes (if any).
+      // Note that we *don't* need to escape runs of backslashes that don't
+      // precede a double quote! See MSDN:
+      // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
+      quotedArg.append(countPrecedingBackslashes(arg, i), '\\');
+
+      // Escape the double quote.
+      quotedArg.push_back('\\');
+    }
+
+    quotedArg.push_back(arg[i]);
+  }
+
+  // Make sure our final double quote doesn't get escaped by a trailing
+  // backslash.
+  quotedArg.append(countPrecedingBackslashes(arg, argLength), '\\');
+  quotedArg.push_back('"');
+
+  return quotedArg;
+}
+
+int executeAndWait(const char *commandLine) {
+  STARTUPINFO si;
+  ZeroMemory(&si, sizeof(si));
+  si.cb = sizeof(si);
+
+  PROCESS_INFORMATION pi;
+  ZeroMemory(&pi, sizeof(pi));
+
+  DWORD exitCode;
+
+#if UNICODE
+  std::wstring wcommandLine;
+  if (!llvm::ConvertUTF8toWide(commandLine, wcommandLine))
+    return -3;
+  auto cmdline = const_cast<wchar_t *>(wcommandLine.data());
+#else
+  auto cmdline = const_cast<char *>(commandLine);
+#endif
+  // according to MSDN, only CreateProcessW (unicode) may modify the passed
+  // command line
+  if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0,
+                     NULL, NULL, &si, &pi)) {
+    exitCode = -1;
+  } else {
+    if (WaitForSingleObject(pi.hProcess, INFINITE) != 0 ||
+        !GetExitCodeProcess(pi.hProcess, &exitCode))
+      exitCode = -2;
+
+    CloseHandle(pi.hProcess);
+    CloseHandle(pi.hThread);
+  }
+
+  return exitCode;
+}
+
+bool setupMsvcEnvironment() {
+  if (getenv("VSINSTALLDIR"))
+    return true;
+
+  llvm::SmallString<128> tmpFilePath;
+  if (llvm::sys::fs::createTemporaryFile("ldc_dumpEnv", "", tmpFilePath))
+    return false;
+
+  /* Run `%ComSpec% /s /c "...\dumpEnv.bat <x86|amd64> > <tmpFilePath>"` to dump
+   * the MSVC environment to the temporary file.
+   *
+   * cmd.exe /c treats the following string argument (the command)
+   * in a very peculiar way if it starts with a double-quote.
+   * By adding /s and enclosing the command in extra double-quotes
+   * (WITHOUT additionally escaping the command), the command will
+   * be parsed properly.
+   */
+
+  auto comspecEnv = getenv("ComSpec");
+  if (!comspecEnv) {
+    warning(Loc(),
+            "'ComSpec' environment variable is not set, assuming 'cmd.exe'.");
+    comspecEnv = "cmd.exe";
+  }
+  std::string cmdExecutable = comspecEnv;
+  std::string batchFile = exe_path::prependBinDir("dumpEnv.bat");
+  std::string arch =
+      global.params.targetTriple->isArch64Bit() ? "amd64" : "x86";
+
+  llvm::SmallString<512> commandLine;
+  commandLine += quoteArg(cmdExecutable);
+  commandLine += " /s /c \"";
+  commandLine += quoteArg(batchFile);
+  commandLine += ' ';
+  commandLine += arch;
+  commandLine += " > ";
+  commandLine += quoteArg(tmpFilePath);
+  commandLine += '"';
+
+  const int exitCode = executeAndWait(commandLine.c_str());
+  if (exitCode != 0) {
+    error(Loc(), "`%s` failed with status: %d", commandLine.c_str(), exitCode);
+    llvm::sys::fs::remove(tmpFilePath);
+    return false;
+  }
+
+  auto fileBuffer = llvm::MemoryBuffer::getFile(tmpFilePath);
+  llvm::sys::fs::remove(tmpFilePath);
+  if (fileBuffer.getError())
+    return false;
+
+  const auto contents = (*fileBuffer)->getBuffer();
+  const auto size = contents.size();
+
+  // Parse the file.
+  std::vector<std::pair<llvm::StringRef, llvm::StringRef>> env;
+
+  size_t i = 0;
+  // for each line
+  while (i < size) {
+    llvm::StringRef key, value;
+
+    for (size_t j = i; j < size; ++j) {
+      const char c = contents[j];
+      if (c == '=' && key.empty()) {
+        key = contents.slice(i, j);
+        i = j + 1;
+      } else if (c == '\n' || c == '\r' || c == '\0') {
+        if (!key.empty()) {
+          value = contents.slice(i, j);
+        }
+        // break and continue with next line
+        i = j + 1;
+        break;
+      }
+    }
+
+    if (!key.empty() && !value.empty())
+      env.emplace_back(key, value);
+  }
+
+  if (global.params.verbose)
+    fprintf(global.stdmsg, "Applying environment variables:\n");
+
+  bool haveVsInstallDir = false;
+
+  for (const auto &pair : env) {
+    const std::string key = pair.first.str();
+    const std::string value = pair.second.str();
+
+    if (global.params.verbose)
+      fprintf(global.stdmsg, "  %s=%s\n", key.c_str(), value.c_str());
+
+    SetEnvironmentVariableA(key.c_str(), value.c_str());
+
+    if (key == "VSINSTALLDIR")
+      haveVsInstallDir = true;
+  }
+
+  return haveVsInstallDir;
+}
+
+} // namespace windows
+
+#endif // _WIN32
diff --git a/driver/tool.h b/driver/tool.h
index d4dc5f8..c96f851 100644
--- a/driver/tool.h
+++ b/driver/tool.h
@@ -1,5 +1,4 @@
-//===-- driver/tool.h - External tool invocation helpers ---------*- C++
-//-*-===//
+//===-- driver/tool.h - External tool invocation helpers --------*- C++ -*-===//
 //
 //                         LDC – the LLVM D compiler
 //
@@ -8,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Functionaliy for invoking external tools executables, such as the system
+// Functionality for invoking external tools executables, such as the system
 // assembler, linker, ...
 //
 //===----------------------------------------------------------------------===//
@@ -23,4 +22,14 @@ int executeToolAndWait(const std::string &tool,
                        std::vector<std::string> const &args,
                        bool verbose = false);
 
+#ifdef _WIN32
+
+namespace windows {
+// Tries to set up the MSVC environment variables and returns true if
+// successful.
+bool setupMsvcEnvironment();
+}
+
+#endif
+
 #endif

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list