Skip to content

Commit

Permalink
add rust-analyzer make target
Browse files Browse the repository at this point in the history
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 <me@kloenk.de>
  • Loading branch information
kloenk committed Apr 30, 2021
1 parent 2222bec commit eaa7bbe
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 40 deletions.
7 changes: 2 additions & 5 deletions Documentation/rust/quick-start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,8 @@ definition, and other features.
``rust-analyzer`` will need to be
`configured <https://rust-analyzer.github.io/manual.html#non-cargo-based-projects>`_
to work with the kernel by adding a ``rust-project.json`` file in the root folder.
The example ``Documentation/rust/rust-project.json`` can
be used after updating ``sysroot_src`` and including the relevant modules.
The path to ``sysroot_src`` is given by::

$(rustc --print sysroot)/lib/rustlib/src/rust/library
A ``rust-project.json`` can be generated by building the Make target ``rust-analyzer``,
which will create a ``rust-project.json`` in the root of the output directory.


Configuration
Expand Down
35 changes: 0 additions & 35 deletions Documentation/rust/rust-project.json

This file was deleted.

6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,8 @@ help:
@echo ' is formatted, printing a diff otherwise.'
@echo ' rustdoc - Generate Rust documentation'
@echo ' (requires kernel .config)'
@echo ' rust-analyzer - Generate rust-project.json rust-analyzer support file'
@echo ' (requires kernel .config)'
@echo ''
@$(if $(dtstree), \
echo 'Devicetree:'; \
Expand Down Expand Up @@ -1830,6 +1832,10 @@ rustfmt:
rustfmtcheck:
find -name '*.rs' | xargs $(RUSTFMT) --check

# IDE support targets
PHONY += rust-analyzer
rust-analyzer: prepare0
$(Q)$(MAKE) $(build)=rust $@

# Misc
# ---------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions rust/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,6 @@ $(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
$(call if_changed_dep,rustc_library)

rust-analyzer:
$(Q)$(srctree)/scripts/generate_rust_analyzer.sh $(srctree) $(objtree) $(RUST_LIB_SRC) $(abspath $(objtree)/rust/bindings_generated.rs) > $(objtree)/rust-project.json
97 changes: 97 additions & 0 deletions scripts/generate_rust_analyzer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env bash

srctree=$1
objtree=$2
lib_src=$3
bindgen_file=$4


# TODO: create issue at RA to accept @arg file
function generate_cfgs() {
echo '['
cfgs=$(cat $objtree/include/generated/rustc_cfg | sed 's/--cfg=//' | sed 's/"/\\"/g' | sed 's/$/",/' | sed 's/^/"/')
echo ${cfgs::-1}
echo ']'
}

function generate_crate() {
name=$1
module=$2
member=${3:-"true"}
cfg=${4:-$(generate_cfgs)}
deps=${5:-'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"},{"crate":4,"name":"kernel"}]'}
extra=${CRATE_EXTRA:-""}

echo "{
\"display_name\":\"$name\",
\"root_module\":\"$module\",
\"edition\":\"2018\",
\"deps\":$deps,
\"is_workspace_member\": $member,
\"cfg\": $cfg,
\"env\": {
\"RUST_BINDINGS_FILE\": \"$bindgen_file\",
\"RUST_MODFILE\": \"This is only for rust-analyzer\"
}
$extra
}"
}

function generate_kernel() {
generate_crate "core" "${lib_src}/core/src/lib.rs" "false" "[]" "[]"
echo ","
generate_crate "compiler_builtins" "${srctree}/rust/compiler_builtins.rs" "true" "[]" "[]"
echo ","
generate_crate "alloc" "${lib_src}/alloc/src/lib.rs" "false" "[]" \
'[{"crate":0,"name":"core"},{"crate":1,"name":"compiler_builtins"}]'
echo ","
echo '{
"display_name":"module",
"root_module":"'${srctree}'/rust/module.rs",
"edition":"2018",
"is_workspace_member":true,
"deps": [],
"proc_macro_dylib_path": "rust/libmodule.so",
"cfg": []
},'
generate_crate "kernel" "${srctree}/rust/kernel/lib.rs" "true" "$(generate_cfgs)" \
'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"},{"crate":3,"name":"module"}]'
echo ","
}

function check_and_generate() {
filepath=$1
file=$(basename $filepath)
makefile=$(dirname $filepath)/Makefile
name=${file%.rs}
objname=${name}.o
echo "checking $filepath" >&2
if grep -q $objname $makefile; then
echo "building crate $name" >&2
echo $(generate_crate "$name" "$filepath")
echo ","
fi
}

function generate_drivers() {
drivers=$(find "$srctree/drivers" -name '*.rs')
for x in $drivers; do
check_and_generate $x
done
echo ""
}

function generate_samples() {
samples=$(find "$srctree/samples/rust" -name '*.rs')
for x in $samples; do
check_and_generate $x
done
}

echo '{"crates":['
generate_kernel
generate_drivers
samples=$(generate_samples)
echo ${samples::-1}
echo '],
"sysroot_src": "'${lib_src}'"}'

0 comments on commit eaa7bbe

Please sign in to comment.