diff options
| author | Miguel Ojeda <ojeda@kernel.org> | 2026-06-09 04:18:30 +0200 |
|---|---|---|
| committer | Miguel Ojeda <ojeda@kernel.org> | 2026-06-09 04:25:04 +0200 |
| commit | 98cc68794c003bc76fc9da2e8a075e947eee5921 (patch) | |
| tree | 3d8521950d137a9ab38233e1aab74ccbb46b6940 /scripts | |
| parent | 759da9e0fa79223138ec8c18b9075cd7dace6070 (diff) | |
| parent | 506bb8742ea52da13f9f281c5cb2b603ac1931e7 (diff) | |
Merge patch series "`zerocopy` support"
Introduce support for `zerocopy` [1][2]:
Fast, safe, compile error. Pick two.
Zerocopy makes zero-cost memory manipulation effortless. We write
`unsafe` so you don't have to.
It essentially provides derivable traits (e.g. `FromBytes`) and macros
(e.g. `transmute!`) for safely converting between byte sequences and
other types. Having such support allows us to remove some `unsafe` code.
It is among the most downloaded Rust crates (top #50 recent, top #100
all-time downloads; according to crates.io), and it is also used by the
Rust compiler itself.
The series starts with a few preparation commits, then the `zerocopy`
and `zerocopy-derive` crates are added. Finally, an example patch using
it is on top, removing one `unsafe impl`.
I had to adapt the crates slightly (just +2/-3 lines), but both patches
could potentially be provided upstream eventually. Please see the
commits for details.
In total, it is about ~39k lines added, ~32k without counting `benches/`
which are just for documentation purposes.
See the cover letter for `syn` for some more details about depending on
third-party crates in commit 54e3eae85562 ("Merge patch series "`syn`
support"").
The codegen of an isolated example function similar to the patch on top
is essentially identical. It also turns out that (for that particular
case) `zerocopy`'s version, even under `debug-assertions` enabled, has
no remaining panics, unlike a few in the current code (because the
compiler can prove the remaining `ub_checks` statically).
So their "fast, safe" does indeed check out -- at least in that case.
P.S. This version of `zerocopy` has already the unstable `Ptr{,Inner}`
types -- to play with them, please use:
make ... KRUSTFLAGS=--cfg=zerocopy_unstable_ptr
Link: https://github.com/google/zerocopy [1]
Link: https://docs.rs/zerocopy [2]
Link: https://patch.msgid.link/20260608141439.182634-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Makefile.build | 1 | ||||
| -rwxr-xr-x | scripts/generate_rust_analyzer.py | 38 |
2 files changed, 33 insertions, 6 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3498d25b15e8..911745743246 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -329,6 +329,7 @@ rust_common_cmd = \ -Zcrate-attr=no_std \ -Zcrate-attr='feature($(rust_allowed_features))' \ -Zunstable-options --extern pin_init --extern kernel \ + --extern zerocopy --extern zerocopy_derive \ --crate-type rlib -L $(objtree)/rust/ \ --sysroot=/dev/null \ --out-dir $(dir $@) --emit=dep-info=$(depfile) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index d5f9a0ca742c..dc1219736f77 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -26,6 +26,14 @@ def args_crates_cfgs(cfgs: List[str]) -> Dict[str, List[str]]: return crates_cfgs +def args_crates_envs(envs: List[str]) -> Dict[str, Dict[str, str]]: + crates_envs = {} + for env in envs: + crate, vals = env.split("=", 1) + crates_envs[crate] = dict(v.split("=", 1) for v in vals.split()) + + return crates_envs + class Dependency(TypedDict): crate: int name: str @@ -61,6 +69,7 @@ def generate_crates( sysroot_src: pathlib.Path, external_src: Optional[pathlib.Path], cfgs: List[str], + envs: List[str], core_edition: str, ) -> List[Crate]: # Generate the configuration list. @@ -74,6 +83,7 @@ def generate_crates( # Now fill the crates list. crates: List[Crate] = [] crates_cfgs = args_crates_cfgs(cfgs) + crates_envs = args_crates_envs(envs) def get_crate_name(path: pathlib.Path) -> str: return invoke_rustc(["--print", "crate-name", str(path)]) @@ -92,6 +102,10 @@ def generate_crates( is_workspace_member if is_workspace_member is not None else True ) edition = edition if edition is not None else "2021" + crate_env = { + "RUST_MODFILE": "This is only for rust-analyzer", + **crates_envs.get(display_name, {}), + } return { "display_name": display_name, "root_module": str(root_module), @@ -99,9 +113,7 @@ def generate_crates( "deps": deps, "cfg": cfg, "edition": edition, - "env": { - "RUST_MODFILE": "This is only for rust-analyzer" - } + "env": crate_env, } def append_proc_macro_crate( @@ -240,6 +252,12 @@ def generate_crates( [std, proc_macro, proc_macro2, quote, syn], ) + zerocopy_derive = append_proc_macro_crate( + "zerocopy_derive", + srctree / "rust" / "zerocopy-derive" / "lib.rs", + [std, proc_macro, proc_macro2, quote, syn], + ) + build_error = append_crate( "build_error", srctree / "rust" / "build_error.rs", @@ -264,6 +282,12 @@ def generate_crates( [core, compiler_builtins], ) + zerocopy = append_crate( + "zerocopy", + srctree / "rust" / "zerocopy" / "src" / "lib.rs", + [core, compiler_builtins], + ) + def append_crate_with_generated( display_name: str, deps: List[Dependency], @@ -292,7 +316,7 @@ def generate_crates( 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] + "kernel", [core, macros, build_error, pin_init, ffi, bindings, uapi, zerocopy, zerocopy_derive] ) scripts = srctree / "scripts" @@ -337,7 +361,7 @@ def generate_crates( append_crate( crate_name, path, - [core, kernel, pin_init], + [core, kernel, pin_init, zerocopy, zerocopy_derive], cfg=generated_cfg, ) @@ -347,6 +371,7 @@ def main() -> None: parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='store_true') parser.add_argument('--cfgs', action='append', default=[]) + parser.add_argument('--envs', action='append', default=[]) parser.add_argument("core_edition") parser.add_argument("srctree", type=pathlib.Path) parser.add_argument("objtree", type=pathlib.Path) @@ -357,6 +382,7 @@ def main() -> None: class Args(argparse.Namespace): verbose: bool cfgs: List[str] + envs: List[str] srctree: pathlib.Path objtree: pathlib.Path sysroot: pathlib.Path @@ -372,7 +398,7 @@ def main() -> None: ) rust_project = { - "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), + "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.envs, args.core_edition), "sysroot": str(args.sysroot), } |
