forked from mirrors/linux
		
	scripts: add generate_rust_analyzer.py
				
					
				
			The `generate_rust_analyzer.py` script generates the configuration file (`rust-project.json`) for rust-analyzer. rust-analyzer is a modular compiler frontend for the Rust language. It provides an LSP server which can be used in editors such as VS Code, Emacs or Vim. Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Finn Behrens <me@kloenk.de> Signed-off-by: Finn Behrens <me@kloenk.de> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Co-developed-by: Gary Guo <gary@garyguo.net> Signed-off-by: Gary Guo <gary@garyguo.net> Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de> Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de> Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com> Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
		
							parent
							
								
									99115db4ec
								
							
						
					
					
						commit
						8c4555ccc5
					
				
					 2 changed files with 138 additions and 0 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -162,3 +162,6 @@ x509.genkey | |||
| 
 | ||||
| # Documentation toolchain | ||||
| sphinx_*/ | ||||
| 
 | ||||
| # Rust analyzer configuration | ||||
| /rust-project.json | ||||
|  |  | |||
							
								
								
									
										135
									
								
								scripts/generate_rust_analyzer.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										135
									
								
								scripts/generate_rust_analyzer.py
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,135 @@ | |||
| #!/usr/bin/env python3 | ||||
| # SPDX-License-Identifier: GPL-2.0 | ||||
| """generate_rust_analyzer - Generates the `rust-project.json` file for `rust-analyzer`. | ||||
| """ | ||||
| 
 | ||||
| import argparse | ||||
| import json | ||||
| import logging | ||||
| import pathlib | ||||
| import sys | ||||
| 
 | ||||
| def generate_crates(srctree, objtree, sysroot_src): | ||||
|     # Generate the configuration list. | ||||
|     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) | ||||
| 
 | ||||
|     # Now fill the crates list -- dependencies need to come first. | ||||
|     # | ||||
|     # Avoid O(n^2) iterations by keeping a map of indexes. | ||||
|     crates = [] | ||||
|     crates_indexes = {} | ||||
| 
 | ||||
|     def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False): | ||||
|         crates_indexes[display_name] = len(crates) | ||||
|         crates.append({ | ||||
|             "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], | ||||
|             "cfg": cfg, | ||||
|             "edition": "2021", | ||||
|             "env": { | ||||
|                 "RUST_MODFILE": "This is only for rust-analyzer" | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|     # First, the ones in `rust/` since they are a bit special. | ||||
|     append_crate( | ||||
|         "core", | ||||
|         sysroot_src / "core" / "src" / "lib.rs", | ||||
|         [], | ||||
|         is_workspace_member=False, | ||||
|     ) | ||||
| 
 | ||||
|     append_crate( | ||||
|         "compiler_builtins", | ||||
|         srctree / "rust" / "compiler_builtins.rs", | ||||
|         [], | ||||
|     ) | ||||
| 
 | ||||
|     append_crate( | ||||
|         "alloc", | ||||
|         srctree / "rust" / "alloc" / "lib.rs", | ||||
|         ["core", "compiler_builtins"], | ||||
|     ) | ||||
| 
 | ||||
|     append_crate( | ||||
|         "macros", | ||||
|         srctree / "rust" / "macros" / "lib.rs", | ||||
|         [], | ||||
|         is_proc_macro=True, | ||||
|     ) | ||||
|     crates[-1]["proc_macro_dylib_path"] = "rust/libmacros.so" | ||||
| 
 | ||||
|     append_crate( | ||||
|         "bindings", | ||||
|         srctree / "rust"/ "bindings" / "lib.rs", | ||||
|         ["core"], | ||||
|         cfg=cfg, | ||||
|     ) | ||||
|     crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) | ||||
| 
 | ||||
|     append_crate( | ||||
|         "kernel", | ||||
|         srctree / "rust" / "kernel" / "lib.rs", | ||||
|         ["core", "alloc", "macros", "bindings"], | ||||
|         cfg=cfg, | ||||
|     ) | ||||
|     crates[-1]["source"] = { | ||||
|         "include_dirs": [ | ||||
|             str(srctree / "rust" / "kernel"), | ||||
|             str(objtree / "rust") | ||||
|         ], | ||||
|         "exclude_dirs": [], | ||||
|     } | ||||
| 
 | ||||
|     # Then, the rest outside of `rust/`. | ||||
|     # | ||||
|     # We explicitly mention the top-level folders we want to cover. | ||||
|     for folder in ("samples", "drivers"): | ||||
|         for path in (srctree / folder).rglob("*.rs"): | ||||
|             logging.info("Checking %s", path) | ||||
|             name = path.name.replace(".rs", "") | ||||
| 
 | ||||
|             # Skip those that are not crate roots. | ||||
|             if f"{name}.o" not in open(path.parent / "Makefile").read(): | ||||
|                 continue | ||||
| 
 | ||||
|             logging.info("Adding %s", name) | ||||
|             append_crate( | ||||
|                 name, | ||||
|                 path, | ||||
|                 ["core", "alloc", "kernel"], | ||||
|                 cfg=cfg, | ||||
|             ) | ||||
| 
 | ||||
|     return crates | ||||
| 
 | ||||
| def main(): | ||||
|     parser = argparse.ArgumentParser() | ||||
|     parser.add_argument('--verbose', '-v', action='store_true') | ||||
|     parser.add_argument("srctree", type=pathlib.Path) | ||||
|     parser.add_argument("objtree", type=pathlib.Path) | ||||
|     parser.add_argument("sysroot_src", type=pathlib.Path) | ||||
|     args = parser.parse_args() | ||||
| 
 | ||||
|     logging.basicConfig( | ||||
|         format="[%(asctime)s] [%(levelname)s] %(message)s", | ||||
|         level=logging.INFO if args.verbose else logging.WARNING | ||||
|     ) | ||||
| 
 | ||||
|     rust_project = { | ||||
|         "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src), | ||||
|         "sysroot_src": str(args.sysroot_src), | ||||
|     } | ||||
| 
 | ||||
|     json.dump(rust_project, sys.stdout, sort_keys=True, indent=4) | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
		Loading…
	
		Reference in a new issue
	
	 Miguel Ojeda
						Miguel Ojeda