| 1 | |
| 2 | |
| 3 | |
| 4 |
|
| 5 |
|
| 6 | import argparse
|
| 7 | import json
|
| 8 | import logging
|
| 9 | import os
|
| 10 | import pathlib
|
| 11 | import sys
|
| 12 |
|
| 13 | def args_crates_cfgs(cfgs):
|
| 14 | crates_cfgs = {}
|
| 15 | for cfg in cfgs:
|
| 16 | crate, vals = cfg.split("=", 1)
|
| 17 | crates_cfgs[crate] = vals.replace("--cfg", "").split()
|
| 18 |
|
| 19 | return crates_cfgs
|
| 20 |
|
| 21 | def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
|
| 22 | |
| 23 | cfg = []
|
| 24 | with open(objtree / "include" / "generated" / "rustc_cfg") as fd:
|
| 25 | for line in fd:
|
| 26 | line = line.replace("--cfg=", "")
|
| 27 | line = line.replace("\n", "")
|
| 28 | cfg.append(line)
|
| 29 |
|
| 30 | |
| 31 | |
| 32 | |
| 33 | crates = []
|
| 34 | crates_indexes = {}
|
| 35 | crates_cfgs = args_crates_cfgs(cfgs)
|
| 36 |
|
| 37 | def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False):
|
| 38 | crates_indexes[display_name] = len(crates)
|
| 39 | crates.append({
|
| 40 | "display_name": display_name,
|
| 41 | "root_module": str(root_module),
|
| 42 | "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],
|
| 45 | "cfg": cfg,
|
| 46 | "edition": "2021",
|
| 47 | "env": {
|
| 48 | "RUST_MODFILE": "This is only for rust-analyzer"
|
| 49 | }
|
| 50 | })
|
| 51 |
|
| 52 | |
| 53 | append_crate(
|
| 54 | "core",
|
| 55 | sysroot_src / "core" / "src" / "lib.rs",
|
| 56 | [],
|
| 57 | cfg=crates_cfgs.get("core", []),
|
| 58 | is_workspace_member=False,
|
| 59 | )
|
| 60 |
|
| 61 | append_crate(
|
| 62 | "compiler_builtins",
|
| 63 | srctree / "rust" / "compiler_builtins.rs",
|
| 64 | [],
|
| 65 | )
|
| 66 |
|
| 67 | append_crate(
|
| 68 | "alloc",
|
| 69 | sysroot_src / "alloc" / "src" / "lib.rs",
|
| 70 | ["core", "compiler_builtins"],
|
| 71 | cfg=crates_cfgs.get("alloc", []),
|
| 72 | )
|
| 73 |
|
| 74 | append_crate(
|
| 75 | "macros",
|
| 76 | srctree / "rust" / "macros" / "lib.rs",
|
| 77 | [],
|
| 78 | is_proc_macro=True,
|
| 79 | )
|
| 80 | crates[-1]["proc_macro_dylib_path"] = f"{objtree}/rust/libmacros.so"
|
| 81 |
|
| 82 | append_crate(
|
| 83 | "build_error",
|
| 84 | srctree / "rust" / "build_error.rs",
|
| 85 | ["core", "compiler_builtins"],
|
| 86 | )
|
| 87 |
|
| 88 | append_crate(
|
| 89 | "bindings",
|
| 90 | srctree / "rust"/ "bindings" / "lib.rs",
|
| 91 | ["core"],
|
| 92 | cfg=cfg,
|
| 93 | )
|
| 94 | crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
|
| 95 |
|
| 96 | append_crate(
|
| 97 | "kernel",
|
| 98 | srctree / "rust" / "kernel" / "lib.rs",
|
| 99 | ["core", "alloc", "macros", "build_error", "bindings"],
|
| 100 | cfg=cfg,
|
| 101 | )
|
| 102 | crates[-1]["source"] = {
|
| 103 | "include_dirs": [
|
| 104 | str(srctree / "rust" / "kernel"),
|
| 105 | str(objtree / "rust")
|
| 106 | ],
|
| 107 | "exclude_dirs": [],
|
| 108 | }
|
| 109 |
|
| 110 | def is_root_crate(build_file, target):
|
| 111 | try:
|
| 112 | return f"{target}.o" in open(build_file).read()
|
| 113 | except FileNotFoundError:
|
| 114 | return False
|
| 115 |
|
| 116 | |
| 117 | |
| 118 | |
| 119 | extra_dirs = map(lambda dir: srctree / dir, ("samples", "drivers"))
|
| 120 | if external_src is not None:
|
| 121 | extra_dirs = [external_src]
|
| 122 | for folder in extra_dirs:
|
| 123 | for path in folder.rglob("*.rs"):
|
| 124 | logging.info("Checking %s", path)
|
| 125 | name = path.name.replace(".rs", "")
|
| 126 |
|
| 127 | |
| 128 | if not is_root_crate(path.parent / "Makefile", name) and \
|
| 129 | not is_root_crate(path.parent / "Kbuild", name):
|
| 130 | continue
|
| 131 |
|
| 132 | logging.info("Adding %s", name)
|
| 133 | append_crate(
|
| 134 | name,
|
| 135 | path,
|
| 136 | ["core", "alloc", "kernel"],
|
| 137 | cfg=cfg,
|
| 138 | )
|
| 139 |
|
| 140 | return crates
|
| 141 |
|
| 142 | def main():
|
| 143 | parser = argparse.ArgumentParser()
|
| 144 | parser.add_argument('--verbose', '-v', action='store_true')
|
| 145 | parser.add_argument('--cfgs', action='append', default=[])
|
| 146 | parser.add_argument("srctree", type=pathlib.Path)
|
| 147 | parser.add_argument("objtree", type=pathlib.Path)
|
| 148 | parser.add_argument("sysroot", type=pathlib.Path)
|
| 149 | parser.add_argument("sysroot_src", type=pathlib.Path)
|
| 150 | parser.add_argument("exttree", type=pathlib.Path, nargs="?")
|
| 151 | args = parser.parse_args()
|
| 152 |
|
| 153 | logging.basicConfig(
|
| 154 | format="[%(asctime)s] [%(levelname)s] %(message)s",
|
| 155 | level=logging.INFO if args.verbose else logging.WARNING
|
| 156 | )
|
| 157 |
|
| 158 | |
| 159 | assert args.sysroot in args.sysroot_src.parents
|
| 160 |
|
| 161 | rust_project = {
|
| 162 | "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs),
|
| 163 | "sysroot": str(args.sysroot),
|
| 164 | }
|
| 165 |
|
| 166 | json.dump(rust_project, sys.stdout, sort_keys=True, indent=4)
|
| 167 |
|
| 168 | if __name__ == "__main__":
|
| 169 | main()
|