From 7984a157efe4c29aec7e6f446773d2b700650108 Mon Sep 17 00:00:00 2001 From: Marcel Hlopko Date: Wed, 29 May 2019 10:31:42 -0700 Subject: [PATCH] Make split cc_configure work on Darwin with only CLT installed Fixes https://github.com/bazelbuild/bazel/issues/8479. To keep this backwards compatible we have to detect xcode early in the Bazel build (even when no C++ is being built). In cases where user knows there is xcode, or when they know it won't be needed, I'm adding environment variable `BAZEL_USE_XCODE_TOOLCHAIN`. When set to `1`, Bazel will not try to detect xcode, it will assume it is there. Makes https://github.com/bazelbuild/bazel/issues/6926 a little bit more complicated. RELNOTES: `BAZEL_USE_XCODE_TOOLCHAIN=1` tells Bazel not to look for Xcode to decide whether to enable toolchains for Apple rules, but to assume Xcode is available. Can be also used when building on Darwin and no C++ or ObjC is being built, so there is no need to detect Xcode. Closes #8492. PiperOrigin-RevId: 250518695 --- tools/cpp/cc_configure.bzl | 49 +++++++++++++++++++++++++++------- tools/cpp/osx_cc_configure.bzl | 7 +++++ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/tools/cpp/cc_configure.bzl b/tools/cpp/cc_configure.bzl index 37f5c689b64eaf..6582cc32f2fa84 100644 --- a/tools/cpp/cc_configure.bzl +++ b/tools/cpp/cc_configure.bzl @@ -21,6 +21,14 @@ load( "get_cpu_value", "resolve_labels", ) +load("@bazel_tools//tools/osx:xcode_configure.bzl", "run_xcode_locator") + +def _generate_cpp_only_build_file(repository_ctx, cpu_value, paths): + repository_ctx.template( + "BUILD", + paths["@bazel_tools//tools/cpp:BUILD.toolchains.tpl"], + {"%{name}": cpu_value}, + ) def cc_autoconf_toolchains_impl(repository_ctx): """Generate BUILD file with 'toolchain' targets for the local host C++ toolchain. @@ -32,21 +40,41 @@ def cc_autoconf_toolchains_impl(repository_ctx): "@bazel_tools//tools/cpp:BUILD.toolchains.tpl", "@bazel_tools//tools/osx/crosstool:BUILD.toolchains", "@bazel_tools//tools/osx/crosstool:osx_archs.bzl", + "@bazel_tools//tools/osx:xcode_locator.m", ]) env = repository_ctx.os.environ cpu_value = get_cpu_value(repository_ctx) - if "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" in env and env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] == "1": + + # Should we try to find C++ toolchain at all? If not, we don't have to generate toolchains for C++ at all. + should_detect_cpp_toolchain = "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" not in env or env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] != "1" + + # Should we unconditionally *not* use xcode? If so, we don't have to run Xcode locator ever. + should_use_cpp_only_toolchain = "BAZEL_USE_CPP_ONLY_TOOLCHAIN" in env and env["BAZEL_USE_CPP_ONLY_TOOLCHAIN"] == "1" + + # Should we unconditionally use xcode? If so, we don't have to run Xcode locator now. + should_use_xcode = "BAZEL_USE_XCODE_TOOLCHAIN" in env and env["BAZEL_USE_XCODE_TOOLCHAIN"] == "1" + + if not should_detect_cpp_toolchain: repository_ctx.file("BUILD", "# C++ toolchain autoconfiguration was disabled by BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN env variable.") - elif (cpu_value == "darwin" and - ("BAZEL_USE_CPP_ONLY_TOOLCHAIN" not in env or env["BAZEL_USE_CPP_ONLY_TOOLCHAIN"] != "1")): - repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:BUILD.toolchains"], "BUILD") - repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:osx_archs.bzl"], "osx_archs.bzl") + elif cpu_value == "darwin" and not should_use_cpp_only_toolchain: + xcode_toolchains = [] + + # Only detect xcode if the user didn't tell us it will be there. + if not should_use_xcode: + # TODO(#6926): Unify C++ and ObjC toolchains so we don't have to run xcode locator to generate toolchain targets. + # And also so we don't have to keep this code in sync with //tools/cpp:osx_cc_configure.bzl. + (xcode_toolchains, _xcodeloc_err) = run_xcode_locator( + repository_ctx, + paths["@bazel_tools//tools/osx:xcode_locator.m"], + ) + + if should_use_xcode or xcode_toolchains: + repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:BUILD.toolchains"], "BUILD") + repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:osx_archs.bzl"], "osx_archs.bzl") + else: + _generate_cpp_only_build_file(repository_ctx, cpu_value, paths) else: - repository_ctx.template( - "BUILD", - paths["@bazel_tools//tools/cpp:BUILD.toolchains.tpl"], - {"%{name}": cpu_value}, - ) + _generate_cpp_only_build_file(repository_ctx, cpu_value, paths) cc_autoconf_toolchains = repository_rule( environ = [ @@ -104,6 +132,7 @@ cc_autoconf = repository_rule( "BAZEL_TARGET_LIBC", "BAZEL_TARGET_SYSTEM", "BAZEL_USE_CPP_ONLY_TOOLCHAIN", + "BAZEL_USE_XCODE_TOOLCHAIN", "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", "BAZEL_USE_LLVM_NATIVE_COVERAGE", "BAZEL_VC", diff --git a/tools/cpp/osx_cc_configure.bzl b/tools/cpp/osx_cc_configure.bzl index 04988814ac43d2..2f6ff0008f3ba1 100644 --- a/tools/cpp/osx_cc_configure.bzl +++ b/tools/cpp/osx_cc_configure.bzl @@ -63,11 +63,18 @@ def configure_osx_toolchain(repository_ctx, overriden_tools): "@bazel_tools//tools/osx:xcode_locator.m", ]) + env = repository_ctx.os.environ + should_use_xcode = "BAZEL_USE_XCODE_TOOLCHAIN" in env and env["BAZEL_USE_XCODE_TOOLCHAIN"] == "1" xcode_toolchains = [] + + # Make the following logic in sync with //tools/cpp:cc_configure.bzl#cc_autoconf_toolchains_impl (xcode_toolchains, xcodeloc_err) = run_xcode_locator( repository_ctx, paths["@bazel_tools//tools/osx:xcode_locator.m"], ) + if should_use_xcode and not xcode_toolchains: + fail("BAZEL_USE_XCODE_TOOLCHAIN is set to 1 but Bazel couldn't find Xcode installed on the " + + "system. Verify that 'xcode-select -p' is correct.") if xcode_toolchains: cc = find_cc(repository_ctx, overriden_tools = {}) repository_ctx.template(