Repository: bazelbuild/bazel
Issue: Compatibility with Xcode and Command Line Developer Tools on macOS
Labels: P4
category: rules > ObjC / iOS / J2ObjC
z-team-Apple

### Description of the problem / feature request:

As you know, `xcode-select` is used to select the developer directory on macOS. Both Xcode and Command Line Developer Tools are installed in my Mac. Due to the reason that the compiler Xcode provides seems not to support the OpenMP, I need to switch to the Command Line Developer Tools. I've executed the command `sudo xcode-select -s /Library/Developer/CommandLineTools`, but when I build with Bazel, it still told me that `Xcode version must be specified to use an Apple CROSSTOOL. If your Xcode version has changed recently, try: "bazel clean --expunge" to re-run Xcode configuration`. And of course, I've cleaned the workspace and rerun the command, but it was useless.

### Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

1. Install Xcode, and now the active developer directory will be switched to Xcode.
2. Open the `Terminal.app`, execute `sudo xcode-select -s /Library/Developer/CommandLineTools` to switch back to the Command Line Developer Tools.
3. Build with Bazel.

### What operating system are you running Bazel on?

`macOS High Sierra 10.13.4`

### What's the output of `bazel info release`?

`release 0.12.0-homebrew`

### What's the output of `git remote get-url origin ; git rev-parse master ; git rev-parse HEAD` ?

Private branch of TensorFlow.

###  Have you found anything relevant by searching the web?

Nope.

### Any other information, logs, or outputs that you want to share?
```Shell
$ bazel clean --expunge
WARNING: ignoring http_proxy in environment.
INFO: Starting clean.
$ bazel build --copt=-DINTEL_MKL_DNN --config=mkl -c opt //tensorflow/tools/pip_package:build_pip_package
WARNING: ignoring http_proxy in environment.
..............
WARNING: /private/var/tmp/_bazel_shilei/d84c9594019614910b5a52be437fcea4/external/protobuf_archive/WORKSPACE:1: Workspace name in /private/var/tmp/_bazel_shilei/d84c9594019614910b5a52be437fcea4/external/protobuf_archive/WORKSPACE (@com_google_protobuf) does not match the name given in the repository's definition (@protobuf_archive); this will cause a build error in future versions
ERROR: /private/var/tmp/_bazel_shilei/d84c9594019614910b5a52be437fcea4/external/local_config_cc/BUILD:50:5: in apple_cc_toolchain rule @local_config_cc//:cc-compiler-darwin_x86_64: Xcode version must be specified to use an Apple CROSSTOOL. If your Xcode version has changed recently, try: "bazel clean --expunge" to re-run Xcode configuration
ERROR: Analysis of target '//tensorflow/tools/pip_package:build_pip_package' failed; build aborted: Analysis of target '@local_config_cc//:cc-compiler-darwin_x86_64' failed; build aborted
INFO: Elapsed time: 13.244s
FAILED: Build did NOT complete successfully (63 packages loaded)
    currently loading: tensorflow/python ... (2 packages)
$ xcode-select -p
/Library/Developer/CommandLineTools
```

Issue comments:
In addition, if the Xcode is not installed, Bazel could work well. A same issue occurred before, and I just uninstalled the Xcode, and then it could work.
Are you using VSCode by any chance? 
@sergiocampama Yeap. Anything to do with it?
Check out https://github.com/bazelbuild/bazel/issues/4603, it has a long discussion on how VSCode messes up with the workspace. Try running expunge and build after closing VSCode
@sergiocampama Really?! Unbelievable…Thanks for your notification. I'll try it tomorrow and feedback to you.
Hi @sergiocampama I've closed the VSCode, cleaned up the project and tried to build with Bazel, but unfortunately, it failed too with the same error.
@sergiocampama should this be moved to https://github.com/bazelbuild/rules_apple/issues?
@dslomov  The xcode locator functionality is provided to rules_apple by bazel. Furthermore, the xcode locator functionality is also depended upon from the C++ rules so they work on macOS. This issue belongs in bazel, not rules_apple.
Update: This issue still exists in the the latest released version 0.13.1.
Is this still an issue?
@jin No idea. I've moved to new project.
I've just hit this on a fresh Bazel clone (https://github.com/bazelbuild/bazel/commit/bc5a9b1f0c55e97f9e9962384d10a03042bf05cb):

```console
~/Desktop
➜  Desktop git clone git@github.com:bazelbuild/bazel.git
Cloning into 'bazel'...
remote: Enumerating objects: 157, done.
remote: Counting objects: 100% (157/157), done.
remote: Compressing objects: 100% (82/82), done.
remote: Total 408534 (delta 61), reused 114 (delta 48), pack-reused 408377
Receiving objects: 100% (408534/408534), 651.51 MiB | 57.78 MiB/s, done.
Resolving deltas: 100% (248658/248658), done.
Checking out files: 100% (11232/11232), done.
➜  Desktop cd bazel
➜  bazel git:(master) bazel build //src:bazel
Starting local Bazel server and connecting to it...
DEBUG: /private/var/tmp/_bazel_azinnatullin/28ee7600c34548f30dad58754d5eebde/external/bazel_toolchains/rules/rbe_repo/checked_in.bzl:103:9: rbe_ubuntu1804_java11 not using checked in configs as detect_java_home was set to True
DEBUG: /private/var/tmp/_bazel_azinnatullin/28ee7600c34548f30dad58754d5eebde/external/bazel_toolchains/rules/rbe_repo/checked_in.bzl:103:9: rbe_ubuntu1604_java8 not using checked in configs as detect_java_home was set to True
ERROR: /private/var/tmp/_bazel_azinnatullin/28ee7600c34548f30dad58754d5eebde/external/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
INFO: Call stack for the definition of repository 'remotejdk11_macos' which is a http_archive (rule definition at /private/var/tmp/_bazel_azinnatullin/28ee7600c34548f30dad58754d5eebde/external/bazel_tools/tools/build_defs/repo/http.bzl:237:16):
 - /DEFAULT.WORKSPACE.SUFFIX:219:1
INFO: Call stack for the definition of repository 'remote_java_tools_darwin' which is a http_archive (rule definition at /private/var/tmp/_bazel_azinnatullin/28ee7600c34548f30dad58754d5eebde/external/bazel_tools/tools/build_defs/repo/http.bzl:237:16):
 - /DEFAULT.WORKSPACE.SUFFIX:255:1
ERROR: Analysis of target '//src:bazel' failed; build aborted: Analysis of target '@local_config_cc//:cc-compiler-armeabi-v7a' failed; build aborted
INFO: Elapsed time: 5.700s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (160 packages loaded, 2040 targets configured)
```

Environment:

- macOS 10.14.6
- Xcode 10.3

I can confirm that I haven't run `xcode-select` ever, I'm not an iOS/macOS developer and reasons I have Xcode installed is because I played with Swift a bit.

I was able to fix it after some googling:

```console
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
bazel shutdown
bazel build //src:bazel
```

It seems that Bazel should be more resistant to system environment like this or this Xcode quirk should be reflected on the [Setting up your coding environment](https://bazel.build/contributing.html#setting-up-your-coding-environment) page :)
This is very easy to reproduce for me:

```
% xcode-select -p
/Applications/Xcode-11.0.0b4.app/Contents/Developer
% sudo xcode-select -r
% sudo xcode-select -p
/Library/Developer/CommandLineTools
% bazel build src:bazel-dev
Starting local Bazel server and connecting to it...
DEBUG: /private/var/tmp/_bazel_ksmiley/5ef608190b288a339c09ffb210204e7f/external/bazel_toolchains/rules/rbe_repo/checked_in.bzl:103:9: rbe_ubuntu1804_java11 not using checked in configs as detect_java_home was set to True
DEBUG: /private/var/tmp/_bazel_ksmiley/5ef608190b288a339c09ffb210204e7f/external/bazel_toolchains/rules/rbe_repo/checked_in.bzl:103:9: rbe_ubuntu1604_java8 not using checked in configs as detect_java_home was set to True
ERROR: /private/var/tmp/_bazel_ksmiley/5ef608190b288a339c09ffb210204e7f/external/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
INFO: Call stack for the definition of repository 'remote_java_tools_darwin' which is a http_archive (rule definition at /private/var/tmp/_bazel_ksmiley/5ef608190b288a339c09ffb210204e7f/external/bazel_tools/tools/build_defs/repo/http.bzl:237:16):
 - /DEFAULT.WORKSPACE.SUFFIX:255:1
INFO: Call stack for the definition of repository 'remotejdk11_macos' which is a http_archive (rule definition at /private/var/tmp/_bazel_ksmiley/5ef608190b288a339c09ffb210204e7f/external/bazel_tools/tools/build_defs/repo/http.bzl:237:16):
 - /DEFAULT.WORKSPACE.SUFFIX:219:1
ERROR: Analysis of target '//src:bazel-dev' failed; build aborted: Analysis of target '@local_config_cc//:cc-compiler-armeabi-v7a' failed; build aborted
INFO: Elapsed time: 5.521s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (152 packages loaded, 2240 targets configured)
    currently loading: @io_bazel//third_party/grpc ... (3 packages)
```
I've submitted a fix for this https://github.com/bazelbuild/bazel/pull/8975
Best case scenario, the docs are wrong to instruct users to install command line tools and not full Xcode.  Can we get the above PR merged?
Actually, I wonder if bazel 1.1.0 fixes this.
Is there a specific change you would have expected to fix this? I haven't seen anything related go in
I was thinking this change. Seems to work on my machine, but once I got 1.1.0 working, I could no longer repro with 0.28.1, so I'm not sure what's really going on.

https://github.com/bazelbuild/bazel/commit/bfbaed8aba95aa78a0cd0755e7f470d39b9d84f8

For those who get to this issue via googling: there is a SO answer that solved the issue for me: https://stackoverflow.com/a/46460129

Pull request review comments:

Patch that resolved the issue:
diff --git a/tools/osx/xcode_configure.bzl b/tools/osx/xcode_configure.bzl
index 566b513031f7fc..764f07dd65f971 100644
--- a/tools/osx/xcode_configure.bzl
+++ b/tools/osx/xcode_configure.bzl
@@ -186,20 +186,6 @@ def _darwin_build_file(repository_ctx):
         _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,11 @@ def _darwin_build_file(repository_ctx):
     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 = ""
@@ -220,14 +209,19 @@ def _darwin_build_file(repository_ctx):
         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)
+        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_name
+            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:


Test patch: