Handle Xcode command line tools when Xcode is installed
Previously if you had a version of Xcode installed, but the command line
tools were selected with `xcode-select`, bazel would fail with this error:
```
local_config_cc/BUILD:62:5: in apple_cc_toolchain rule @local_config_cc//:cc-compiler-armeabi-v7a: Xcode version must be specified to use an Apple CROSSTOOL. If your Xcode version has changed recently, verify that "xcode-select -p" is correct and then try: "bazel shutdown" to re-run Xcode configuration
```
This happened because we ran `xcodebuild -version` which fails when
the command line tools are selected with this error:
```
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
```
And therefore xcode_autoconf didn't complete successfully, but
osx_cc_configure did because xcode_locator happily found the Xcode you
had installed but not selected.
With this change the behavior is, if there's an xcodebuild error during
xcode_autoconf, it's ignored (which is ok because xcode_locator will
still fail if no Xcode versions are installed), and if there are Xcode
versions discovered, pick the newest (by a dumb string sort) as the
default version.
In all other cases this shouldn't change behavior for anyone because:
1. With no command line tools and no Xcodes this code doesn't get hit at
all
2. With only the command line tools installed xcode_locator returns no
Xcode versions and xcode_autoconf will still exit early just like
before, just from xcode_locator returning nothing instead of
`xcodebuild -version` failing
3. With `xcode-select` set to a Xcode the previous behavior of choosing
a default Xcode will be the same since `xcodebuild -version` will
succeed.
Fixes https://github.com/bazelbuild/bazel/issues/5178
Closes #8975.
PiperOrigin-RevId: 298802222
diff --git a/tools/osx/xcode_configure.bzl b/tools/osx/xcode_configure.bzl
index 566b513..d9a859a 100644
--- a/tools/osx/xcode_configure.bzl
+++ b/tools/osx/xcode_configure.bzl
@@ -186,20 +186,6 @@
_EXECUTE_TIMEOUT,
)
- # "xcodebuild -version" failing may be indicative of no versions of xcode
- # installed, which is an acceptable machine configuration to have for using
- # bazel. Thus no print warning should be emitted here.
- if (xcodebuild_result.return_code != 0):
- error_msg = (
- "Running xcodebuild -version failed, " +
- "return code {code}, stderr: {err}, stdout: {out}"
- ).format(
- code = xcodebuild_result.return_code,
- err = xcodebuild_result.stderr,
- out = xcodebuild_result.stdout,
- )
- return VERSION_CONFIG_STUB + "\n# Error: " + error_msg.replace("\n", " ") + "\n"
-
(toolchains, xcodeloc_err) = run_xcode_locator(
repository_ctx,
Label(repository_ctx.attr.xcode_locator),
@@ -208,8 +194,15 @@
if xcodeloc_err:
return VERSION_CONFIG_STUB + "\n# Error: " + xcodeloc_err + "\n"
- default_xcode_version = _search_string(xcodebuild_result.stdout, "Xcode ", "\n")
- default_xcode_build_version = _search_string(xcodebuild_result.stdout, "Build version ", "\n")
+ default_xcode_version = ""
+ default_xcode_build_version = ""
+ if xcodebuild_result.return_code == 0:
+ default_xcode_version = _search_string(xcodebuild_result.stdout, "Xcode ", "\n")
+ default_xcode_build_version = _search_string(
+ xcodebuild_result.stdout,
+ "Build version ",
+ "\n",
+ )
default_xcode_target = ""
target_names = []
buildcontents = ""
@@ -219,21 +212,34 @@
aliases = toolchain.aliases
developer_dir = toolchain.developer_dir
target_name = "version%s" % version.replace(".", "_")
- buildcontents += _xcode_version_output(repository_ctx, target_name, version, aliases, developer_dir)
- target_names.append("':%s'" % target_name)
- if (version.startswith(default_xcode_version) and version.endswith(default_xcode_build_version)):
- default_xcode_target = target_name
+ buildcontents += _xcode_version_output(
+ repository_ctx,
+ target_name,
+ version,
+ aliases,
+ developer_dir,
+ )
+ target_label = "':%s'" % target_name
+ target_names.append(target_label)
+ if (version.startswith(default_xcode_version) and
+ version.endswith(default_xcode_build_version)):
+ default_xcode_target = target_label
buildcontents += "xcode_config(name = 'host_xcodes',"
if target_names:
buildcontents += "\n versions = [%s]," % ", ".join(target_names)
+ if not default_xcode_target and target_names:
+ default_xcode_target = sorted(target_names, reverse = True)[0]
+ print("No default Xcode version is set with 'xcode-select'; picking %s" %
+ default_xcode_target)
if default_xcode_target:
- buildcontents += "\n default = ':%s'," % default_xcode_target
+ buildcontents += "\n default = %s," % default_xcode_target
+
buildcontents += "\n)\n"
buildcontents += "available_xcodes(name = 'host_available_xcodes',"
if target_names:
buildcontents += "\n versions = [%s]," % ", ".join(target_names)
if default_xcode_target:
- buildcontents += "\n default = ':%s'," % default_xcode_target
+ buildcontents += "\n default = %s," % default_xcode_target
buildcontents += "\n)\n"
if repository_ctx.attr.remote_xcode:
buildcontents += "xcode_config(name = 'all_xcodes',"