Apply path search logic more generally
The --script-executable option becomes much more portable if "python"
(or "python3") can be specified across platforms. On Windows this
requires adding a .bat or .exe extension and doing a search of the path.
The logic to do this already existed and just needed to be generalized.
Running clang-format on setup.cc adjusted a few unrelated lines.
Change-Id: If0b44449fa4f4672b5408c3c26dc21b2388dd184
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/10600
Commit-Queue: Dirk Pranke <dpranke@google.com>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/src/gn/setup.cc b/src/gn/setup.cc
index 081bc7e..8c402f1 100644
--- a/src/gn/setup.cc
+++ b/src/gn/setup.cc
@@ -286,16 +286,14 @@
return base::FilePath();
}
-const char16_t kPythonExeName[] = u"python.exe";
-const char16_t kPythonBatName[] = u"python.bat";
-
-base::FilePath FindWindowsPython() {
+base::FilePath FindWindowsPython(const base::FilePath& python_exe_name,
+ const base::FilePath& python_bat_name) {
char16_t current_directory[MAX_PATH];
::GetCurrentDirectory(MAX_PATH, reinterpret_cast<LPWSTR>(current_directory));
// First search for python.exe in the current directory.
base::FilePath cur_dir_candidate_exe =
- base::FilePath(current_directory).Append(kPythonExeName);
+ base::FilePath(current_directory).Append(python_exe_name);
if (base::PathExists(cur_dir_candidate_exe))
return cur_dir_candidate_exe;
@@ -316,13 +314,13 @@
std::u16string_view(full_path.get(), path_length), u";",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
base::FilePath candidate_exe =
- base::FilePath(component).Append(kPythonExeName);
+ base::FilePath(component).Append(python_exe_name);
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);
+ base::FilePath(component).Append(python_bat_name);
if (base::PathExists(candidate_bat)) {
base::FilePath python_exe = PythonBatToExe(candidate_bat);
if (!python_exe.empty())
@@ -652,7 +650,8 @@
base::GetCurrentDirectory(&cur_dir);
dotfile_name_ = FindDotFile(cur_dir);
if (dotfile_name_.empty()) {
- *err = Err(Location(), "Can't find source root.",
+ *err = Err(
+ Location(), "Can't find source root.",
"I could not find a \".gn\" file in the current directory or any "
"parent,\nand the --root command-line argument was not specified.");
return false;
@@ -727,10 +726,20 @@
ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Fill Python Path");
const Value* value = dotfile_scope_.GetValue("script_executable", true);
if (cmdline.HasSwitch(switches::kScriptExecutable)) {
- auto script_executable = cmdline.GetSwitchValuePath(switches::kScriptExecutable);
+ auto script_executable =
+ cmdline.GetSwitchValuePath(switches::kScriptExecutable);
#if defined(OS_WIN)
- if (script_executable.FinalExtension() == u".bat")
- script_executable = PythonBatToExe(script_executable);
+ // If we have a relative path with no extension such as "python" or
+ // "python3" then do a path search on the name with .exe and .bat appended.
+ if (!script_executable.IsAbsolute() &&
+ script_executable.FinalExtension() == u"") {
+ script_executable =
+ FindWindowsPython(script_executable.ReplaceExtension(u".exe"),
+ script_executable.ReplaceExtension(u".bat"));
+ } else {
+ if (script_executable.FinalExtension() == u".bat")
+ script_executable = PythonBatToExe(script_executable);
+ }
#endif
build_settings_.set_python_path(script_executable);
} else if (value) {
@@ -741,12 +750,15 @@
base::FilePath(UTF8ToFilePath(value->string_value())));
} else {
#if defined(OS_WIN)
- base::FilePath python_path = FindWindowsPython();
+ const base::FilePath python_exe_name(u"python.exe");
+ const base::FilePath python_bat_name(u"python.bat");
+ base::FilePath python_path =
+ FindWindowsPython(python_exe_name, python_bat_name);
if (python_path.empty()) {
scheduler_.Log("WARNING",
"Could not find python on path, using "
"just \"python.exe\"");
- python_path = base::FilePath(kPythonExeName);
+ python_path = python_exe_name;
}
build_settings_.set_python_path(python_path.NormalizePathSeparatorsTo('/'));
#else
@@ -848,8 +860,7 @@
// Root build file.
if (cmdline.HasSwitch(switches::kRootTarget)) {
- auto switch_value =
- cmdline.GetSwitchValueASCII(switches::kRootTarget);
+ auto switch_value = cmdline.GetSwitchValueASCII(switches::kRootTarget);
Value root_value(nullptr, switch_value);
root_target_label = Label::Resolve(current_dir, std::string_view(), Label(),
root_value, err);