From c5cde65bc6974e9f1f13c4ea5cdb7beca93f6148 Mon Sep 17 00:00:00 2001 From: mehrdadn Date: Tue, 21 Jul 2020 13:35:29 -0700 Subject: [PATCH] Add bazel to the PATH in setup.py (#9590) Co-authored-by: Mehrdad --- ci/travis/install-bazel.sh | 8 ++++--- doc/source/development.rst | 1 + python/setup.py | 44 ++++++++++++++++++++++++++++++++++---- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/ci/travis/install-bazel.sh b/ci/travis/install-bazel.sh index 67549e289..138581931 100755 --- a/ci/travis/install-bazel.sh +++ b/ci/travis/install-bazel.sh @@ -6,7 +6,6 @@ ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}")"; pwd) arg1="${1-}" -version="3.2.0" achitecture="${HOSTTYPE}" platform="unknown" case "${OSTYPE}" in @@ -30,7 +29,8 @@ esac # Sanity check: Verify we have symlinks where we expect them, or Bazel can produce weird "missing input file" errors. # This is most likely to occur on Windows, where symlinks are sometimes disabled by default. -{ git ls-files -s || true; } | { +{ git ls-files -s 2>/dev/null || true; } | ( + set +x missing_symlinks=() while read -r mode digest sn path; do if [ "${mode}" = 120000 ]; then @@ -42,8 +42,10 @@ esac echo "For a correct build, please run 'git config --local core.symlinks true' and re-run git checkout." 1>&2 false fi -} +) +python="$(command -v python3 || command -v python || echo python)" +version="$("${python}" -s -c "import runpy, sys; runpy.run_path(sys.argv.pop(), run_name='__api__')" bazel_version "${ROOT_DIR}/../../python/setup.py")" if [ "${OSTYPE}" = "msys" ]; then target="${MINGW_DIR-/usr}/bin/bazel.exe" mkdir -p "${target%/*}" diff --git a/doc/source/development.rst b/doc/source/development.rst index 82c931aa5..7a47c267d 100644 --- a/doc/source/development.rst +++ b/doc/source/development.rst @@ -80,6 +80,7 @@ Ray can be built from the repository as follows. git clone https://github.com/ray-project/ray.git # Install Bazel. + # (Windows users: please manually place Bazel in your PATH, and point BAZEL_SH to MSYS2's Bash.) ray/ci/travis/install-bazel.sh # Optionally build the dashboard diff --git a/python/setup.py b/python/setup.py index 2cd44d809..1df98653e 100644 --- a/python/setup.py +++ b/python/setup.py @@ -1,6 +1,7 @@ import argparse import glob import io +import logging import os import re import shutil @@ -16,6 +17,8 @@ import urllib.error import urllib.parse import urllib.request +logger = logging.getLogger(__name__) + # Ideally, we could include these files by putting them in a # MANIFEST.in or using the package_data argument to setup, but the # MANIFEST.in gets applied at the very beginning when setup.py runs @@ -23,6 +26,7 @@ import urllib.request # manually. SUPPORTED_PYTHONS = [(3, 5), (3, 6), (3, 7), (3, 8)] +SUPPORTED_BAZEL = (3, 2, 0) ROOT_DIR = os.path.dirname(__file__) BUILD_JAVA = os.getenv("RAY_INSTALL_JAVA") == "1" @@ -129,6 +133,28 @@ def is_invalid_windows_platform(): return platform == "msys" or (platform == "win32" and ver and "GCC" in ver) +# Calls Bazel in PATH, falling back to the standard user installatation path +# (~/.bazel/bin/bazel) if it isn't found. +def bazel_invoke(invoker, cmdline, *args, **kwargs): + home = os.path.expanduser("~") + candidates = ["bazel"] + if sys.platform == "win32": + mingw_dir = os.getenv("MINGW_DIR") + if mingw_dir: + candidates.append(mingw_dir + "/bin/bazel.exe") + else: + candidates.append(os.path.join(home, ".bazel", "bin", "bazel")) + result = None + for i, cmd in enumerate(candidates): + try: + result = invoker([cmd] + cmdline, *args, **kwargs) + break + except IOError: + if i >= len(candidates) - 1: + raise + return result + + def download(url): try: result = urllib.request.urlopen(url).read() @@ -221,12 +247,19 @@ def build(build_python, build_java): ] + pip_packages, env=dict(os.environ, CC="gcc")) - bazel = os.getenv("BAZEL_EXECUTABLE", "bazel") + version_info = bazel_invoke(subprocess.check_output, ["--version"]) + bazel_version_str = version_info.rstrip().decode("utf-8").split(" ", 1)[1] + bazel_version = tuple(map(int, bazel_version_str.split("."))) + if bazel_version <= SUPPORTED_BAZEL: + logger.warning("Expected Bazel version {} but found {}", + bazel_version, SUPPORTED_BAZEL) + bazel_targets = [] bazel_targets += ["//:ray_pkg"] if build_python else [] bazel_targets += ["//java:ray_java_pkg"] if build_java else [] - return subprocess.check_call( - [bazel, "build", "--verbose_failures", "--"] + bazel_targets, + return bazel_invoke( + subprocess.check_call, + ["build", "--verbose_failures", "--"] + bazel_targets, env=bazel_env) @@ -318,7 +351,8 @@ def pip_run(build_ext): def api_main(program, *args): parser = argparse.ArgumentParser() - parser.add_argument("command", type=str, choices=["build", "help"]) + choices = ["build", "bazel_version", "help"] + parser.add_argument("command", type=str, choices=choices) parser.add_argument( "-l", "--language", @@ -341,6 +375,8 @@ def api_main(program, *args): else: raise ValueError("invalid language: {!r}".format(lang)) result = build(**kwargs) + elif parsed_args.command == "bazel_version": + print(".".join(map(str, SUPPORTED_BAZEL))) elif parsed_args.command == "help": parser.print_help() else: