Repository: bazelbuild/bazel
Issue: cc_configure rules do not work with Clang on Linux
Labels: type: feature request
P3
team-Rules-CPP

### Description of the problem / feature request / question:
The cc_autoconf repository rule does not work with Clang on Linux, but rather spits out a number of warnings:
clang: warning: -Wl,-z,-relro,-z,now: 'linker' input unused

and the error:
clang: error: unsupported option '-pass-exit-codes'

I suspect there are further issues, but these are just the first encountered.  Additionally, it would be nice if the repository rule itself allowed a bit more flexibility.  I know they are experimental, but it would be nice if there was a middle ground between "entirely automatic" and "entirely manual" when configuring the C compiler to use.  Some nice-to-haves:

Compiler name (used by _find_cc).  In our case, GCC doesn't work and we need Clang.
`cxx_flags`: In particular, specifying the required version of C++ via `-std=c++11`, etc.

### If possible, provide a minimal example to reproduce the problem:
CC=/usr/bin/clang bazel build //any:cc_rule

### Environment info
* Operating System: Linux
* Bazel version (output of `bazel info release`): release 0.4.0 (But still present in HEAD)


Issue comments:
Hi Shahms,

Thank you for the report, I'll try to improve the clang support in cc_configure.bzl when I'll have spare cycles. If in the meantime you feel like it, feel free to tackle it yourself, cc_configure.bzl is not too complicated. If not, no worries, I will get to it eventually :)
Cheers
Piggybacking on this, since it's the same issue, just on different OS: builds on macOS fail if GCC is installed in the system, because Bazel prefers it over Clang (even though `/usr/bin/cc` still points to `clang`), which leads to a case when Clang-only flags are passed to GCC, because `if darwin` check in `cc_configure.bzl` should really be a `if clang` check.
Hi Piotr,

bazel doesn't look at /usr/bin/cc, but what you could do is to set CC env var to clang and blaze will take it. Altough it is probably reasonable to autodetect gcc on macOS, cc_configure.bzl can only get you so far. At some point you will have to provide your own CROSSTOOL file with all the specific requirements of your environment. Luckily, we are making CROSSTOOL more expressive and nicer to work with almost every day now :)
Marcel, but my problem is not with (lack of) auto-detection of GCC on macOS, it's with the fact that Bazel prefers GCC over Clang (i.e. behavior changes without any changes to Bazel usage, depending on whether or not GCC is available in the `$PATH`), which results in failed builds, because the checks in `cc_configre.bzl` are platform-specific and not compiler-specific.
I see, that is indeed incorrect. I'll take a look once I get rid of some higher priority issues in my queue. Thanks Piotr!
Created a minimal patch adding `-pass-exit-codes` through the `_add_option_if_supported` guard.
https://bazel-review.googlesource.com/#/c/8070/
Thanks Markus so much!  Importing.
This looks fixed to me, please shout if it's not true.

Pull request review comments:

Patch that resolved the issue:
diff --git a/tools/cpp/windows_cc_configure.bzl b/tools/cpp/windows_cc_configure.bzl
index 54a3a8c4b4b5a3..2c0952769adbb0 100644
--- a/tools/cpp/windows_cc_configure.bzl
+++ b/tools/cpp/windows_cc_configure.bzl
@@ -341,6 +341,14 @@ def _use_clang_cl(repository_ctx):
     """Returns True if USE_CLANG_CL is set to 1."""
     return repository_ctx.os.environ.get("USE_CLANG_CL", default = "0") == "1"
 
+def _get_clang_version(repository_ctx, clang_cl):
+    result = repository_ctx.execute([clang_cl, "-v"])
+    if result.return_code != 0:
+        auto_configure_fail("Failed to get clang version by running \"%s -v\"" % clang_cl)
+    # Stderr should look like "clang version X.X.X ..."
+    return result.stderr.strip().split(" ")[2]
+
+
 def configure_windows_toolchain(repository_ctx):
     """Configure C++ toolchain on Windows."""
     paths = resolve_labels(repository_ctx, [
@@ -427,7 +435,11 @@ def configure_windows_toolchain(repository_ctx):
                                 "Please install Clang via http://releases.llvm.org/download.html\n")
         cl_path = find_llvm_tool(repository_ctx, llvm_path, "clang-cl.exe")
         link_path = find_llvm_tool(repository_ctx, llvm_path, "lld-link.exe")
+        if not link_path:
+            link_path = find_msvc_tool(repository_ctx, vc_path, "link.exe")
         lib_path = find_llvm_tool(repository_ctx, llvm_path, "llvm-lib.exe")
+        if not lib_path:
+            lib_path = find_msvc_tool(repository_ctx, vc_path, "lib.exe")
     else:
         cl_path = find_msvc_tool(repository_ctx, vc_path, "cl.exe")
         link_path = find_msvc_tool(repository_ctx, vc_path, "link.exe")
@@ -440,8 +452,12 @@ def configure_windows_toolchain(repository_ctx):
         if path:
             escaped_cxx_include_directories.append("cxx_builtin_include_directory: \"%s\"" % path)
     if llvm_path:
-        clang_include_path = (llvm_path + "\\lib\\clang").replace("\\", "\\\\")
+        clang_version = _get_clang_version(repository_ctx, cl_path)
+        clang_dir = llvm_path + "\\lib\\clang\\" + clang_version
+        clang_include_path = (clang_dir + "\\include").replace("\\", "\\\\")
         escaped_cxx_include_directories.append("cxx_builtin_include_directory: \"%s\"" % clang_include_path)
+        clang_lib_path = (clang_dir + "\\lib\\windows").replace("\\", "\\\\")
+        escaped_lib_paths = escaped_lib_paths + ";" + clang_lib_path
 
     support_debug_fastlink = _is_support_debug_fastlink(repository_ctx, link_path)
 


Test patch: