Make //third_party/stl the entrypoint for toolchain bindings
Now -isystem third_party/stl/cxx17 appears first in the list of system includes.
The "unittest" ended up being quite complicated because action.argv is not available for CppCompile action and action.args is not accessible during analysis phase. So, we pass action.args to a script that does the actual order checking. Sometimes life gives you lemons.
PiperOrigin-RevId: 427185605
diff --git a/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_aspect.bzl b/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_aspect.bzl
index cb588fa..6c053da 100644
--- a/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_aspect.bzl
+++ b/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_aspect.bzl
@@ -63,6 +63,11 @@
if RustBindingsFromCcInfo in target:
return []
+ # We generate bindings for these headers via the
+ # rs_bindings_from_cc:cc_std target.
+ if target.label == Label("//third_party/stl:stl"):
+ return [ctx.attr._std[RustBindingsFromCcInfo]]
+
# This is not a C++ rule
if CcInfo not in target:
return []
@@ -108,13 +113,10 @@
header_includes.append("-include")
header_includes.append(hdr.short_path)
- stl = ctx.attr._stl[CcInfo].compilation_context
- compilation_context = target[CcInfo].compilation_context
-
return generate_and_compile_bindings(
ctx,
ctx.rule.attr,
- compilation_context = compilation_context,
+ compilation_context = target[CcInfo].compilation_context,
public_hdrs = public_hdrs,
header_includes = header_includes,
action_inputs = public_hdrs + ctx.files._builtin_hdrs,
diff --git a/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_utils.bzl b/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_utils.bzl
index becde40..9d9fd10 100644
--- a/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_utils.bzl
+++ b/rs_bindings_from_cc/blaze_support/rust_bindings_from_cc_utils.bzl
@@ -172,9 +172,7 @@
cc_toolchain.built_in_include_directories[1].replace("/stable/", "/llvm_unstable/"),
cc_toolchain.built_in_include_directories[2],
],
- transitive = [
- compilation_context.system_includes,
- ],
+ transitive = [compilation_context.system_includes],
),
include_directories = compilation_context.includes,
quote_include_directories = compilation_context.quote_includes,
@@ -314,7 +312,6 @@
default = Label("//tools/cpp:grep-includes"),
cfg = "host",
),
- "_stl": attr.label(default = "//third_party/stl"),
"_rustfmt": attr.label(
default = "//third_party/unsupported_toolchains/rust/toolchains/nightly:bin/rustfmt",
executable = True,
diff --git a/rs_bindings_from_cc/blaze_support/toolchain_headers.bzl b/rs_bindings_from_cc/blaze_support/toolchain_headers.bzl
index 559bcdd..c3adae1 100644
--- a/rs_bindings_from_cc/blaze_support/toolchain_headers.bzl
+++ b/rs_bindings_from_cc/blaze_support/toolchain_headers.bzl
@@ -20,7 +20,7 @@
return [hdr for hdr in input_list if not _is_public_std_header(hdr, public_hdrs)]
def _bindings_for_toolchain_headers_impl(ctx):
- std_hdrs = ctx.files.hdrs
+ std_hdrs = ctx.attr._stl[CcInfo].compilation_context.headers.to_list() + ctx.files.hdrs
# The clang builtin headers also contain some standard headers. We'll consider those part of
# the C++ Standard library target, so we generate bindings for them.
@@ -50,12 +50,10 @@
header_includes.append("-include")
header_includes.append(hdr.basename)
- compilation_context = cc_common.create_compilation_context()
-
return generate_and_compile_bindings(
ctx,
ctx.attr,
- compilation_context = compilation_context,
+ compilation_context = ctx.attr._stl[CcInfo].compilation_context,
public_hdrs = public_std_hdrs,
header_includes = header_includes,
action_inputs = ctx.files._builtin_hdrs + std_hdrs,
@@ -71,6 +69,7 @@
"hdrs": attr.label(),
"public_hdrs": attr.string_list(),
"deps": attr.label_list(),
+ "_stl": attr.label(default = "//third_party/stl:stl"),
}.items(),
),
toolchains = [
diff --git a/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/bar.h b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/bar.h
new file mode 100644
index 0000000..2c7bb59
--- /dev/null
+++ b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/bar.h
@@ -0,0 +1,8 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef CRUBIT_RS_BINDINGS_FROM_CC_TEST_BLAZE_UNIT_TESTS_CC_STD_BAR_H_
+#define CRUBIT_RS_BINDINGS_FROM_CC_TEST_BLAZE_UNIT_TESTS_CC_STD_BAR_H_
+
+#endif // CRUBIT_RS_BINDINGS_FROM_CC_TEST_BLAZE_UNIT_TESTS_CC_STD_BAR_H_
diff --git a/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/cc_std_test.bzl b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/cc_std_test.bzl
new file mode 100644
index 0000000..1852ac7
--- /dev/null
+++ b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/cc_std_test.bzl
@@ -0,0 +1,64 @@
+# Part of the Crubit project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+"""This module contains unit tests for rust_bindings_from_cc_aspect."""
+
+load(
+ "//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_aspect.bzl",
+ "rust_bindings_from_cc_aspect",
+)
+load(
+ "//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_utils.bzl",
+ "RustBindingsFromCcInfo",
+)
+
+OutputsInfo = provider(
+ doc = """A helper provider for determining the command line. """,
+ fields = {
+ "args": "Args object",
+ },
+)
+
+def _get_args_aspect_impl(target, ctx):
+ bindings_action = None
+
+ # Find CppHeaderAnalysis action
+ for action in target.actions:
+ if action.mnemonic == "CppHeaderAnalysis":
+ bindings_action = action
+ break
+
+ args = bindings_action.args[0]
+ return [OutputsInfo(args = args)]
+
+get_args_aspect = aspect(
+ implementation = _get_args_aspect_impl,
+ attr_aspects = ["deps"],
+ requires = [rust_bindings_from_cc_aspect],
+)
+
+def _cc_std_test_impl(ctx):
+ out = ctx.actions.declare_file(ctx.label.name + "_test.sh")
+ ctx.actions.run(
+ inputs = [ctx.attr.dep[RustBindingsFromCcInfo].dep_variant_info.crate_info.output],
+ arguments = [out.path, ctx.attr.dep[OutputsInfo].args],
+ executable = ctx.executable._include_directives_checker,
+ outputs = [out],
+ )
+ return [DefaultInfo(executable = out)]
+
+cc_std_test = rule(
+ implementation = _cc_std_test_impl,
+ attrs = {
+ "dep": attr.label(
+ aspects = [rust_bindings_from_cc_aspect, get_args_aspect],
+ ),
+ "_include_directives_checker": attr.label(
+ default = "//rs_bindings_from_cc/test/bazel_unit_tests/cc_std:check_include_directives",
+ executable = True,
+ cfg = "exec",
+ ),
+ },
+ test = True,
+)
diff --git a/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/check_include_directives.sh b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/check_include_directives.sh
new file mode 100755
index 0000000..9c650a4
--- /dev/null
+++ b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/check_include_directives.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+# Part of the Crubit project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+
+# A script to test that we are passing the system headers include directives
+# in the correct order.
+
+path_to_test_executable="$1"
+shift
+
+has_stl_isystem=0
+has_cc_stdlib_isystem=0
+has_clang_builtin_isystem=0
+has_grte_isystem=0
+
+stl_isystem="third_party/stl/cxx17"
+cc_std_lib_isystem="external/clang/toolchain/include/c++/v1"
+cc_std_lib_unstable_isystem="external/clang/toolchain/include/c++/v1"
+clang_builtin_isystem="external/clang/toolchain/lib/clang/google3-trunk/include"
+grte_isystem="@libc//include"
+
+function fail () {
+ cat > "${path_to_test_executable}" <<EOF
+echo "$1"
+exit 1
+EOF
+exit 0
+}
+
+while [[ $# -gt 0 ]]; do
+ if [[ "$1" = "-isystem" ]]; then
+ shift;
+ if [[ "$1" = "$stl_isystem" ]]; then
+ has_stl_isystem=1
+ elif [[ "$1" = "$cc_std_lib_isystem" ]] || \
+ [[ "$1" = "$cc_std_lib_unstable_isystem" ]] ; then
+ if [[ "$has_stl_isystem" = 0 ]]; then
+ fail "C++ standard library headers appear before STL headers"
+ fi
+ has_cc_stdlib_isystem=1
+ elif [[ "$1" = "$clang_builtin_isystem" ]]; then
+ if [[ "$has_cc_stdlib_isystem" = 0 ]]; then
+ fail "Clang builtin headers appear before C++ standard library headers."
+ fi
+ has_clang_builtin_isystem=1
+ elif [[ "$1" = "${grte_isystem}" ]]; then
+ if [[ "$has_clang_builtin_isystem" = 0 ]]; then
+ fail "GRTE headers appear before Clang builtin headers."
+ fi
+ has_grte_isystem=1
+ fi
+ fi
+ shift;
+done
+
+if [[ "$has_stl_isystem" = 0 ]]; then
+ fail "Failed to send STL -isystem directives to the command line"
+elif [[ "$has_cc_stdlib_isystem" = 0 ]]; then
+ fail "Failed to send C++ Standard Library -isystem directives to the command line"
+elif [[ "$has_clang_builtin_isystem" = 0 ]]; then
+ fail "Failed to send Clang builtin -isystem directives to the command line"
+elif [[ "$has_grte_isystem" = 0 ]]; then
+ fail "Failed to send GRTE -isystem directives to the command line"
+fi
+
+cat > "${path_to_test_executable}" <<EOF
+echo "Success!"
+exit 0
+EOF
+
+
diff --git a/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/foo.h b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/foo.h
new file mode 100644
index 0000000..7d10298
--- /dev/null
+++ b/rs_bindings_from_cc/test/blaze_unit_tests/cc_std/foo.h
@@ -0,0 +1,10 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef CRUBIT_RS_BINDINGS_FROM_CC_TEST_BLAZE_UNIT_TESTS_CC_STD_FOO_H_
+#define CRUBIT_RS_BINDINGS_FROM_CC_TEST_BLAZE_UNIT_TESTS_CC_STD_FOO_H_
+
+#include "rs_bindings_from_cc/test/bazel_unit_tests/cc_std/bar.h"
+
+#endif // CRUBIT_RS_BINDINGS_FROM_CC_TEST_BLAZE_UNIT_TESTS_CC_STD_FOO_H_
diff --git a/rs_bindings_from_cc/test/cc_std/empty.h b/rs_bindings_from_cc/test/cc_std/empty.h
new file mode 100644
index 0000000..e05cf1f
--- /dev/null
+++ b/rs_bindings_from_cc/test/cc_std/empty.h
@@ -0,0 +1,8 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef CRUBIT_RS_BINDINGS_FROM_CC_TEST_CC_STD_EMPTY_H_
+#define CRUBIT_RS_BINDINGS_FROM_CC_TEST_CC_STD_EMPTY_H_
+
+#endif // CRUBIT_RS_BINDINGS_FROM_CC_TEST_CC_STD_EMPTY_H_
diff --git a/rs_bindings_from_cc/test/cc_std/empty.rs b/rs_bindings_from_cc/test/cc_std/empty.rs
new file mode 100644
index 0000000..191f0ba
--- /dev/null
+++ b/rs_bindings_from_cc/test/cc_std/empty.rs
@@ -0,0 +1,5 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+