summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorMiguel Ojeda <ojeda@kernel.org>2026-06-09 04:18:30 +0200
committerMiguel Ojeda <ojeda@kernel.org>2026-06-09 04:25:04 +0200
commit98cc68794c003bc76fc9da2e8a075e947eee5921 (patch)
tree3d8521950d137a9ab38233e1aab74ccbb46b6940 /scripts
parent759da9e0fa79223138ec8c18b9075cd7dace6070 (diff)
parent506bb8742ea52da13f9f281c5cb2b603ac1931e7 (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.build1
-rwxr-xr-xscripts/generate_rust_analyzer.py38
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),
}