History

Merge tag 'rust-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux

Pull Rust updates from Miguel Ojeda: "Toolchain and infrastructure: - Bump the minimum Rust version to 1.85.0 (and 'bindgen' to 0.71.1). As proposed in LPC 2025 and the Maintainers Summit [1], we are going to follow Debian Stable's Rust versions as our minimum versions. Debian Trixie was released on 2025-08-09 with a Rust 1.85.0 and 'bindgen' 0.71.1 toolchain, which is a fair amount of time for e.g. kernel developers to upgrade. Other major distributions support a Rust version that is high enough as well, including: + Arch Linux. + Fedora Linux. + Gentoo Linux. + Nix. + openSUSE Slowroll and openSUSE Tumbleweed. + Ubuntu 25.10 and 26.04 LTS. In addition, 24.04 LTS using their versioned packages. The merged patch series comes with the associated cleanups and simplifications treewide that can be performed thanks to both bumps, as well as documentation updates. In addition, start using 'bindgen''s '--with-attribute-custom-enum' feature to set the 'cfi_encoding' attribute for the 'lru_status' enum used in Binder. Link: https://lwn.net/Articles/1050174/ [1] - Add experimental Kconfig option ('CONFIG_RUST_INLINE_HELPERS') that inlines C helpers into Rust. Essentially, it performs a step similar to LTO, but just for the helpers, i.e. very local and fast. It relies on 'llvm-link' and its '--internalize' flag, and requires a compatible LLVM between Clang and 'rustc' (i.e. same major version, 'CONFIG_RUSTC_CLANG_LLVM_COMPATIBLE'). It is only enabled for two architectures for now. The result is a measurable speedup in different workloads that different users have tested. For instance, for the null block driver, it amounts to a 2%. - Support global per-version flags. While we already have per-version flags in many places, we didn't have a place to set global ones that depend on the compiler version, i.e. in 'rust_common_flags', which sometimes is needed to e.g. tweak the lints set per version. Use that to allow the 'clippy::precedence' lint for Rust < 1.86.0, since it had a change in behavior. - Support overriding the crate name and apply it to Rust Binder, which wanted the module to be called 'rust_binder'. - Add the remaining '__rust_helper' annotations (started in the previous cycle). 'kernel' crate: - Introduce the 'const_assert!' macro: a more powerful version of 'static_assert!' that can refer to generics inside functions or implementation bodies, e.g.: fn f<const N: usize>() { const_assert!(N > 1); } fn g<T>() { const_assert!(size_of::<T>() > 0, "T cannot be ZST"); } In addition, reorganize our set of build-time assertion macros ('{build,const,static_assert}!') to live in the 'build_assert' module. Finally, improve the docs as well to clarify how these are different from one another and how to pick the right one to use, and their equivalence (if any) to the existing C ones for extra clarity. - 'sizes' module: add 'SizeConstants' trait. This gives us typed 'SZ_*' constants (avoiding casts) for use in device address spaces where the address width depends on the hardware (e.g. 32-bit MMIO windows, 64-bit GPU framebuffers, etc.), e.g.: let gpu_heap = 14 * u64::SZ_1M; let mmio_window = u32::SZ_16M; - 'clk' module: implement 'Send' and 'Sync' for 'Clk' and thus simplify the users in Tyr and PWM. - 'ptr' module: add 'const_align_up'. - 'str' module: improve the documentation of the 'c_str!' macro to explain that one should only use it for non-literal cases (for the other case we instead use C string literals, e.g. 'c"abc"'). - Disallow the use of 'CStr::{as_ptr,from_ptr}' and clean one such use in the 'task' module. - 'sync' module: finish the move of 'ARef' and 'AlwaysRefCounted' outside of the 'types' module, i.e. update the last remaining instances and finally remove the re-exports. - 'error' module: clarify that 'from_err_ptr' can return 'Ok(NULL)', including runtime-tested examples. The intention is to hopefully prevent UB that assumes the result of the function is not 'NULL' if successful. This originated from a case of UB I noticed in 'regulator' that created a 'NonNull' on it. Timekeeping: - Expand the example section in the 'HrTimer' documentation. - Mark the 'ClockSource' trait as unsafe to ensure valid values for 'ktime_get()'. - Add 'Delta::from_nanos()'. 'pin-init' crate: - Replace the 'Zeroable' impls for 'Option<NonZero*>' with impls of 'ZeroableOption' for 'NonZero*'. - Improve feature gate handling for unstable features. - Declutter the documentation of implementations of 'Zeroable' for tuples. - Replace uses of 'addr_of[_mut]!' with '&raw [mut]'. rust-analyzer: - Add type annotations to 'generate_rust_analyzer.py'. - Add support for scripts written in Rust ('generate_rust_target.rs', 'rustdoc_test_builder.rs', 'rustdoc_test_gen.rs'). - Refactor 'generate_rust_analyzer.py' to explicitly identify host and target crates, improve readability, and reduce duplication. And some other fixes, cleanups and improvements" * tag 'rust-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (79 commits) rust: sizes: add SizeConstants trait for device address space constants rust: kernel: update `file_with_nul` comment rust: kbuild: allow `clippy::precedence` for Rust < 1.86.0 rust: kbuild: support global per-version flags rust: declare cfi_encoding for lru_status docs: rust: general-information: use real example docs: rust: general-information: simplify Kconfig example docs: rust: quick-start: remove GDB/Binutils mention docs: rust: quick-start: remove Nix "unstable channel" note docs: rust: quick-start: remove Gentoo "testing" note docs: rust: quick-start: add Ubuntu 26.04 LTS and remove subsection title docs: rust: quick-start: update minimum Ubuntu version docs: rust: quick-start: update Ubuntu versioned packages docs: rust: quick-start: openSUSE provides `rust-src` package nowadays rust: kbuild: remove "dummy parameter" workaround for `bindgen` < 0.71.1 rust: kbuild: update `bindgen --rust-target` version and replace comment rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1 rust: rust_is_available: remove warning for `bindgen` 0.66.[01] rust: bump `bindgen` minimum supported version to 0.71.1 (Debian Trixie) rust: block: update `const_refs_to_static` MSRV TODO comment ...

Linus Torvalds committed 7 months ago

Commit 26ff9692 parents 2848320 8a2305178 files · +1391 −821Browse files

Showing the changes to scripts (7 of 78 files). Show all

Unified · Split

7 files
  1. scripts/Makefile.build +7 −8
  2. scripts/generate_rust_analyzer.py +216 −82
  3. scripts/min-tool-version.sh +2 −2
  4. scripts/rust_is_available.sh +1 −35
  5. scripts/rust_is_available_bindgen_0_66.h +0 −2
  6. scripts/rust_is_available_bindgen_libclang_concat.h +0 −3
  7. scripts/rust_is_available_test.py +3 −55
scripts/Makefile.build+7−8
@@ -310,18 +310,13 @@ $(obj)/%.lst: $(obj)/%.c FORCE · 309 unmodified lines
310310
311311 # The features in this list are the ones allowed for non-`rust/` code.
312312 #
313−# - Stable since Rust 1.79.0: `feature(slice_ptr_len)`.
314−# - Stable since Rust 1.81.0: `feature(lint_reasons)`.
315−# - Stable since Rust 1.82.0: `feature(asm_const)`,
316−# `feature(offset_of_nested)`, `feature(raw_ref_op)`.
317−# - Stable since Rust 1.84.0: `feature(strict_provenance)`.
318313 # - Stable since Rust 1.87.0: `feature(asm_goto)`.
319314 # - Expected to become stable: `feature(arbitrary_self_types)`.
320315 # - To be determined: `feature(used_with_arg)`.
321316 #
322317 # Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on
323318 # the unstable features in use.
324−rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,slice_ptr_len,strict_provenance,used_with_arg
319+rust_allowed_features := arbitrary_self_types,asm_goto,used_with_arg
325320
326321 # `--out-dir` is required to avoid temporaries being created by `rustc` in the
327322 # current working directory, which may be not accessible in the out-of-tree
@@ -334,7 +329,6 @@ rust_common_cmd = \ · 6 unmodified lines
334329 -Zcrate-attr='feature($(rust_allowed_features))' \
335330 -Zunstable-options --extern pin_init --extern kernel \
336331 --crate-type rlib -L $(objtree)/rust/ \
337− --crate-name $(basename $(notdir $@)) \
338332 --sysroot=/dev/null \
339333 --out-dir $(dir $@) --emit=dep-info=$(depfile)
340334
@@ -347,7 +341,12 @@ rust_common_cmd = \ · 6 unmodified lines
347341 # would not match each other.
348342
349343 quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
350− cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< $(cmd_objtool)
344+ cmd_rustc_o_rs = $(rust_common_cmd) --emit=$(if $(CONFIG_RUST_INLINE_HELPERS),llvm-bc=$(patsubst %.o,%.bc,$@),obj=$@) $< \
345+ $(if $(CONFIG_RUST_INLINE_HELPERS),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \
346+ $(objtree)/rust/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \
347+ $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \
348+ $(cmd_ld_single)) \
349+ $(cmd_objtool)
351350
352351 define rule_rustc_o_rs
353352 $(call cmd_and_fixdep,rustc_o_rs)
scripts/generate_rust_analyzer.py+216−82
@@ -10,8 +10,15 @@ import os · 9 unmodified lines
1010 import pathlib
1111 import subprocess
1212 import sys
13+from typing import Dict, Iterable, List, Literal, Optional, TypedDict
1314
14−def args_crates_cfgs(cfgs):
15+def invoke_rustc(args: List[str]) -> str:
16+ return subprocess.check_output(
17+ [os.environ["RUSTC"]] + args,
18+ stdin=subprocess.DEVNULL,
19+ ).decode('utf-8').strip()
20+
21+def args_crates_cfgs(cfgs: List[str]) -> Dict[str, List[str]]:
1522 crates_cfgs = {}
1623 for cfg in cfgs:
1724 crate, vals = cfg.split("=", 1)
@@ -19,54 +26,153 @@ def args_crates_cfgs(cfgs): · 1 unmodified line
1926
2027 return crates_cfgs
2128
22−def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edition):
29+class Dependency(TypedDict):
30+ crate: int
31+ name: str
32+
33+
34+class Source(TypedDict):
35+ include_dirs: List[str]
36+ exclude_dirs: List[str]
37+
38+
39+class Crate(TypedDict):
40+ display_name: str
41+ root_module: str
42+ is_workspace_member: bool
43+ deps: List[Dependency]
44+ cfg: List[str]
45+ edition: str
46+ env: Dict[str, str]
47+
48+
49+class ProcMacroCrate(Crate):
50+ is_proc_macro: Literal[True]
51+ proc_macro_dylib_path: str # `pathlib.Path` is not JSON serializable.
52+
53+
54+class CrateWithGenerated(Crate):
55+ source: Source
56+
57+
58+def generate_crates(
59+ srctree: pathlib.Path,
60+ objtree: pathlib.Path,
61+ sysroot_src: pathlib.Path,
62+ external_src: Optional[pathlib.Path],
63+ cfgs: List[str],
64+ core_edition: str,
65+) -> List[Crate]:
2366 # Generate the configuration list.
24− cfg = []
67+ generated_cfg = []
2568 with open(objtree / "include" / "generated" / "rustc_cfg") as fd:
2669 for line in fd:
2770 line = line.replace("--cfg=", "")
2871 line = line.replace("\n", "")
29− cfg.append(line)
72+ generated_cfg.append(line)
3073
31− # Now fill the crates list -- dependencies need to come first.
32− #
33− # Avoid O(n^2) iterations by keeping a map of indexes.
34− crates = []
35− crates_indexes = {}
74+ # Now fill the crates list.
75+ crates: List[Crate] = []
3676 crates_cfgs = args_crates_cfgs(cfgs)
3777
38− def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False, edition="2021"):
39− crate = {
78+ def get_crate_name(path: pathlib.Path) -> str:
79+ return invoke_rustc(["--print", "crate-name", str(path)])
80+
81+ def build_crate(
82+ display_name: str,
83+ root_module: pathlib.Path,
84+ deps: List[Dependency],
85+ *,
86+ cfg: Optional[List[str]],
87+ is_workspace_member: Optional[bool],
88+ edition: Optional[str],
89+ ) -> Crate:
90+ cfg = cfg if cfg is not None else crates_cfgs.get(display_name, [])
91+ is_workspace_member = (
92+ is_workspace_member if is_workspace_member is not None else True
93+ )
94+ edition = edition if edition is not None else "2021"
95+ return {
4096 "display_name": display_name,
4197 "root_module": str(root_module),
4298 "is_workspace_member": is_workspace_member,
43− "is_proc_macro": is_proc_macro,
44− "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps],
99+ "deps": deps,
45100 "cfg": cfg,
46101 "edition": edition,
47102 "env": {
48103 "RUST_MODFILE": "This is only for rust-analyzer"
49104 }
50105 }
51− if is_proc_macro:
52− proc_macro_dylib_name = subprocess.check_output(
53− [os.environ["RUSTC"], "--print", "file-names", "--crate-name", display_name, "--crate-type", "proc-macro", "-"],
54− stdin=subprocess.DEVNULL,
55− ).decode('utf-8').strip()
56− crate["proc_macro_dylib_path"] = f"{objtree}/rust/{proc_macro_dylib_name}"
57− crates_indexes[display_name] = len(crates)
106+
107+ def append_proc_macro_crate(
108+ display_name: str,
109+ root_module: pathlib.Path,
110+ deps: List[Dependency],
111+ *,
112+ cfg: Optional[List[str]] = None,
113+ is_workspace_member: Optional[bool] = None,
114+ edition: Optional[str] = None,
115+ ) -> Dependency:
116+ crate = build_crate(
117+ display_name,
118+ root_module,
119+ deps,
120+ cfg=cfg,
121+ is_workspace_member=is_workspace_member,
122+ edition=edition,
123+ )
124+ proc_macro_dylib_name = invoke_rustc([
125+ "--print",
126+ "file-names",
127+ "--crate-name",
128+ display_name,
129+ "--crate-type",
130+ "proc-macro",
131+ "-",
132+ ])
133+ proc_macro_crate: ProcMacroCrate = {
134+ **crate,
135+ "is_proc_macro": True,
136+ "proc_macro_dylib_path": str(objtree / "rust" / proc_macro_dylib_name),
137+ }
138+ return register_crate(proc_macro_crate)
139+
140+ def register_crate(crate: Crate) -> Dependency:
141+ index = len(crates)
58142 crates.append(crate)
143+ return {"crate": index, "name": crate["display_name"]}
144+
145+ def append_crate(
146+ display_name: str,
147+ root_module: pathlib.Path,
148+ deps: List[Dependency],
149+ *,
150+ cfg: Optional[List[str]] = None,
151+ is_workspace_member: Optional[bool] = None,
152+ edition: Optional[str] = None,
153+ ) -> Dependency:
154+ return register_crate(
155+ build_crate(
156+ display_name,
157+ root_module,
158+ deps,
159+ cfg=cfg,
160+ is_workspace_member=is_workspace_member,
161+ edition=edition,
162+ )
163+ )
59164
60165 def append_sysroot_crate(
61− display_name,
62− deps,
63− cfg=[],
64− ):
65− append_crate(
166+ display_name: str,
167+ deps: List[Dependency],
168+ *,
169+ cfg: Optional[List[str]] = None,
170+ ) -> Dependency:
171+ return append_crate(
66172 display_name,
67173 sysroot_src / display_name / "src" / "lib.rs",
68174 deps,
69− cfg,
175+ cfg=cfg,
70176 is_workspace_member=False,
71177 # Miguel Ojeda writes:
72178 #
@@ -98,129 +204,146 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit · 25 unmodified lines
98204 # NB: sysroot crates reexport items from one another so setting up our transitive dependencies
99205 # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth
100206 # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`.
101− append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []))
102− append_sysroot_crate("alloc", ["core"])
103− append_sysroot_crate("std", ["alloc", "core"])
104− append_sysroot_crate("proc_macro", ["core", "std"])
207+ core = append_sysroot_crate("core", [])
208+ alloc = append_sysroot_crate("alloc", [core])
209+ std = append_sysroot_crate("std", [alloc, core])
210+ proc_macro = append_sysroot_crate("proc_macro", [core, std])
105211
106− append_crate(
212+ compiler_builtins = append_crate(
107213 "compiler_builtins",
108214 srctree / "rust" / "compiler_builtins.rs",
109− ["core"],
215+ [core],
110216 )
111217
112− append_crate(
218+ proc_macro2 = append_crate(
113219 "proc_macro2",
114220 srctree / "rust" / "proc-macro2" / "lib.rs",
115− ["core", "alloc", "std", "proc_macro"],
116− cfg=crates_cfgs["proc_macro2"],
221+ [core, alloc, std, proc_macro],
117222 )
118223
119− append_crate(
224+ quote = append_crate(
120225 "quote",
121226 srctree / "rust" / "quote" / "lib.rs",
122− ["core", "alloc", "std", "proc_macro", "proc_macro2"],
123− cfg=crates_cfgs["quote"],
227+ [core, alloc, std, proc_macro, proc_macro2],
124228 edition="2018",
125229 )
126230
127− append_crate(
231+ syn = append_crate(
128232 "syn",
129233 srctree / "rust" / "syn" / "lib.rs",
130− ["std", "proc_macro", "proc_macro2", "quote"],
131− cfg=crates_cfgs["syn"],
234+ [std, proc_macro, proc_macro2, quote],
132235 )
133236
134− append_crate(
237+ macros = append_proc_macro_crate(
135238 "macros",
136239 srctree / "rust" / "macros" / "lib.rs",
137− ["std", "proc_macro", "proc_macro2", "quote", "syn"],
138− is_proc_macro=True,
240+ [std, proc_macro, proc_macro2, quote, syn],
139241 )
140242
141− append_crate(
243+ build_error = append_crate(
142244 "build_error",
143245 srctree / "rust" / "build_error.rs",
144− ["core", "compiler_builtins"],
246+ [core, compiler_builtins],
145247 )
146248
147− append_crate(
249+ pin_init_internal = append_proc_macro_crate(
148250 "pin_init_internal",
149251 srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs",
150− ["std", "proc_macro", "proc_macro2", "quote", "syn"],
151− cfg=["kernel"],
152− is_proc_macro=True,
252+ [std, proc_macro, proc_macro2, quote, syn],
153253 )
154254
155− append_crate(
255+ pin_init = append_crate(
156256 "pin_init",
157257 srctree / "rust" / "pin-init" / "src" / "lib.rs",
158− ["core", "compiler_builtins", "pin_init_internal", "macros"],
159− cfg=["kernel"],
258+ [core, compiler_builtins, pin_init_internal, macros],
160259 )
161260
162− append_crate(
261+ ffi = append_crate(
163262 "ffi",
164263 srctree / "rust" / "ffi.rs",
165− ["core", "compiler_builtins"],
264+ [core, compiler_builtins],
166265 )
167266
168267 def append_crate_with_generated(
169− display_name,
170− deps,
171− ):
172− append_crate(
268+ display_name: str,
269+ deps: List[Dependency],
270+ ) -> Dependency:
271+ crate = build_crate(
173272 display_name,
174273 srctree / "rust"/ display_name / "lib.rs",
175274 deps,
176− cfg=cfg,
275+ cfg=generated_cfg,
276+ is_workspace_member=True,
277+ edition=None,
177278 )
178− crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
179− crates[-1]["source"] = {
180− "include_dirs": [
181− str(srctree / "rust" / display_name),
182− str(objtree / "rust")
183− ],
184− "exclude_dirs": [],
279+ crate["env"]["OBJTREE"] = str(objtree.resolve(True))
280+ crate_with_generated: CrateWithGenerated = {
281+ **crate,
282+ "source": {
283+ "include_dirs": [
284+ str(srctree / "rust" / display_name),
285+ str(objtree / "rust"),
286+ ],
287+ "exclude_dirs": [],
288+ },
185289 }
290+ return register_crate(crate_with_generated)
291+
292+ bindings = append_crate_with_generated("bindings", [core, ffi, pin_init])
293+ uapi = append_crate_with_generated("uapi", [core, ffi, pin_init])
294+ kernel = append_crate_with_generated(
295+ "kernel", [core, macros, build_error, pin_init, ffi, bindings, uapi]
296+ )
186297
187− append_crate_with_generated("bindings", ["core", "ffi", "pin_init"])
188− append_crate_with_generated("uapi", ["core", "ffi", "pin_init"])
189− append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"])
298+ scripts = srctree / "scripts"
299+ makefile = (scripts / "Makefile").read_text()
300+ for path in scripts.glob("*.rs"):
301+ name = path.stem
302+ if f"{name}-rust" not in makefile:
303+ continue
304+ append_crate(
305+ name,
306+ path,
307+ [std],
308+ )
190309
191− def is_root_crate(build_file, target):
310+ def is_root_crate(build_file: pathlib.Path, target: str) -> bool:
192311 try:
193− return f"{target}.o" in open(build_file).read()
312+ contents = build_file.read_text()
194313 except FileNotFoundError:
195314 return False
315+ return f"{target}.o" in contents
196316
197317 # Then, the rest outside of `rust/`.
198318 #
199319 # We explicitly mention the top-level folders we want to cover.
200− extra_dirs = map(lambda dir: srctree / dir, ("samples", "drivers"))
320+ extra_dirs: Iterable[pathlib.Path] = (
321+ srctree / dir for dir in ("samples", "drivers")
322+ )
201323 if external_src is not None:
202324 extra_dirs = [external_src]
203325 for folder in extra_dirs:
204326 for path in folder.rglob("*.rs"):
205327 logging.info("Checking %s", path)
206− name = path.name.replace(".rs", "")
328+ file_name = path.stem
207329
208330 # Skip those that are not crate roots.
209− if not is_root_crate(path.parent / "Makefile", name) and \
210− not is_root_crate(path.parent / "Kbuild", name):
331+ if not is_root_crate(path.parent / "Makefile", file_name) and \
332+ not is_root_crate(path.parent / "Kbuild", file_name):
211333 continue
212334
213− logging.info("Adding %s", name)
335+ crate_name = get_crate_name(path)
336+ logging.info("Adding %s", crate_name)
214337 append_crate(
215− name,
338+ crate_name,
216339 path,
217− ["core", "kernel", "pin_init"],
218− cfg=cfg,
340+ [core, kernel, pin_init],
341+ cfg=generated_cfg,
219342 )
220343
221344 return crates
222345
223−def main():
346+def main() -> None:
224347 parser = argparse.ArgumentParser()
225348 parser.add_argument('--verbose', '-v', action='store_true')
226349 parser.add_argument('--cfgs', action='append', default=[])
@@ -230,7 +353,18 @@ def main(): · 3 unmodified lines
230353 parser.add_argument("sysroot", type=pathlib.Path)
231354 parser.add_argument("sysroot_src", type=pathlib.Path)
232355 parser.add_argument("exttree", type=pathlib.Path, nargs="?")
233− args = parser.parse_args()
356+
357+ class Args(argparse.Namespace):
358+ verbose: bool
359+ cfgs: List[str]
360+ srctree: pathlib.Path
361+ objtree: pathlib.Path
362+ sysroot: pathlib.Path
363+ sysroot_src: pathlib.Path
364+ exttree: Optional[pathlib.Path]
365+ core_edition: str
366+
367+ args = parser.parse_args(namespace=Args())
234368
235369 logging.basicConfig(
236370 format="[%(asctime)s] [%(levelname)s] %(message)s",
scripts/min-tool-version.sh+2−2
@@ -31,10 +31,10 @@ llvm) · 30 unmodified lines
3131 fi
3232 ;;
3333 rustc)
34− echo 1.78.0
34+ echo 1.85.0
3535 ;;
3636 bindgen)
37− echo 0.65.1
37+ echo 0.71.1
3838 ;;
3939 *)
4040 echo "$1: unknown tool" >&2
scripts/rust_is_available.sh+1−35
@@ -121,14 +121,8 @@ fi · 120 unmodified lines
121121 # Check that the Rust bindings generator is suitable.
122122 #
123123 # Non-stable and distributions' versions may have a version suffix, e.g. `-dev`.
124−#
125−# The dummy parameter `workaround-for-0.69.0` is required to support 0.69.0
126−# (https://github.com/rust-lang/rust-bindgen/pull/2678) and 0.71.0
127−# (https://github.com/rust-lang/rust-bindgen/pull/3040). It can be removed when
128−# the minimum version is upgraded past the latter (0.69.1 and 0.71.1 both fixed
129−# the issue).
130124 rust_bindings_generator_output=$( \
131− LC_ALL=C "$BINDGEN" --version workaround-for-0.69.0 2>/dev/null
125+ LC_ALL=C "$BINDGEN" --version 2>/dev/null
132126 ) || rust_bindings_generator_code=$?
133127 if [ -n "$rust_bindings_generator_code" ]; then
134128 echo >&2 "***"
@@ -163,19 +157,6 @@ if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cvers · 28 unmodified lines
163157 echo >&2 "***"
164158 exit 1
165159 fi
166−if [ "$rust_bindings_generator_cversion" -eq 6600 ] ||
167− [ "$rust_bindings_generator_cversion" -eq 6601 ]; then
168− # Distributions may have patched the issue (e.g. Debian did).
169− if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_0_66.h >/dev/null; then
170− echo >&2 "***"
171− echo >&2 "*** Rust bindings generator '$BINDGEN' versions 0.66.0 and 0.66.1 may not"
172− echo >&2 "*** work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2567),"
173− echo >&2 "*** unless patched (like Debian's)."
174− echo >&2 "*** Your version: $rust_bindings_generator_version"
175− echo >&2 "***"
176− warning=1
177− fi
178−fi
179160
180161 # Check that the `libclang` used by the Rust bindings generator is suitable.
181162 #
@@ -227,21 +208,6 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then · 45 unmodified lines
227208 exit 1
228209 fi
229210
230−if [ "$bindgen_libclang_cversion" -ge 1900100 ] &&
231− [ "$rust_bindings_generator_cversion" -lt 6905 ]; then
232− # Distributions may have patched the issue (e.g. Debian did).
233− if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_concat.h | grep -q foofoo; then
234− echo >&2 "***"
235− echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.69.5 together with libclang >= 19.1"
236− echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824),"
237− echo >&2 "*** unless patched (like Debian's)."
238− echo >&2 "*** Your bindgen version: $rust_bindings_generator_version"
239− echo >&2 "*** Your libclang version: $bindgen_libclang_version"
240− echo >&2 "***"
241− warning=1
242− fi
243−fi
244−
245211 # If the C compiler is Clang, then we can also check whether its version
246212 # matches the `libclang` version used by the Rust bindings generator.
247213 #
scripts/rust_is_available_bindgen_0_66.h+0−2
@@ -1,2 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−#define A "\0"
scripts/rust_is_available_bindgen_libclang_concat.h+0−3
@@ -1,3 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−#define F(x) int x##x
3−F(foo);
scripts/rust_is_available_test.py+3−55
@@ -54,37 +54,23 @@ else: · 53 unmodified lines
5454 """)
5555
5656 @classmethod
57− def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False):
57+ def generate_bindgen(cls, version_stdout, libclang_stderr):
5858 if libclang_stderr is None:
5959 libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})"
6060 else:
6161 libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)"
6262
63− if version_0_66_patched:
64− version_0_66_case = "pass"
65− else:
66− version_0_66_case = "raise SystemExit(1)"
67−
68− if libclang_concat_patched:
69− libclang_concat_case = "print('pub static mut foofoo: ::std::os::raw::c_int;')"
70− else:
71− libclang_concat_case = "pass"
72−
7363 return cls.generate_executable(f"""#!/usr/bin/env python3
7464 import sys
7565 if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv):
7666 {libclang_case}
77−elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv):
78− {version_0_66_case}
79−elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv):
80− {libclang_concat_case}
8167 else:
8268 print({repr(version_stdout)})
8369 """)
8470
8571 @classmethod
86− def generate_bindgen_version(cls, stdout, version_0_66_patched=False):
87− return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr, version_0_66_patched)
72+ def generate_bindgen_version(cls, stdout):
73+ return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr)
8874
8975 @classmethod
9076 def generate_bindgen_libclang_failure(cls):
@@ -245,19 +231,6 @@ else: · 154 unmodified lines
245231 result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
246232 self.assertIn(f"Rust bindings generator '{bindgen}' is too old.", result.stderr)
247233
248− def test_bindgen_bad_version_0_66_0_and_0_66_1(self):
249− for version in ("0.66.0", "0.66.1"):
250− with self.subTest(version=version):
251− bindgen = self.generate_bindgen_version(f"bindgen {version}")
252− result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
253− self.assertIn(f"Rust bindings generator '{bindgen}' versions 0.66.0 and 0.66.1 may not", result.stderr)
254−
255− def test_bindgen_bad_version_0_66_0_and_0_66_1_patched(self):
256− for version in ("0.66.0", "0.66.1"):
257− with self.subTest(version=version):
258− bindgen = self.generate_bindgen_version(f"bindgen {version}", True)
259− result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen })
260−
261234 def test_bindgen_libclang_failure(self):
262235 bindgen = self.generate_bindgen_libclang_failure()
263236 result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
@@ -275,31 +248,6 @@ else: · 11 unmodified lines
275248 result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
276249 self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr)
277250
278− def test_bindgen_bad_libclang_concat(self):
279− for (bindgen_version, libclang_version, expected_not_patched) in (
280− ("0.69.4", "18.0.0", self.Expected.SUCCESS),
281− ("0.69.4", "19.1.0", self.Expected.SUCCESS_WITH_WARNINGS),
282− ("0.69.4", "19.2.0", self.Expected.SUCCESS_WITH_WARNINGS),
283−
284− ("0.69.5", "18.0.0", self.Expected.SUCCESS),
285− ("0.69.5", "19.1.0", self.Expected.SUCCESS),
286− ("0.69.5", "19.2.0", self.Expected.SUCCESS),
287−
288− ("0.70.0", "18.0.0", self.Expected.SUCCESS),
289− ("0.70.0", "19.1.0", self.Expected.SUCCESS),
290− ("0.70.0", "19.2.0", self.Expected.SUCCESS),
291− ):
292− with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version):
293− cc = self.generate_clang(f"clang version {libclang_version}")
294− libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false"
295− bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr)
296− result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc })
297− if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS:
298− self.assertIn(f"Rust bindings generator '{bindgen}' < 0.69.5 together with libclang >= 19.1", result.stderr)
299−
300− bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_concat_patched=True)
301− result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc })
302−
303251 def test_clang_matches_bindgen_libclang_different_bindgen(self):
304252 bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false")
305253 result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })