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
diff --git a/tools/cpp/cc_configure.bzl b/tools/cpp/cc_configure.bzl
index 37f5c68..6582cc3 100644
--- a/tools/cpp/cc_configure.bzl
+++ b/tools/cpp/cc_configure.bzl
@@ -21,6 +21,14 @@
"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 @@
"@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 @@
"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 0498881..2f6ff00 100644
--- a/tools/cpp/osx_cc_configure.bzl
+++ b/tools/cpp/osx_cc_configure.bzl
@@ -63,11 +63,18 @@
"@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(