diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-13 09:54:20 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-13 09:54:20 -0700 |
| commit | 26ff969926a08eee069767ddbbbc301adbcd9676 (patch) | |
| tree | f54b18cf585550612ac9301bbae82c006978733f /scripts | |
| parent | 28483203f7d7fe4f123ed08266c381fac96b0701 (diff) | |
| parent | 8a23051ed8584215b22368e9501f771ef98f0c1d (diff) | |
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
...
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Makefile.build | 15 | ||||
| -rwxr-xr-x | scripts/generate_rust_analyzer.py | 298 | ||||
| -rwxr-xr-x | scripts/min-tool-version.sh | 4 | ||||
| -rwxr-xr-x | scripts/rust_is_available.sh | 36 | ||||
| -rw-r--r-- | scripts/rust_is_available_bindgen_0_66.h | 2 | ||||
| -rw-r--r-- | scripts/rust_is_available_bindgen_libclang_concat.h | 3 | ||||
| -rwxr-xr-x | scripts/rust_is_available_test.py | 58 |
7 files changed, 229 insertions, 187 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3652b85be545..57cff77c2897 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -310,18 +310,13 @@ $(obj)/%.lst: $(obj)/%.c FORCE # The features in this list are the ones allowed for non-`rust/` code. # -# - Stable since Rust 1.79.0: `feature(slice_ptr_len)`. -# - Stable since Rust 1.81.0: `feature(lint_reasons)`. -# - Stable since Rust 1.82.0: `feature(asm_const)`, -# `feature(offset_of_nested)`, `feature(raw_ref_op)`. -# - Stable since Rust 1.84.0: `feature(strict_provenance)`. # - Stable since Rust 1.87.0: `feature(asm_goto)`. # - Expected to become stable: `feature(arbitrary_self_types)`. # - To be determined: `feature(used_with_arg)`. # # Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on # the unstable features in use. -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 +rust_allowed_features := arbitrary_self_types,asm_goto,used_with_arg # `--out-dir` is required to avoid temporaries being created by `rustc` in the # current working directory, which may be not accessible in the out-of-tree @@ -334,7 +329,6 @@ rust_common_cmd = \ -Zcrate-attr='feature($(rust_allowed_features))' \ -Zunstable-options --extern pin_init --extern kernel \ --crate-type rlib -L $(objtree)/rust/ \ - --crate-name $(basename $(notdir $@)) \ --sysroot=/dev/null \ --out-dir $(dir $@) --emit=dep-info=$(depfile) @@ -347,7 +341,12 @@ rust_common_cmd = \ # would not match each other. quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ - cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< $(cmd_objtool) + cmd_rustc_o_rs = $(rust_common_cmd) --emit=$(if $(CONFIG_RUST_INLINE_HELPERS),llvm-bc=$(patsubst %.o,%.bc,$@),obj=$@) $< \ + $(if $(CONFIG_RUST_INLINE_HELPERS),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ + $(objtree)/rust/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ + $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ + $(cmd_ld_single)) \ + $(cmd_objtool) define rule_rustc_o_rs $(call cmd_and_fixdep,rustc_o_rs) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index f9b545104f21..d5f9a0ca742c 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -10,8 +10,15 @@ import os import pathlib import subprocess import sys +from typing import Dict, Iterable, List, Literal, Optional, TypedDict -def args_crates_cfgs(cfgs): +def invoke_rustc(args: List[str]) -> str: + return subprocess.check_output( + [os.environ["RUSTC"]] + args, + stdin=subprocess.DEVNULL, + ).decode('utf-8').strip() + +def args_crates_cfgs(cfgs: List[str]) -> Dict[str, List[str]]: crates_cfgs = {} for cfg in cfgs: crate, vals = cfg.split("=", 1) @@ -19,54 +26,153 @@ def args_crates_cfgs(cfgs): return crates_cfgs -def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edition): +class Dependency(TypedDict): + crate: int + name: str + + +class Source(TypedDict): + include_dirs: List[str] + exclude_dirs: List[str] + + +class Crate(TypedDict): + display_name: str + root_module: str + is_workspace_member: bool + deps: List[Dependency] + cfg: List[str] + edition: str + env: Dict[str, str] + + +class ProcMacroCrate(Crate): + is_proc_macro: Literal[True] + proc_macro_dylib_path: str # `pathlib.Path` is not JSON serializable. + + +class CrateWithGenerated(Crate): + source: Source + + +def generate_crates( + srctree: pathlib.Path, + objtree: pathlib.Path, + sysroot_src: pathlib.Path, + external_src: Optional[pathlib.Path], + cfgs: List[str], + core_edition: str, +) -> List[Crate]: # Generate the configuration list. - cfg = [] + generated_cfg = [] with open(objtree / "include" / "generated" / "rustc_cfg") as fd: for line in fd: line = line.replace("--cfg=", "") line = line.replace("\n", "") - cfg.append(line) + generated_cfg.append(line) - # Now fill the crates list -- dependencies need to come first. - # - # Avoid O(n^2) iterations by keeping a map of indexes. - crates = [] - crates_indexes = {} + # Now fill the crates list. + crates: List[Crate] = [] crates_cfgs = args_crates_cfgs(cfgs) - def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): - crate = { + def get_crate_name(path: pathlib.Path) -> str: + return invoke_rustc(["--print", "crate-name", str(path)]) + + def build_crate( + display_name: str, + root_module: pathlib.Path, + deps: List[Dependency], + *, + cfg: Optional[List[str]], + is_workspace_member: Optional[bool], + edition: Optional[str], + ) -> Crate: + cfg = cfg if cfg is not None else crates_cfgs.get(display_name, []) + is_workspace_member = ( + is_workspace_member if is_workspace_member is not None else True + ) + edition = edition if edition is not None else "2021" + return { "display_name": display_name, "root_module": str(root_module), "is_workspace_member": is_workspace_member, - "is_proc_macro": is_proc_macro, - "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps], + "deps": deps, "cfg": cfg, "edition": edition, "env": { "RUST_MODFILE": "This is only for rust-analyzer" } } - if is_proc_macro: - proc_macro_dylib_name = subprocess.check_output( - [os.environ["RUSTC"], "--print", "file-names", "--crate-name", display_name, "--crate-type", "proc-macro", "-"], - stdin=subprocess.DEVNULL, - ).decode('utf-8').strip() - crate["proc_macro_dylib_path"] = f"{objtree}/rust/{proc_macro_dylib_name}" - crates_indexes[display_name] = len(crates) + + def append_proc_macro_crate( + display_name: str, + root_module: pathlib.Path, + deps: List[Dependency], + *, + cfg: Optional[List[str]] = None, + is_workspace_member: Optional[bool] = None, + edition: Optional[str] = None, + ) -> Dependency: + crate = build_crate( + display_name, + root_module, + deps, + cfg=cfg, + is_workspace_member=is_workspace_member, + edition=edition, + ) + proc_macro_dylib_name = invoke_rustc([ + "--print", + "file-names", + "--crate-name", + display_name, + "--crate-type", + "proc-macro", + "-", + ]) + proc_macro_crate: ProcMacroCrate = { + **crate, + "is_proc_macro": True, + "proc_macro_dylib_path": str(objtree / "rust" / proc_macro_dylib_name), + } + return register_crate(proc_macro_crate) + + def register_crate(crate: Crate) -> Dependency: + index = len(crates) crates.append(crate) + return {"crate": index, "name": crate["display_name"]} + + def append_crate( + display_name: str, + root_module: pathlib.Path, + deps: List[Dependency], + *, + cfg: Optional[List[str]] = None, + is_workspace_member: Optional[bool] = None, + edition: Optional[str] = None, + ) -> Dependency: + return register_crate( + build_crate( + display_name, + root_module, + deps, + cfg=cfg, + is_workspace_member=is_workspace_member, + edition=edition, + ) + ) def append_sysroot_crate( - display_name, - deps, - cfg=[], - ): - append_crate( + display_name: str, + deps: List[Dependency], + *, + cfg: Optional[List[str]] = None, + ) -> Dependency: + return append_crate( display_name, sysroot_src / display_name / "src" / "lib.rs", deps, - cfg, + cfg=cfg, is_workspace_member=False, # Miguel Ojeda writes: # @@ -98,129 +204,146 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit # NB: sysroot crates reexport items from one another so setting up our transitive dependencies # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`. - append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", [])) - append_sysroot_crate("alloc", ["core"]) - append_sysroot_crate("std", ["alloc", "core"]) - append_sysroot_crate("proc_macro", ["core", "std"]) + core = append_sysroot_crate("core", []) + alloc = append_sysroot_crate("alloc", [core]) + std = append_sysroot_crate("std", [alloc, core]) + proc_macro = append_sysroot_crate("proc_macro", [core, std]) - append_crate( + compiler_builtins = append_crate( "compiler_builtins", srctree / "rust" / "compiler_builtins.rs", - ["core"], + [core], ) - append_crate( + proc_macro2 = append_crate( "proc_macro2", srctree / "rust" / "proc-macro2" / "lib.rs", - ["core", "alloc", "std", "proc_macro"], - cfg=crates_cfgs["proc_macro2"], + [core, alloc, std, proc_macro], ) - append_crate( + quote = append_crate( "quote", srctree / "rust" / "quote" / "lib.rs", - ["core", "alloc", "std", "proc_macro", "proc_macro2"], - cfg=crates_cfgs["quote"], + [core, alloc, std, proc_macro, proc_macro2], edition="2018", ) - append_crate( + syn = append_crate( "syn", srctree / "rust" / "syn" / "lib.rs", - ["std", "proc_macro", "proc_macro2", "quote"], - cfg=crates_cfgs["syn"], + [std, proc_macro, proc_macro2, quote], ) - append_crate( + macros = append_proc_macro_crate( "macros", srctree / "rust" / "macros" / "lib.rs", - ["std", "proc_macro", "proc_macro2", "quote", "syn"], - is_proc_macro=True, + [std, proc_macro, proc_macro2, quote, syn], ) - append_crate( + build_error = append_crate( "build_error", srctree / "rust" / "build_error.rs", - ["core", "compiler_builtins"], + [core, compiler_builtins], ) - append_crate( + pin_init_internal = append_proc_macro_crate( "pin_init_internal", srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs", - ["std", "proc_macro", "proc_macro2", "quote", "syn"], - cfg=["kernel"], - is_proc_macro=True, + [std, proc_macro, proc_macro2, quote, syn], ) - append_crate( + pin_init = append_crate( "pin_init", srctree / "rust" / "pin-init" / "src" / "lib.rs", - ["core", "compiler_builtins", "pin_init_internal", "macros"], - cfg=["kernel"], + [core, compiler_builtins, pin_init_internal, macros], ) - append_crate( + ffi = append_crate( "ffi", srctree / "rust" / "ffi.rs", - ["core", "compiler_builtins"], + [core, compiler_builtins], ) def append_crate_with_generated( - display_name, - deps, - ): - append_crate( + display_name: str, + deps: List[Dependency], + ) -> Dependency: + crate = build_crate( display_name, srctree / "rust"/ display_name / "lib.rs", deps, - cfg=cfg, + cfg=generated_cfg, + is_workspace_member=True, + edition=None, ) - crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) - crates[-1]["source"] = { - "include_dirs": [ - str(srctree / "rust" / display_name), - str(objtree / "rust") - ], - "exclude_dirs": [], + crate["env"]["OBJTREE"] = str(objtree.resolve(True)) + crate_with_generated: CrateWithGenerated = { + **crate, + "source": { + "include_dirs": [ + str(srctree / "rust" / display_name), + str(objtree / "rust"), + ], + "exclude_dirs": [], + }, } + return register_crate(crate_with_generated) + + bindings = append_crate_with_generated("bindings", [core, ffi, pin_init]) + uapi = append_crate_with_generated("uapi", [core, ffi, pin_init]) + kernel = append_crate_with_generated( + "kernel", [core, macros, build_error, pin_init, ffi, bindings, uapi] + ) - append_crate_with_generated("bindings", ["core", "ffi", "pin_init"]) - append_crate_with_generated("uapi", ["core", "ffi", "pin_init"]) - append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"]) + scripts = srctree / "scripts" + makefile = (scripts / "Makefile").read_text() + for path in scripts.glob("*.rs"): + name = path.stem + if f"{name}-rust" not in makefile: + continue + append_crate( + name, + path, + [std], + ) - def is_root_crate(build_file, target): + def is_root_crate(build_file: pathlib.Path, target: str) -> bool: try: - return f"{target}.o" in open(build_file).read() + contents = build_file.read_text() except FileNotFoundError: return False + return f"{target}.o" in contents # Then, the rest outside of `rust/`. # # We explicitly mention the top-level folders we want to cover. - extra_dirs = map(lambda dir: srctree / dir, ("samples", "drivers")) + extra_dirs: Iterable[pathlib.Path] = ( + srctree / dir for dir in ("samples", "drivers") + ) if external_src is not None: extra_dirs = [external_src] for folder in extra_dirs: for path in folder.rglob("*.rs"): logging.info("Checking %s", path) - name = path.name.replace(".rs", "") + file_name = path.stem # Skip those that are not crate roots. - if not is_root_crate(path.parent / "Makefile", name) and \ - not is_root_crate(path.parent / "Kbuild", name): + if not is_root_crate(path.parent / "Makefile", file_name) and \ + not is_root_crate(path.parent / "Kbuild", file_name): continue - logging.info("Adding %s", name) + crate_name = get_crate_name(path) + logging.info("Adding %s", crate_name) append_crate( - name, + crate_name, path, - ["core", "kernel", "pin_init"], - cfg=cfg, + [core, kernel, pin_init], + cfg=generated_cfg, ) return crates -def main(): +def main() -> None: parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='store_true') parser.add_argument('--cfgs', action='append', default=[]) @@ -230,7 +353,18 @@ def main(): parser.add_argument("sysroot", type=pathlib.Path) parser.add_argument("sysroot_src", type=pathlib.Path) parser.add_argument("exttree", type=pathlib.Path, nargs="?") - args = parser.parse_args() + + class Args(argparse.Namespace): + verbose: bool + cfgs: List[str] + srctree: pathlib.Path + objtree: pathlib.Path + sysroot: pathlib.Path + sysroot_src: pathlib.Path + exttree: Optional[pathlib.Path] + core_edition: str + + args = parser.parse_args(namespace=Args()) logging.basicConfig( format="[%(asctime)s] [%(levelname)s] %(message)s", diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh index 99b5575c1ef7..b96ec2d379b6 100755 --- a/scripts/min-tool-version.sh +++ b/scripts/min-tool-version.sh @@ -31,10 +31,10 @@ llvm) fi ;; rustc) - echo 1.78.0 + echo 1.85.0 ;; bindgen) - echo 0.65.1 + echo 0.71.1 ;; *) echo "$1: unknown tool" >&2 diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh index d2323de0692c..551f1ebd0dcb 100755 --- a/scripts/rust_is_available.sh +++ b/scripts/rust_is_available.sh @@ -121,14 +121,8 @@ fi # Check that the Rust bindings generator is suitable. # # Non-stable and distributions' versions may have a version suffix, e.g. `-dev`. -# -# The dummy parameter `workaround-for-0.69.0` is required to support 0.69.0 -# (https://github.com/rust-lang/rust-bindgen/pull/2678) and 0.71.0 -# (https://github.com/rust-lang/rust-bindgen/pull/3040). It can be removed when -# the minimum version is upgraded past the latter (0.69.1 and 0.71.1 both fixed -# the issue). rust_bindings_generator_output=$( \ - LC_ALL=C "$BINDGEN" --version workaround-for-0.69.0 2>/dev/null + LC_ALL=C "$BINDGEN" --version 2>/dev/null ) || rust_bindings_generator_code=$? if [ -n "$rust_bindings_generator_code" ]; then echo >&2 "***" @@ -163,19 +157,6 @@ if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cvers echo >&2 "***" exit 1 fi -if [ "$rust_bindings_generator_cversion" -eq 6600 ] || - [ "$rust_bindings_generator_cversion" -eq 6601 ]; then - # Distributions may have patched the issue (e.g. Debian did). - if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_0_66.h >/dev/null; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' versions 0.66.0 and 0.66.1 may not" - echo >&2 "*** work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2567)," - echo >&2 "*** unless patched (like Debian's)." - echo >&2 "*** Your version: $rust_bindings_generator_version" - echo >&2 "***" - warning=1 - fi -fi # Check that the `libclang` used by the Rust bindings generator is suitable. # @@ -227,21 +208,6 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then exit 1 fi -if [ "$bindgen_libclang_cversion" -ge 1900100 ] && - [ "$rust_bindings_generator_cversion" -lt 6905 ]; then - # Distributions may have patched the issue (e.g. Debian did). - if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_concat.h | grep -q foofoo; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.69.5 together with libclang >= 19.1" - echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824)," - echo >&2 "*** unless patched (like Debian's)." - echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" - echo >&2 "*** Your libclang version: $bindgen_libclang_version" - echo >&2 "***" - warning=1 - fi -fi - # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. # diff --git a/scripts/rust_is_available_bindgen_0_66.h b/scripts/rust_is_available_bindgen_0_66.h deleted file mode 100644 index c0431293421c..000000000000 --- a/scripts/rust_is_available_bindgen_0_66.h +++ /dev/null @@ -1,2 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#define A "\0" diff --git a/scripts/rust_is_available_bindgen_libclang_concat.h b/scripts/rust_is_available_bindgen_libclang_concat.h deleted file mode 100644 index efc6e98d0f1d..000000000000 --- a/scripts/rust_is_available_bindgen_libclang_concat.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#define F(x) int x##x -F(foo); diff --git a/scripts/rust_is_available_test.py b/scripts/rust_is_available_test.py index 4fcc319dea84..d6d54b7ea42a 100755 --- a/scripts/rust_is_available_test.py +++ b/scripts/rust_is_available_test.py @@ -54,37 +54,23 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False): + def generate_bindgen(cls, version_stdout, libclang_stderr): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else: libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)" - if version_0_66_patched: - version_0_66_case = "pass" - else: - version_0_66_case = "raise SystemExit(1)" - - if libclang_concat_patched: - libclang_concat_case = "print('pub static mut foofoo: ::std::os::raw::c_int;')" - else: - libclang_concat_case = "pass" - return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} -elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv): - {version_0_66_case} -elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv): - {libclang_concat_case} else: print({repr(version_stdout)}) """) @classmethod - def generate_bindgen_version(cls, stdout, version_0_66_patched=False): - return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr, version_0_66_patched) + def generate_bindgen_version(cls, stdout): + return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr) @classmethod def generate_bindgen_libclang_failure(cls): @@ -245,19 +231,6 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"Rust bindings generator '{bindgen}' is too old.", result.stderr) - def test_bindgen_bad_version_0_66_0_and_0_66_1(self): - for version in ("0.66.0", "0.66.1"): - with self.subTest(version=version): - bindgen = self.generate_bindgen_version(f"bindgen {version}") - result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen }) - self.assertIn(f"Rust bindings generator '{bindgen}' versions 0.66.0 and 0.66.1 may not", result.stderr) - - def test_bindgen_bad_version_0_66_0_and_0_66_1_patched(self): - for version in ("0.66.0", "0.66.1"): - with self.subTest(version=version): - bindgen = self.generate_bindgen_version(f"bindgen {version}", True) - result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen }) - def test_bindgen_libclang_failure(self): bindgen = self.generate_bindgen_libclang_failure() result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) @@ -275,31 +248,6 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr) - def test_bindgen_bad_libclang_concat(self): - for (bindgen_version, libclang_version, expected_not_patched) in ( - ("0.69.4", "18.0.0", self.Expected.SUCCESS), - ("0.69.4", "19.1.0", self.Expected.SUCCESS_WITH_WARNINGS), - ("0.69.4", "19.2.0", self.Expected.SUCCESS_WITH_WARNINGS), - - ("0.69.5", "18.0.0", self.Expected.SUCCESS), - ("0.69.5", "19.1.0", self.Expected.SUCCESS), - ("0.69.5", "19.2.0", self.Expected.SUCCESS), - - ("0.70.0", "18.0.0", self.Expected.SUCCESS), - ("0.70.0", "19.1.0", self.Expected.SUCCESS), - ("0.70.0", "19.2.0", self.Expected.SUCCESS), - ): - with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): - cc = self.generate_clang(f"clang version {libclang_version}") - libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" - bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) - result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) - if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: - self.assertIn(f"Rust bindings generator '{bindgen}' < 0.69.5 together with libclang >= 19.1", result.stderr) - - bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_concat_patched=True) - result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) - def test_clang_matches_bindgen_libclang_different_bindgen(self): 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") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen }) |
