Skip to content

Commit f9d42ff

Browse files
authored
bindgen: Strip out -Xclang flags that upstream Clang doesn't understand. (#3606)
Some forks of Clang, such as Apple's, define additional `-Xclang` flags that upstream Clang (as used by bindgen) does not understand. This PR adds code for stripping these out so that bindgen does not error out on them.
1 parent 64bdbdf commit f9d42ff

File tree

2 files changed

+83
-14
lines changed

2 files changed

+83
-14
lines changed

extensions/bindgen/private/bindgen.bzl

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,20 @@ def _rust_bindgen_impl(ctx):
322322
"-nostdlib++",
323323
"-nostdlibinc",
324324
)
325+
326+
# Some forks of Clang, such as Apple's, define additional `-Xclang` flags that upstream Clang
327+
# (as used by bindgen) does not understand, so we want to strip them out. We list them here.
328+
xclang_flags_to_strip = (
329+
"-fexperimental-optimized-noescape",
330+
)
331+
325332
open_arg = False
326-
for arg in compile_flags:
333+
skip_next = False
334+
for idx, arg in enumerate(compile_flags):
335+
if skip_next:
336+
skip_next = False
337+
continue
338+
327339
if open_arg:
328340
args.add(arg)
329341
open_arg = False
@@ -337,6 +349,10 @@ def _rust_bindgen_impl(ctx):
337349
if not arg.startswith(param_flags_known_to_clang) and not arg in paramless_flags_known_to_clang:
338350
continue
339351

352+
if arg == "-Xclang" and idx + 1 < len(compile_flags) and compile_flags[idx + 1] in xclang_flags_to_strip:
353+
skip_next = True
354+
continue
355+
340356
args.add(arg)
341357

342358
if arg in param_flags_known_to_clang:

extensions/bindgen/test/bindgen_test.bzl

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Analysis test for for rust_bindgen_library rule."""
22

33
load("@bazel_skylib//rules:write_file.bzl", "write_file")
4+
load("@rules_cc//cc:action_names.bzl", "ALL_CPP_COMPILE_ACTION_NAMES")
5+
load("@rules_cc//cc:cc_toolchain_config_lib.bzl", "feature", "flag_group", "flag_set")
46
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_toolchain")
57
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
68
load("@rules_rust//rust:defs.bzl", "rust_binary")
@@ -9,6 +11,24 @@ load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
911
load("@rules_testing//lib:truth.bzl", "matching")
1012

1113
def _fake_cc_toolchain_config_impl(ctx):
14+
xclang_flags_feature = feature(
15+
name = "xclang_flags",
16+
enabled = True,
17+
flag_sets = [
18+
flag_set(
19+
actions = ALL_CPP_COMPILE_ACTION_NAMES,
20+
flag_groups = [
21+
flag_group(flags = [
22+
"-Xclang",
23+
"-fexperimental-optimized-noescape",
24+
"-Xclang",
25+
"-fcolor-diagnostics",
26+
]),
27+
],
28+
),
29+
],
30+
)
31+
1232
return cc_common.create_cc_toolchain_config_info(
1333
ctx = ctx,
1434
toolchain_identifier = "fake-toolchain",
@@ -19,6 +39,7 @@ def _fake_cc_toolchain_config_impl(ctx):
1939
compiler = "unknown",
2040
abi_version = "unknown",
2141
abi_libc_version = "unknown",
42+
features = [xclang_flags_feature],
2243
)
2344

2445
_fake_cc_toolchain_config = rule(
@@ -37,7 +58,7 @@ def _fake_cc_toolchain(name):
3758
write_file(
3859
name = stdbool_file,
3960
content = [],
40-
out = "my/resource/dir/include/stdbool.h",
61+
out = name + "/resource/dir/include/stdbool.h",
4162
)
4263

4364
all_files = name + "_all_files"
@@ -60,6 +81,21 @@ def _fake_cc_toolchain(name):
6081
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
6182
)
6283

84+
def _create_simple_rust_bindgen_library(test_name):
85+
cc_library(
86+
name = test_name + "_cc",
87+
hdrs = ["simple.h"],
88+
srcs = ["simple.cc"],
89+
)
90+
91+
rust_bindgen_library(
92+
name = test_name + "_rust_bindgen",
93+
cc_lib = test_name + "_cc",
94+
header = "simple.h",
95+
tags = ["manual"],
96+
edition = "2021",
97+
)
98+
6399
def _test_cc_linkopt_impl(env, target):
64100
# Assert
65101
env.expect.that_action(target.actions[0]) \
@@ -161,31 +197,47 @@ def _test_resource_dir_impl(env, target):
161197
env.expect.that_action(target.actions[0]).argv().contains_predicate(
162198
matching.all(
163199
matching.str_startswith("-resource-dir="),
164-
matching.str_endswith("my/resource/dir"),
200+
matching.str_endswith("/resource/dir"),
165201
),
166202
)
167203

168204
def _test_resource_dir(name):
169205
_fake_cc_toolchain(name + "_toolchain")
170206

171-
cc_library(
172-
name = name + "_cc",
173-
hdrs = ["simple.h"],
174-
srcs = ["simple.cc"],
207+
_create_simple_rust_bindgen_library(name)
208+
209+
analysis_test(
210+
name = name,
211+
target = name + "_rust_bindgen__bindgen",
212+
impl = _test_resource_dir_impl,
213+
config_settings = {
214+
"//command_line_option:extra_toolchains": [str(native.package_relative_label(name + "_toolchain"))],
215+
},
175216
)
176217

177-
rust_bindgen_library(
178-
name = name + "_rust_bindgen",
179-
cc_lib = name + "_cc",
180-
header = "simple.h",
181-
tags = ["manual"],
182-
edition = "2021",
218+
def _test_strip_xclang_impl(env, target):
219+
env.expect.that_int(len(target.actions)).is_greater_than(0)
220+
env.expect.that_action(target.actions[0]).mnemonic().contains("RustBindgen")
221+
env.expect.that_action(target.actions[0]).not_contains_arg(
222+
"-fexperimental-optimized-noescape",
223+
)
224+
env.expect.that_action(target.actions[0]).contains_at_least_args(
225+
["-Xclang", "-fcolor-diagnostics"],
183226
)
184227

228+
def _test_strip_xclang(name):
229+
# Test that we strip certain `-Xclang` flags defined by forks of Clang
230+
# that upstream Clang doesn't know about, such as
231+
# `-fexperimental-optimized-noescape`. (This is added by the toolchain.)
232+
233+
_fake_cc_toolchain(name + "_toolchain")
234+
235+
_create_simple_rust_bindgen_library(name)
236+
185237
analysis_test(
186238
name = name,
187239
target = name + "_rust_bindgen__bindgen",
188-
impl = _test_resource_dir_impl,
240+
impl = _test_strip_xclang_impl,
189241
config_settings = {
190242
"//command_line_option:extra_toolchains": [str(native.package_relative_label(name + "_toolchain"))],
191243
},
@@ -199,5 +251,6 @@ def bindgen_test_suite(name):
199251
_test_cc_lib_object_merging,
200252
_test_cc_lib_object_merging_disabled,
201253
_test_resource_dir,
254+
_test_strip_xclang,
202255
],
203256
)

0 commit comments

Comments
 (0)