Use the libraries included with the clang distribution for bindgen (#820)

* Use the libraries included with the clang distribution for bindgen

* Fall back to the system load path if libstdcxx is not specified

* Regenerate documentation

* Fix bugs and preserve backward compatibility with users of bindgen_clang_*

* Buildifier

* Regenerate documentation

* Re-enable tests

* Generate rpaths correctly

* Skip rpath generation on Windows

* Better comment about why test is disabled

* Add comment about DYLD_LIBRARY_PATH

* buildifier
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index eab4a50..a3a8ea0 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -29,10 +29,8 @@
       - "--" # Allows negative patterns; hack for https://github.com/bazelbuild/continuous-integration/pull/245
       - "..."
       - "@examples//..."
-      # Skip tests for dylib support on osx, since we don't support it yet.
+      # This test requires --incompatible_macos_set_install_name and Bazel 4.2.0+
       - "-@examples//ffi/rust_calling_c:matrix_dylib_test"
-      - "-@examples//ffi/rust_calling_c:matrix_dynamically_linked"
-      - "-@examples//ffi/rust_calling_c/simple/..."
     build_targets: *osx_targets
     test_targets: *osx_targets
     build_flags:
diff --git a/bindgen/BUILD.bazel b/bindgen/BUILD.bazel
index 92543c9..2dc0b2d 100644
--- a/bindgen/BUILD.bazel
+++ b/bindgen/BUILD.bazel
@@ -19,10 +19,13 @@
         "//conditions:default": "@bindgen_clang_linux//:clang",
     }),
     libclang = select({
-        "//rust/platform:osx": "@bindgen_clang_osx//:libclang.so",
-        "//conditions:default": "@bindgen_clang_linux//:libclang.so",
+        "//rust/platform:osx": "@bindgen_clang_osx//:libclang",
+        "//conditions:default": "@bindgen_clang_linux//:libclang",
     }),
-    libstdcxx = "@local_libstdcpp//:libstdc++",
+    libstdcxx = select({
+        "//rust/platform:osx": "@bindgen_clang_osx//:libc++",
+        "//conditions:default": None,
+    }),
 )
 
 toolchain(
diff --git a/bindgen/bindgen.bzl b/bindgen/bindgen.bzl
index d3f7266..2cb8d15 100644
--- a/bindgen/bindgen.bzl
+++ b/bindgen/bindgen.bzl
@@ -87,13 +87,6 @@
     rustfmt_bin = toolchain.rustfmt or rust_toolchain.rustfmt
     clang_bin = toolchain.clang
     libclang = toolchain.libclang
-
-    # TODO: This rule shouldn't need to depend on libstdc++
-    #  This rule requires an explicit dependency on a libstdc++ because
-    #    1. It is a runtime dependency of libclang.so
-    #    2. We cannot locate it in the cc_toolchain yet
-    #  Depending on how libclang.so was compiled, it may try to locate its libstdc++ dependency
-    #  in a way that makes our handling here unnecessary (eg. system /usr/lib/x86_64-linux-gnu/libstdc++.so.6)
     libstdcxx = toolchain.libstdcxx
 
     # rustfmt is not where bindgen expects to find it, so we format manually
@@ -130,8 +123,11 @@
         "RUST_BACKTRACE": "1",
     }
 
+    # Set the dynamic linker search path so that clang uses the libstdcxx from the toolchain.
+    # DYLD_LIBRARY_PATH is LD_LIBRARY_PATH on macOS.
     if libstdcxx:
         env["LD_LIBRARY_PATH"] = ":".join([f.dirname for f in _get_libs_for_static_executable(libstdcxx).to_list()])
+        env["DYLD_LIBRARY_PATH"] = env["LD_LIBRARY_PATH"]
 
     ctx.actions.run(
         executable = bindgen_bin,
@@ -140,9 +136,9 @@
             transitive = [
                 cc_lib[CcInfo].compilation_context.headers,
                 _get_libs_for_static_executable(libclang),
-            ] + [
+            ] + ([
                 _get_libs_for_static_executable(libstdcxx),
-            ] if libstdcxx else [],
+            ] if libstdcxx else []),
         ),
         outputs = [unformatted_output],
         mnemonic = "RustBindgen",
@@ -232,9 +228,10 @@
             providers = [CcInfo],
         ),
         "libstdcxx": attr.label(
-            doc = "A cc_library that satisfies libclang's libstdc++ dependency.",
+            doc = "A cc_library that satisfies libclang's libstdc++ dependency. This is used to make the execution of clang hermetic. If None, system libraries will be used instead.",
             cfg = "exec",
             providers = [CcInfo],
+            mandatory = False,
         ),
         "rustfmt": attr.label(
             doc = "The label of a `rustfmt` executable. If this is provided, generated sources will be formatted.",
diff --git a/bindgen/repositories.bzl b/bindgen/repositories.bzl
index c40b9c3..b9a1b2f 100644
--- a/bindgen/repositories.bzl
+++ b/bindgen/repositories.bzl
@@ -24,11 +24,6 @@
     # nb. The bindgen rule itself should work on any platform.
     _bindgen_clang_repositories()
 
-    maybe(
-        _local_libstdcpp,
-        name = "local_libstdcpp",
-    )
-
     rules_rust_bindgen_fetch_remote_crates()
 
     native.register_toolchains(str(Label("//bindgen:default_bindgen_toolchain")))
@@ -48,19 +43,29 @@
 """
 
 _CLANG_BUILD_FILE = """\
-load("@rules_cc//cc:defs.bzl", "cc_library")
+load("@rules_cc//cc:defs.bzl", "cc_import")
 
 package(default_visibility = ["//visibility:public"])
 
 sh_binary(
     name = "clang",
     srcs = ["bin/clang"],
-    data = glob(["lib/**"]),
 )
 
-cc_library(
+cc_import(
+    name = "libclang",
+    shared_library = "lib/libclang.{suffix}",
+)
+
+alias(
     name = "libclang.so",
-    srcs = ["{}"],
+    actual = ":libclang",
+    deprecation = "Use :libclang instead",
+)
+
+cc_import(
+    name = "libc++",
+    shared_library = "lib/libc++.{suffix}"
 )
 """
 
@@ -72,7 +77,7 @@
         urls = ["https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz"],
         strip_prefix = "clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04",
         sha256 = "b25f592a0c00686f03e3b7db68ca6dc87418f681f4ead4df4745a01d9be63843",
-        build_file_content = _CLANG_BUILD_FILE.format("lib/libclang.so"),
+        build_file_content = _CLANG_BUILD_FILE.format(suffix = "so"),
         workspace_file_content = _COMMON_WORKSPACE.format("bindgen_clang_linux"),
     )
 
@@ -82,32 +87,6 @@
         urls = ["https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-apple-darwin.tar.xz"],
         strip_prefix = "clang+llvm-10.0.0-x86_64-apple-darwin",
         sha256 = "633a833396bf2276094c126b072d52b59aca6249e7ce8eae14c728016edb5e61",
-        build_file_content = _CLANG_BUILD_FILE.format("lib/libclang.dylib"),
+        build_file_content = _CLANG_BUILD_FILE.format(suffix = "dylib"),
         workspace_file_content = _COMMON_WORKSPACE.format("bindgen_clang_osx"),
     )
-
-_LIBSTDCPP_BUILD_FILE = """\
-load("@rules_cc//cc:defs.bzl", "cc_library")
-
-cc_library(
-  name = "libstdc++",
-  srcs = ["{}"],
-  visibility = ["//visibility:public"]
-)
-"""
-
-def _local_libstdcpp_impl(repository_ctx):
-    os = repository_ctx.os.name.lower()
-    if os == "linux":
-        repository_ctx.symlink("/usr/lib/x86_64-linux-gnu/libstdc++.so.6", "libstdc++.so.6")
-        repository_ctx.file("BUILD.bazel", _LIBSTDCPP_BUILD_FILE.format("libstdc++.so.6"))
-    elif os.startswith("mac"):
-        repository_ctx.symlink("/usr/lib/libstdc++.6.dylib", "libstdc++.6.dylib")
-        repository_ctx.file("BUILD.bazel", _LIBSTDCPP_BUILD_FILE.format("libstdc++.6.dylib"))
-    else:
-        fail(os + " is not supported.")
-    repository_ctx.file("WORKSPACE.bazel", _COMMON_WORKSPACE.format(repository_ctx.name))
-
-_local_libstdcpp = repository_rule(
-    implementation = _local_libstdcpp_impl,
-)
diff --git a/docs/flatten.md b/docs/flatten.md
index d6ae3a0..356b3f7 100644
--- a/docs/flatten.md
+++ b/docs/flatten.md
@@ -367,7 +367,7 @@
 | <a id="rust_bindgen_toolchain-bindgen"></a>bindgen |  The label of a <code>bindgen</code> executable.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 | <a id="rust_bindgen_toolchain-clang"></a>clang |  The label of a <code>clang</code> executable.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 | <a id="rust_bindgen_toolchain-libclang"></a>libclang |  A cc_library that provides bindgen's runtime dependency on libclang.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
-| <a id="rust_bindgen_toolchain-libstdcxx"></a>libstdcxx |  A cc_library that satisfies libclang's libstdc++ dependency.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
+| <a id="rust_bindgen_toolchain-libstdcxx"></a>libstdcxx |  A cc_library that satisfies libclang's libstdc++ dependency. This is used to make the execution of clang hermetic. If None, system libraries will be used instead.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 | <a id="rust_bindgen_toolchain-rustfmt"></a>rustfmt |  The label of a <code>rustfmt</code> executable. If this is provided, generated sources will be formatted.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 
 
diff --git a/docs/rust_bindgen.md b/docs/rust_bindgen.md
index e44c95b..c4b2f3f 100644
--- a/docs/rust_bindgen.md
+++ b/docs/rust_bindgen.md
@@ -47,7 +47,7 @@
 | <a id="rust_bindgen_toolchain-bindgen"></a>bindgen |  The label of a <code>bindgen</code> executable.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 | <a id="rust_bindgen_toolchain-clang"></a>clang |  The label of a <code>clang</code> executable.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 | <a id="rust_bindgen_toolchain-libclang"></a>libclang |  A cc_library that provides bindgen's runtime dependency on libclang.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
-| <a id="rust_bindgen_toolchain-libstdcxx"></a>libstdcxx |  A cc_library that satisfies libclang's libstdc++ dependency.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
+| <a id="rust_bindgen_toolchain-libstdcxx"></a>libstdcxx |  A cc_library that satisfies libclang's libstdc++ dependency. This is used to make the execution of clang hermetic. If None, system libraries will be used instead.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 | <a id="rust_bindgen_toolchain-rustfmt"></a>rustfmt |  The label of a <code>rustfmt</code> executable. If this is provided, generated sources will be formatted.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
 
 
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
index dc154bf..9d1e28a 100644
--- a/rust/private/rustc.bzl
+++ b/rust/private/rustc.bzl
@@ -752,12 +752,17 @@
     Returns:
         depset: A set of relative paths from the output directory to each dependency
     """
-    preferreds = [get_preferred_artifact(lib) for linker_input in dep_info.transitive_noncrates.to_list() for lib in linker_input.libraries]
 
-    # TODO(augie): I don't understand why this can't just be filtering on
-    # _is_dylib(lib), but doing that causes failures on darwin and windows
-    # examples that otherwise work.
-    dylibs = [lib for lib in preferreds if _has_dylib_ext(lib, toolchain.dylib_ext)]
+    # Windows has no rpath equivalent, so always return an empty depset.
+    if toolchain.os == "windows":
+        return depset([])
+
+    dylibs = [
+        get_preferred_artifact(lib)
+        for linker_input in dep_info.transitive_noncrates.to_list()
+        for lib in linker_input.libraries
+        if _is_dylib(lib)
+    ]
     if not dylibs:
         return depset([])