Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow a bootstrap build of Bazel on OpenBSD to succeed. #10274

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions scripts/bootstrap/buildenv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ freebsd)
JAVA_HOME="${JAVA_HOME:-/usr/local/openjdk8}"
;;

openbsd)
# JAVA_HOME must point to a Java installation.
JAVA_HOME="${JAVA_HOME:-/usr/local/jdk-1.8.0}"
;;

darwin)
if [[ -z "$JAVA_HOME" ]]; then
JAVA_HOME="$(/usr/libexec/java_home -v ${JAVA_VERSION}+ 2> /dev/null)" \
Expand Down
1 change: 1 addition & 0 deletions scripts/packages/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ filegroup(
":zip-bazel-exe_nojdk",
],
"//src/conditions:freebsd": [],
"//src/conditions:openbsd": [],
"//src/conditions:darwin": [
":with-jdk/install.sh",
":without-jdk/install.sh",
Expand Down
4 changes: 4 additions & 0 deletions scripts/packages/template_bin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ if [ -z "${JAVA_HOME-}" ]; then
JAVA_HOME="/usr/local/openjdk8"
BASHRC="~/.bashrc"
;;
openbsd)
JAVA_HOME="/usr/local/jdk-1.8.0"
BASHRC="~/.bashrc"
;;
darwin)
JAVA_HOME="$(/usr/libexec/java_home -v ${JAVA_VERSION}+ 2> /dev/null)" || true
BASHRC="~/.bash_profile"
Expand Down
19 changes: 16 additions & 3 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ load(":rule_size_test.bzl", "rule_size_test")
exports_files(["jdeps_modules.golden"])

# Keep only the first 32 chars (a hex md5sum) and no trailing newline.
md5_cmd = "set -e -o pipefail && echo $(SRCS) | sort | xargs %s | %s | head -c 32 > $@"
# Avoid using the `head` tool's `-c` option, since it does not exist on OpenBSD;
# here we use `dd` instead.
md5_cmd = "set -e -o pipefail && echo $(SRCS) | sort | xargs %s | %s | dd bs=32 count=1 > $@"

# TODO(bazel-team): find a better way to handle dylib extensions.
filegroup(
Expand Down Expand Up @@ -40,6 +42,7 @@ filegroup(
"//src/conditions:darwin": md5_cmd % ("/sbin/md5", "/sbin/md5"),
"//src/conditions:darwin_x86_64": md5_cmd % ("/sbin/md5", "/sbin/md5"),
"//src/conditions:freebsd": md5_cmd % ("/sbin/md5", "/sbin/md5"),
"//src/conditions:openbsd": md5_cmd % ("/bin/md5", "/bin/md5"),
"//conditions:default": md5_cmd % ("md5sum", "md5sum"),
}),
) for suffix, embedded_tools_target in {
Expand Down Expand Up @@ -354,8 +357,8 @@ filegroup(
],
}),
outs = ["package" + suffix + ".zip"],
cmd = "$(location :package-bazel.sh) $@ " + ("" if embed else "''") + " $(SRCS)",
tools = ["package-bazel.sh"],
cmd = "$(location :package_bazel_on_host_platform) $@ " + ("" if embed else "''") + " $(SRCS)",
tools = [":package_bazel_on_host_platform"],
) for suffix, embed in [
("_jdk_allmodules", True),
("_jdk_minimal", True),
Expand All @@ -364,6 +367,16 @@ filegroup(
("_nojdk", True),
]]

genrule(
name = "package_bazel_on_host_platform",
srcs = ["package-bazel.sh"],
outs = ["package-bazel-on-host-platform.sh"],
cmd = select({
"//src/conditions:openbsd": "cat $(SRCS) | sed -e 's@#!/bin/bash@#!/usr/local/bin/bash@' > $@",
"//conditions:default": "cp $(SRCS) $@",
}),
)

genrule(
name = "platforms_archive",
srcs = ["@platforms//:srcs"],
Expand Down
6 changes: 6 additions & 0 deletions src/conditions/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ config_setting(
visibility = ["//visibility:public"],
)

config_setting(
name = "openbsd",
values = {"cpu": "openbsd"},
visibility = ["//visibility:public"],
)

config_setting(
name = "windows",
values = {"cpu": "x64_windows"},
Expand Down
6 changes: 6 additions & 0 deletions src/conditions/BUILD.tools
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ config_setting(
visibility = ["//visibility:public"],
)

config_setting(
name = "openbsd",
values = {"cpu": "openbsd"},
visibility = ["//visibility:public"],
)

config_setting(
name = "darwin",
values = {"cpu": "darwin"},
Expand Down
8 changes: 8 additions & 0 deletions src/main/cpp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ cc_library(
"blaze_util_freebsd.cc",
"blaze_util_posix.cc",
],
"//src/conditions:openbsd": [
"blaze_util_openbsd.cc",
"blaze_util_posix.cc",
],
"//src/conditions:windows": [
"blaze_util_windows.cc",
],
Expand All @@ -53,6 +57,8 @@ cc_library(
],
"//src/conditions:freebsd": [
],
"//src/conditions:openbsd": [
],
"//src/conditions:windows": WIN_LINK_OPTS,
"//conditions:default": [
"-lrt",
Expand Down Expand Up @@ -114,6 +120,8 @@ cc_binary(
"-lprocstat",
"-lm",
],
"//src/conditions:openbsd": [
],
"//src/conditions:windows": [
],
"//conditions:default": [
Expand Down
16 changes: 12 additions & 4 deletions src/main/cpp/blaze.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1519,21 +1519,25 @@ static void RunLauncher(const string &self_path,

const blaze_util::Path jvm_path = startup_options.GetJvm();
const string server_jar_path = GetServerJarPath(archive_contents);
const vector<string> server_exe_args = GetServerExeArgs(

const blaze_util::Path server_exe =
startup_options.GetExe(jvm_path, server_jar_path);

vector<string> server_exe_args = GetServerExeArgs(
jvm_path,
server_jar_path,
archive_contents,
install_md5,
workspace_layout,
workspace,
startup_options);
#if !defined(CAN_FIND_OWN_EXECUTABLE_PATH)
server_exe_args[0] = server_exe.AsNativePath();
#endif

KillRunningServerIfDifferentStartupOptions(
startup_options, server_exe_args, logging_info, blaze_server);

const blaze_util::Path server_exe =
startup_options.GetExe(jvm_path, server_jar_path);

const blaze_util::Path server_dir =
blaze_util::Path(startup_options.output_base).GetRelative("server");
if (IsServerMode(option_processor.GetCommand())) {
Expand All @@ -1558,7 +1562,11 @@ int Main(int argc, const char *const *argv, WorkspaceLayout *workspace_layout,
new blaze_util::BazelLogHandler());
blaze_util::SetLogHandler(std::move(default_handler));

#if defined(CAN_FIND_OWN_EXECUTABLE_PATH)
const string self_path = GetSelfPath();
#else
const string self_path = GetSelfPath(argv[0]);
#endif

if (argc == 2 && strcmp(argv[1], "--version") == 0) {
PrintVersionInfo(self_path, option_processor->GetLowercaseProductName());
Expand Down
168 changes: 168 additions & 0 deletions src/main/cpp/blaze_util_openbsd.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <errno.h> // errno, ENAMETOOLONG
#include <limits.h>
#include <pwd.h>
#include <signal.h>
#include <spawn.h>
#include <stdlib.h>
#include <string.h> // strerror
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/util/errors.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/path.h"
#include "src/main/cpp/util/port.h"
#include "src/main/cpp/util/strings.h"

namespace blaze {

using blaze_util::GetLastErrorString;
using std::string;

string GetOutputRoot() {
char buf[2048];
struct passwd pwbuf;
struct passwd *pw = NULL;
int uid = getuid();
int r = getpwuid_r(uid, &pwbuf, buf, 2048, &pw);
if (r != -1 && pw != NULL) {
return blaze_util::JoinPath(pw->pw_dir, ".cache/bazel");
} else {
return "/tmp";
}
}

void WarnFilesystemType(const blaze_util::Path &output_base) {
struct statfs buf = {};
if (statfs(output_base.AsNativePath().c_str(), &buf) < 0) {
BAZEL_LOG(WARNING) << "couldn't get file system type information for '"
<< output_base.AsPrintablePath()
<< "': " << strerror(errno);
return;
}

if (strcmp(buf.f_fstypename, "nfs") == 0) {
BAZEL_LOG(WARNING) << "Output base '" << output_base.AsPrintablePath()
<< "' is on NFS. This may lead to surprising failures "
"and undetermined behavior.";
}
}

// OpenBSD does not provide an API for a running process to find the path of
// its own executable, so we try to figure out the path by inspecting argv[0].
// In theory this is inadequate, since the parent process can set argv[0] to
// anything, but in practice this is good enough.
string GetSelfPath(const string& argv0) {
// TODO(aldersondrive): Add a new --bazel_executable_path startup option
// only on platforms that need it), and inspect it here. If it's set, use its
// value instead of applying the heuristics below.

// If argv[0] starts with a slash, it's an absolute path. Use it.
if (argv0.length() > 0 && argv0[0] == '/') {
return argv0;
}

// Otherwise, if argv[0] contains a slash, then it's a relative path. Prepend
// the current directory to form an absolute path.
if (argv0.length() > 0 && argv0.find('/') != string::npos) {
char buf[PATH_MAX];
if (getcwd(buf, sizeof(buf)) == nullptr) {
BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR) << "getcwd failed";
}
return string(buf) + "/" + argv0;
}

// TODO(aldersondrive): Try to find the executable by inspecting the 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.";
return ""; // Never executed. Needed so compiler does not complain.
}

uint64_t GetMillisecondsMonotonic() {
struct timespec ts = {};
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000LL + (ts.tv_nsec / 1000000LL);
}

void SetScheduling(bool batch_cpu_scheduling, int io_nice_level) {
// Stubbed out so we can compile for OpenBSD.
}

blaze_util::Path GetProcessCWD(int pid) {
// OpenBSD does not support looking up the working directory of another
// process.
return blaze_util::Path("");
}

bool IsSharedLibrary(const string &filename) {
return blaze_util::ends_with(filename, ".so");
}

string GetSystemJavabase() {
// If JAVA_HOME is defined, then use it as default.
string javahome = GetPathEnv("JAVA_HOME");

if (!javahome.empty()) {
string javac = blaze_util::JoinPath(javahome, "bin/javac");
if (access(javac.c_str(), X_OK) == 0) {
return javahome;
}
BAZEL_LOG(WARNING)
<< "Ignoring JAVA_HOME, because it must point to a JDK, not a JRE.";
}

return "/usr/local/jdk-1.8.0";
}

int ConfigureDaemonProcess(posix_spawnattr_t *attrp,
const StartupOptions &options) {
// No interesting platform-specific details to configure on this platform.
return 0;
}

void WriteSystemSpecificProcessIdentifier(const blaze_util::Path &server_dir,
pid_t server_pid) {}

bool VerifyServerProcess(int pid, const blaze_util::Path &output_base) {
// TODO(lberki): This only checks for the process's existence, not whether
// its start time matches. Therefore this might accidentally kill an
// unrelated process if the server died and the PID got reused.
return killpg(pid, 0) == 0;
}

// Not supported.
void ExcludePathFromBackup(const blaze_util::Path &path) {}

int32_t GetExplicitSystemLimit(const int resource) {
return -1;
}

} // namespace blaze
9 changes: 7 additions & 2 deletions src/main/cpp/blaze_util_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,13 @@ void SigPrintf(const char *format, ...);

std::string GetProcessIdAsString();

// Get an absolute path to the binary being executed that is guaranteed to be
// Gets an absolute path to the binary being executed that is guaranteed to be
// readable.
#if defined(CAN_FIND_OWN_EXECUTABLE_PATH)
std::string GetSelfPath();
#else
std::string GetSelfPath(const std::string& argv0);
#endif

// Returns the directory Bazel can use to store output.
std::string GetOutputRoot();
Expand All @@ -129,7 +133,8 @@ uint64_t GetMillisecondsMonotonic();
// on Linux, so it should only be called when necessary.
void SetScheduling(bool batch_cpu_scheduling, int io_nice_level);

// Returns the cwd for a process.
// Returns the cwd for a process, or an empty string if the directory is
// unknown.
blaze_util::Path GetProcessCWD(int pid);

bool IsSharedLibrary(const std::string& filename);
Expand Down
15 changes: 15 additions & 0 deletions src/main/cpp/util/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,21 @@
#endif


// CAN_FIND_OWN_EXECUTABLE_PATH
//
// Indicates that a running process can find a path to its own executable.
#if !defined(__OpenBSD__)
#define CAN_FIND_OWN_EXECUTABLE_PATH
#endif

// HAVE_EMULTIHOP
//
// Indicates that errno.h defines EMULTIHOP.
#if !defined(__OpenBSD__)
#define HAVE_EMULTIHOP
#endif


// Linux I/O priorities support is available only in later versions of glibc.
// Therefore, we include some of the needed definitions here. May need to
// be removed once we switch to a new version of glibc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class ShellConfiguration extends BuildConfiguration.Fragment {
ImmutableMap.<OS, PathFragment>builder()
.put(OS.WINDOWS, PathFragment.create("c:/tools/msys64/usr/bin/bash.exe"))
.put(OS.FREEBSD, PathFragment.create("/usr/local/bin/bash"))
.put(OS.OPENBSD, PathFragment.create("/usr/local/bin/bash"))
.build();

private final PathFragment shellExecutable;
Expand Down
Loading