From dd41ff012531ffa0d970d6e1594bf23588ccd831 Mon Sep 17 00:00:00 2001 From: aldersondrive Date: Tue, 4 Feb 2020 11:00:27 -0800 Subject: [PATCH] On OpenBSD, search the PATH to find the Bazel executable. Searching the `PATH` is the only feasible way to find the executable on OpenBSD when `argv[0]` is not an absolute path or a relative path. This change resolves a TODO. This change moves a preexisting `Which` function for searching the `PATH` out of `blaze_util_linux.cc` and into `blaze_util_posix.cc`, so that the Linux code and the BSD code can share this function. In my testing on OpenBSD 6.6-current, a bootstrap build of Bazel succeeds and the resulting `bazel` binary can find itself on the `PATH`. (One caveat: For the bootstrap build to succeed, I had to manually apply the unrelated change in https://github.com/bazelbuild/bazel/pull/10639, since it's not merged yet.) This change is part of the OpenBSD port in https://github.com/bazelbuild/bazel/issues/10250. @jmmv FYI. Closes #10691. PiperOrigin-RevId: 293183553 --- src/main/cpp/blaze_util_bsd.cc | 10 ++++++---- src/main/cpp/blaze_util_linux.cc | 23 ----------------------- src/main/cpp/blaze_util_platform.h | 4 ++++ src/main/cpp/blaze_util_posix.cc | 24 ++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/main/cpp/blaze_util_bsd.cc b/src/main/cpp/blaze_util_bsd.cc index 954c8f0f1bec15..14f5456c609a33 100644 --- a/src/main/cpp/blaze_util_bsd.cc +++ b/src/main/cpp/blaze_util_bsd.cc @@ -131,13 +131,15 @@ string GetSelfPath(const char* argv0) { return blaze_util::GetCwd() + "/" + argv0str; } - // TODO(aldersondrive): Try to find the executable by inspecting the PATH. + // Otherwise, try to find the executable by searching the PATH. + const std::string from_search_path = Which(argv0); + if (!from_search_path.empty()) { + return from_search_path; + } // None of the above worked. Give up. BAZEL_DIE(blaze_exit_code::BAD_ARGV) - << "Unable to determine the location of this Bazel executable. " - "Currently, argv[0] must be an absolute or relative path to the " - "executable."; + << "Unable to determine the location of this Bazel executable."; return ""; // Never executed. Needed so compiler does not complain. #else # error This BSD is not supported diff --git a/src/main/cpp/blaze_util_linux.cc b/src/main/cpp/blaze_util_linux.cc index 9c105035921912..ef9a3e1a8768d2 100644 --- a/src/main/cpp/blaze_util_linux.cc +++ b/src/main/cpp/blaze_util_linux.cc @@ -132,29 +132,6 @@ bool IsSharedLibrary(const string &filename) { return blaze_util::ends_with(filename, ".so"); } -static string Which(const string &executable) { - string path(GetPathEnv("PATH")); - if (path.empty()) { - return ""; - } - - vector pieces = blaze_util::Split(path, ':'); - for (auto piece : pieces) { - if (piece.empty()) { - piece = "."; - } - - struct stat file_stat; - string candidate = blaze_util::JoinPath(piece, executable); - if (access(candidate.c_str(), X_OK) == 0 && - stat(candidate.c_str(), &file_stat) == 0 && - S_ISREG(file_stat.st_mode)) { - return candidate; - } - } - return ""; -} - string GetSystemJavabase() { // if JAVA_HOME is defined, then use it as default. string javahome = GetPathEnv("JAVA_HOME"); diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h index 3c6bff20473ce9..42075f106ba094 100644 --- a/src/main/cpp/blaze_util_platform.h +++ b/src/main/cpp/blaze_util_platform.h @@ -107,6 +107,10 @@ void SigPrintf(const char *format, ...); std::string GetProcessIdAsString(); +// Locates a file named `executable` in the PATH. Returns a path to the first +// matching file, or an empty string if `executable` is not found on the PATH. +std::string Which(const std::string& executable); + // Gets an absolute path to the binary being executed that is guaranteed to be // readable. std::string GetSelfPath(const char* argv0); diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc index 70e9c13f0dd417..25f57b322ee917 100644 --- a/src/main/cpp/blaze_util_posix.cc +++ b/src/main/cpp/blaze_util_posix.cc @@ -54,6 +54,7 @@ #include "src/main/cpp/util/numbers.h" #include "src/main/cpp/util/path.h" #include "src/main/cpp/util/path_platform.h" +#include "src/main/cpp/util/strings.h" namespace blaze { @@ -217,6 +218,29 @@ string GetHomeDir() { return GetPathEnv("HOME"); } string GetJavaBinaryUnderJavabase() { return "bin/java"; } +string Which(const string& executable) { + const string path = GetPathEnv("PATH"); + if (path.empty()) { + return ""; + } + + const vector pieces = blaze_util::Split(path, ':'); + for (string piece : pieces) { + if (piece.empty()) { + piece = "."; + } + + struct stat file_stat; + const string candidate = blaze_util::JoinPath(piece, executable); + if (access(candidate.c_str(), X_OK) == 0 && + stat(candidate.c_str(), &file_stat) == 0 && + S_ISREG(file_stat.st_mode)) { + return candidate; + } + } + return ""; +} + // Converter of C++ data structures to a C-style array of strings. // // The primary consumer of this class is the execv family of functions