| Index: tools/gn/setup.cc
|
| diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
|
| index 774d877691e58ba8cfac76df38e2a4ceae92b9c3..459b87bc5d6e3da36a1856dc89b192131d33f513 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();
|
| }
|
|
|