summaryrefslogtreecommitdiffstats
path: root/tools/gn
diff options
context:
space:
mode:
authorbrettw <brettw@chromium.org>2016-01-06 10:17:21 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-06 18:18:13 +0000
commited40c411145ea48d8d76e171ec4fa3ba84d130d0 (patch)
tree2589a9b353b2a9095af7f9abd578163abba25c13 /tools/gn
parentfd6ee646cd313f26234e2ddcfc0574089cf54c29 (diff)
downloadchromium_src-ed40c411145ea48d8d76e171ec4fa3ba84d130d0.zip
chromium_src-ed40c411145ea48d8d76e171ec4fa3ba84d130d0.tar.gz
chromium_src-ed40c411145ea48d8d76e171ec4fa3ba84d130d0.tar.bz2
Allow python.bat files for finding Python in GN.
Previously gn would look for python.exe on the path. This adds the ability to handle python.bat files also in many cases. This comes up in practice if you install depot tools on a clean machine and add depot_tools to your path. Python will be a batch file that redirects to a subdirectory. Googlers don't see this because corp images have Python installed on the path separately. Review URL: https://codereview.chromium.org/1561873002 Cr-Commit-Position: refs/heads/master@{#367858}
Diffstat (limited to 'tools/gn')
-rw-r--r--tools/gn/setup.cc41
1 files changed, 41 insertions, 0 deletions
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index 774d877..459b87b 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -16,6 +16,7 @@
#include "base/process/launch.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "tools/gn/commands.h"
@@ -149,7 +150,38 @@ void DecrementWorkCount() {
}
#if defined(OS_WIN)
+
+// Given the path to a batch file that runs Python, extracts the name of the
+// executable actually implementing Python. Generally people write a batch file
+// to put something named "python" on the path, which then just redirects to
+// a python.exe somewhere else. This step decodes that setup. On failure,
+// returns empty path.
+base::FilePath PythonBatToExe(const base::FilePath& bat_path) {
+ // Note exciting double-quoting to allow spaces. The /c switch seems to check
+ // for quotes around the whole thing and then deletes them. If you want to
+ // quote the first argument in addition (to allow for spaces in the Python
+ // path, you need *another* set of quotes around that, likewise, we need
+ // two quotes at the end.
+ base::string16 command = L"cmd.exe /c \"\"";
+ command.append(bat_path.value());
+ command.append(L"\" -c \"import sys; print sys.executable\"\"");
+
+ std::string python_path;
+ if (base::GetAppOutput(command, &python_path)) {
+ base::TrimWhitespaceASCII(python_path, base::TRIM_ALL, &python_path);
+
+ // Python uses the system multibyte code page for sys.executable.
+ base::FilePath exe_path(base::SysNativeMBToWide(python_path));
+
+ // Check for reasonable output, cmd may have output an error message.
+ if (base::PathExists(exe_path))
+ return exe_path;
+ }
+ return base::FilePath();
+}
+
const base::char16 kPythonExeName[] = L"python.exe";
+const base::char16 kPythonBatName[] = L"python.bat";
base::FilePath FindWindowsPython() {
base::char16 current_directory[MAX_PATH];
@@ -179,6 +211,15 @@ base::FilePath FindWindowsPython() {
base::FilePath(component).Append(kPythonExeName);
if (base::PathExists(candidate_exe))
return candidate_exe;
+
+ // Also allow python.bat, but convert into the .exe.
+ base::FilePath candidate_bat =
+ base::FilePath(component).Append(kPythonBatName);
+ if (base::PathExists(candidate_bat)) {
+ base::FilePath python_exe = PythonBatToExe(candidate_bat);
+ if (!python_exe.empty())
+ return python_exe;
+ }
}
return base::FilePath();
}