Skip to content

Commit 3bb9c5e

Browse files
committed
rust: avoid assuming a particular bindgen build
`bindgen`'s logic to find `libclang` (via `clang-sys`) may change over time, and depends on how it was built (e.g. Linux distributions may decide to build it differently, and we are going to provide documentation on installing it via distributions later in this series). Therefore, clarify that `bindgen` may be built in several ways and simplify the documentation by only mentioning the most prominent environment variable (`LIBCLANG_PATH`) as an example on how to tweak the search of the library at runtime (i.e. when `bindgen` is built as our documentation explains). This also avoids duplicating the documentation, like `bindgen` itself does (i.e. it refers to `clang-sys`). Similarly, replace the test we had for this (which used the real program) with a mocked one, to avoid depending on the particular build as well. Tested-by: Benno Lossin <[email protected]> Tested-by: Andreas Hindborg <[email protected]> Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 35a3543 commit 3bb9c5e

File tree

2 files changed

+24
-24
lines changed

2 files changed

+24
-24
lines changed

Documentation/rust/quick-start.rst

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,15 @@ Install it via (note that this will download and build the tool from source)::
113113

114114
cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli
115115

116-
``bindgen`` needs to find a suitable ``libclang`` in order to work. If it is
117-
not found (or a different ``libclang`` than the one found should be used),
118-
the process can be tweaked using the environment variables understood by
119-
``clang-sys`` (the Rust bindings crate that ``bindgen`` uses to access
120-
``libclang``):
121-
122-
* ``LLVM_CONFIG_PATH`` can be pointed to an ``llvm-config`` executable.
123-
124-
* Or ``LIBCLANG_PATH`` can be pointed to a ``libclang`` shared library
125-
or to the directory containing it.
126-
127-
* Or ``CLANG_PATH`` can be pointed to a ``clang`` executable.
128-
129-
For details, please see ``clang-sys``'s documentation at:
116+
``bindgen`` uses the ``clang-sys`` crate to find a suitable ``libclang`` (which
117+
may be linked statically, dynamically or loaded at runtime). By default, the
118+
``cargo`` command above will produce a ``bindgen`` binary that will load
119+
``libclang`` at runtime. If it is not found (or a different ``libclang`` than
120+
the one found should be used), the process can be tweaked, e.g. by using the
121+
``LIBCLANG_PATH`` environment variable. For details, please see ``clang-sys``'s
122+
documentation at:
123+
124+
https://github.com/KyleMayes/clang-sys#linking
130125

131126
https://github.com/KyleMayes/clang-sys#environment-variables
132127

scripts/rust_is_available_test.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,15 @@ def generate_rustc(cls, stdout):
5555

5656
@classmethod
5757
def generate_bindgen(cls, version_stdout, libclang_stderr):
58+
if libclang_stderr is None:
59+
libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})"
60+
else:
61+
libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)"
62+
5863
return cls.generate_executable(f"""#!/usr/bin/env python3
5964
import sys
6065
if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv):
61-
print({repr(libclang_stderr)}, file=sys.stderr)
66+
{libclang_case}
6267
else:
6368
print({repr(version_stdout)})
6469
""")
@@ -67,6 +72,10 @@ def generate_bindgen(cls, version_stdout, libclang_stderr):
6772
def generate_bindgen_version(cls, stdout):
6873
return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr)
6974

75+
@classmethod
76+
def generate_bindgen_libclang_failure(cls):
77+
return cls.generate_bindgen(cls.bindgen_default_bindgen_version_stdout, None)
78+
7079
@classmethod
7180
def generate_bindgen_libclang(cls, stderr):
7281
return cls.generate_bindgen(cls.bindgen_default_bindgen_version_stdout, stderr)
@@ -89,6 +98,7 @@ def setUpClass(cls):
8998
cls.rust_default_sysroot = subprocess.check_output(("rustc", "--print", "sysroot")).decode().strip()
9099

91100
cls.bindgen_default_bindgen_version_stdout = f"bindgen {cls.bindgen_default_version}"
101+
cls.bindgen_default_bindgen_libclang_failure_exit_code = 42
92102
cls.bindgen_default_bindgen_libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {cls.llvm_default_version} [-W#pragma-messages], err: false"
93103

94104
cls.default_rustc = cls.generate_rustc(f"rustc {cls.rustc_default_version}")
@@ -227,15 +237,10 @@ def test_bindgen_new_version(self):
227237
self.assertIn(f"Rust bindings generator '{bindgen}' is too new. This may or may not work.", result.stderr)
228238

229239
def test_bindgen_libclang_failure(self):
230-
for env in (
231-
{ "LLVM_CONFIG_PATH": self.missing },
232-
{ "LIBCLANG_PATH": self.missing },
233-
{ "CLANG_PATH": self.missing },
234-
):
235-
with self.subTest(env=env):
236-
result = self.run_script(self.Expected.FAILURE, env | { "PATH": os.environ["PATH"], "BINDGEN": "bindgen" })
237-
self.assertIn("Running 'bindgen' to check the libclang version (used by the Rust", result.stderr)
238-
self.assertIn("bindings generator) failed with code ", result.stderr)
240+
bindgen = self.generate_bindgen_libclang_failure()
241+
result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
242+
self.assertIn(f"Running '{bindgen}' to check the libclang version (used by the Rust", result.stderr)
243+
self.assertIn(f"bindings generator) failed with code {self.bindgen_default_bindgen_libclang_failure_exit_code}. This may be caused by", result.stderr)
239244

240245
def test_bindgen_libclang_unexpected_version(self):
241246
bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version unexpected [-W#pragma-messages], err: false")

0 commit comments

Comments
 (0)