Skip to content

Commit eaa7bbe

Browse files
committed
add rust-analyzer make target
This target creates ${objtree}/rust-project.json which can be read by rust-analyzer to help with autocompletion for the kernel crate. The raw bindings do not work yet, as rust-analyzer seems to have a problem with the include macro. Signed-off-by: Finn Behrens <[email protected]>
1 parent 2222bec commit eaa7bbe

File tree

5 files changed

+108
-40
lines changed

5 files changed

+108
-40
lines changed

Diff for: Documentation/rust/quick-start.rst

+2-5
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,8 @@ definition, and other features.
155155
``rust-analyzer`` will need to be
156156
`configured <https://rust-analyzer.github.io/manual.html#non-cargo-based-projects>`_
157157
to work with the kernel by adding a ``rust-project.json`` file in the root folder.
158-
The example ``Documentation/rust/rust-project.json`` can
159-
be used after updating ``sysroot_src`` and including the relevant modules.
160-
The path to ``sysroot_src`` is given by::
161-
162-
$(rustc --print sysroot)/lib/rustlib/src/rust/library
158+
A ``rust-project.json`` can be generated by building the Make target ``rust-analyzer``,
159+
which will create a ``rust-project.json`` in the root of the output directory.
163160

164161

165162
Configuration

Diff for: Documentation/rust/rust-project.json

-35
This file was deleted.

Diff for: Makefile

+6
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,8 @@ help:
17381738
@echo ' is formatted, printing a diff otherwise.'
17391739
@echo ' rustdoc - Generate Rust documentation'
17401740
@echo ' (requires kernel .config)'
1741+
@echo ' rust-analyzer - Generate rust-project.json rust-analyzer support file'
1742+
@echo ' (requires kernel .config)'
17411743
@echo ''
17421744
@$(if $(dtstree), \
17431745
echo 'Devicetree:'; \
@@ -1830,6 +1832,10 @@ rustfmt:
18301832
rustfmtcheck:
18311833
find -name '*.rs' | xargs $(RUSTFMT) --check
18321834

1835+
# IDE support targets
1836+
PHONY += rust-analyzer
1837+
rust-analyzer: prepare0
1838+
$(Q)$(MAKE) $(build)=rust $@
18331839

18341840
# Misc
18351841
# ---------------------------------------------------------------------------

Diff for: rust/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,6 @@ $(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
150150
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
151151
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
152152
$(call if_changed_dep,rustc_library)
153+
154+
rust-analyzer:
155+
$(Q)$(srctree)/scripts/generate_rust_analyzer.sh $(srctree) $(objtree) $(RUST_LIB_SRC) $(abspath $(objtree)/rust/bindings_generated.rs) > $(objtree)/rust-project.json

Diff for: scripts/generate_rust_analyzer.sh

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/env bash
2+
3+
srctree=$1
4+
objtree=$2
5+
lib_src=$3
6+
bindgen_file=$4
7+
8+
9+
# TODO: create issue at RA to accept @arg file
10+
function generate_cfgs() {
11+
echo '['
12+
cfgs=$(cat $objtree/include/generated/rustc_cfg | sed 's/--cfg=//' | sed 's/"/\\"/g' | sed 's/$/",/' | sed 's/^/"/')
13+
echo ${cfgs::-1}
14+
echo ']'
15+
}
16+
17+
function generate_crate() {
18+
name=$1
19+
module=$2
20+
member=${3:-"true"}
21+
cfg=${4:-$(generate_cfgs)}
22+
deps=${5:-'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"},{"crate":4,"name":"kernel"}]'}
23+
extra=${CRATE_EXTRA:-""}
24+
25+
echo "{
26+
\"display_name\":\"$name\",
27+
\"root_module\":\"$module\",
28+
\"edition\":\"2018\",
29+
\"deps\":$deps,
30+
\"is_workspace_member\": $member,
31+
\"cfg\": $cfg,
32+
\"env\": {
33+
\"RUST_BINDINGS_FILE\": \"$bindgen_file\",
34+
\"RUST_MODFILE\": \"This is only for rust-analyzer\"
35+
}
36+
$extra
37+
}"
38+
}
39+
40+
function generate_kernel() {
41+
generate_crate "core" "${lib_src}/core/src/lib.rs" "false" "[]" "[]"
42+
echo ","
43+
generate_crate "compiler_builtins" "${srctree}/rust/compiler_builtins.rs" "true" "[]" "[]"
44+
echo ","
45+
generate_crate "alloc" "${lib_src}/alloc/src/lib.rs" "false" "[]" \
46+
'[{"crate":0,"name":"core"},{"crate":1,"name":"compiler_builtins"}]'
47+
echo ","
48+
echo '{
49+
"display_name":"module",
50+
"root_module":"'${srctree}'/rust/module.rs",
51+
"edition":"2018",
52+
"is_workspace_member":true,
53+
"deps": [],
54+
"proc_macro_dylib_path": "rust/libmodule.so",
55+
"cfg": []
56+
},'
57+
generate_crate "kernel" "${srctree}/rust/kernel/lib.rs" "true" "$(generate_cfgs)" \
58+
'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"},{"crate":3,"name":"module"}]'
59+
echo ","
60+
}
61+
62+
function check_and_generate() {
63+
filepath=$1
64+
file=$(basename $filepath)
65+
makefile=$(dirname $filepath)/Makefile
66+
name=${file%.rs}
67+
objname=${name}.o
68+
echo "checking $filepath" >&2
69+
if grep -q $objname $makefile; then
70+
echo "building crate $name" >&2
71+
echo $(generate_crate "$name" "$filepath")
72+
echo ","
73+
fi
74+
}
75+
76+
function generate_drivers() {
77+
drivers=$(find "$srctree/drivers" -name '*.rs')
78+
for x in $drivers; do
79+
check_and_generate $x
80+
done
81+
echo ""
82+
}
83+
84+
function generate_samples() {
85+
samples=$(find "$srctree/samples/rust" -name '*.rs')
86+
for x in $samples; do
87+
check_and_generate $x
88+
done
89+
}
90+
91+
echo '{"crates":['
92+
generate_kernel
93+
generate_drivers
94+
samples=$(generate_samples)
95+
echo ${samples::-1}
96+
echo '],
97+
"sysroot_src": "'${lib_src}'"}'

0 commit comments

Comments
 (0)