Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <benno.lossin@proton.me>
Tested-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20240709160615.998336-8-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

+23 -23
+8 -13
Documentation/rust/quick-start.rst
··· 113 113 114 114 cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli 115 115 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``): 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: 121 123 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: 124 + https://github.com/KyleMayes/clang-sys#linking 130 125 131 126 https://github.com/KyleMayes/clang-sys#environment-variables 132 127
+15 -10
scripts/rust_is_available_test.py
··· 55 55 56 56 @classmethod 57 57 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 + 58 63 return cls.generate_executable(f"""#!/usr/bin/env python3 59 64 import sys 60 65 if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): 61 - print({repr(libclang_stderr)}, file=sys.stderr) 66 + {libclang_case} 62 67 else: 63 68 print({repr(version_stdout)}) 64 69 """) ··· 71 66 @classmethod 72 67 def generate_bindgen_version(cls, stdout): 73 68 return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr) 69 + 70 + @classmethod 71 + def generate_bindgen_libclang_failure(cls): 72 + return cls.generate_bindgen(cls.bindgen_default_bindgen_version_stdout, None) 74 73 75 74 @classmethod 76 75 def generate_bindgen_libclang(cls, stderr): ··· 98 89 cls.rust_default_sysroot = subprocess.check_output(("rustc", "--print", "sysroot")).decode().strip() 99 90 100 91 cls.bindgen_default_bindgen_version_stdout = f"bindgen {cls.bindgen_default_version}" 92 + cls.bindgen_default_bindgen_libclang_failure_exit_code = 42 101 93 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" 102 94 103 95 cls.default_rustc = cls.generate_rustc(f"rustc {cls.rustc_default_version}") ··· 237 227 self.assertIn(f"Rust bindings generator '{bindgen}' is too new. This may or may not work.", result.stderr) 238 228 239 229 def test_bindgen_libclang_failure(self): 240 - for env in ( 241 - { "LLVM_CONFIG_PATH": self.missing }, 242 - { "LIBCLANG_PATH": self.missing }, 243 - { "CLANG_PATH": self.missing }, 244 - ): 245 - with self.subTest(env=env): 246 - result = self.run_script(self.Expected.FAILURE, env | { "PATH": os.environ["PATH"], "BINDGEN": "bindgen" }) 247 - self.assertIn("Running 'bindgen' to check the libclang version (used by the Rust", result.stderr) 248 - self.assertIn("bindings generator) failed with code ", result.stderr) 230 + bindgen = self.generate_bindgen_libclang_failure() 231 + result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) 232 + self.assertIn(f"Running '{bindgen}' to check the libclang version (used by the Rust", result.stderr) 233 + self.assertIn(f"bindings generator) failed with code {self.bindgen_default_bindgen_libclang_failure_exit_code}. This may be caused by", result.stderr) 249 234 250 235 def test_bindgen_libclang_unexpected_version(self): 251 236 bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version unexpected [-W#pragma-messages], err: false")