diff --git a/.gitignore b/.gitignore index 2b8009b..9fd06f0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /target .env /build +/rust-project.json diff --git a/AGENTS.md b/AGENTS.md index 01fbd5e..5c8d35c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,6 +19,7 @@ The project contains: entry helpers - `macros/src/lib.rs`: host-side `#[rslibc_macros::main]` attribute macro - `runtime/main.rs`: minimal example entry point +- `cmake/RustLSP.cmake`: generates `rust-project.json` for rust-analyzer - `CMakeLists.txt`: direct `rustc` library, macro, and executable commands ## No-Std Design @@ -112,6 +113,19 @@ Run it on Windows: - `RelWithDebInfo`: `-C opt-level=3 -C debuginfo=2` - Other or unset configurations: `-C opt-level=0 -C debuginfo=2` +## LSP + +rust-analyzer works without Cargo through a generated manifest: + +- `cmake/RustLSP.cmake` runs on every configure and writes + `rust-project.json` (git-ignored) describing the three crates and the + toolchain sysroot, so `core`, `alloc`, and proc-macro attributes resolve. +- Requires the rustup components: + `rustup component add rust-analyzer rust-src`. +- Open the repository root in the editor so rust-analyzer picks up + `rust-project.json`. Re-run CMake configure after changing the crate + layout or switching toolchains. + ## Verification After changing the source or build configuration, run a clean release build diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d5e7f9..e269db0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,9 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) find_program(RUSTC rustc REQUIRED) +# Generate rust-project.json for rust-analyzer (LSP) support. +include(cmake/RustLSP.cmake) + set(RUST_MACRO_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/macros/src/lib.rs") set(RUST_MACRO "${CMAKE_CURRENT_BINARY_DIR}/rslibc_macros${CMAKE_SHARED_LIBRARY_SUFFIX}") set(RUST_LIBRARY_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/src/lib.rs") diff --git a/cmake/RustLSP.cmake b/cmake/RustLSP.cmake new file mode 100644 index 0000000..f625a44 --- /dev/null +++ b/cmake/RustLSP.cmake @@ -0,0 +1,36 @@ +# Generate rust-project.json for rust-analyzer (LSP) support. +# +# This project has no Cargo manifest, so rust-analyzer cannot discover the +# crate layout on its own. The generated file describes the three crates and +# points at the toolchain sysroot so core/alloc resolve. It is regenerated on +# every configure; the output is git-ignored. + +if(NOT RUSTC) + find_program(RUSTC rustc REQUIRED) +endif() + +execute_process( + COMMAND "${RUSTC}" --print sysroot + OUTPUT_VARIABLE RUST_SYSROOT_RAW + RESULT_VARIABLE RUST_SYSROOT_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(NOT RUST_SYSROOT_RESULT EQUAL 0 OR NOT RUST_SYSROOT_RAW) + message(FATAL_ERROR "Failed to query the rustc sysroot") +endif() + +# Use forward slashes so the JSON needs no backslash escaping. +string(REPLACE "\\" "/" RUST_SYSROOT "${RUST_SYSROOT_RAW}") +set(RUST_SYSROOT_SRC "${RUST_SYSROOT}/lib/rustlib/src/rust/library") + +if(NOT IS_DIRECTORY "${RUST_SYSROOT_SRC}") + message(WARNING "rust-src not found at ${RUST_SYSROOT_SRC}. " + "Run `rustup component add rust-src` for full LSP support.") +endif() + +configure_file( + "${CMAKE_CURRENT_LIST_DIR}/rust-project.json.in" + "${CMAKE_CURRENT_SOURCE_DIR}/rust-project.json" + @ONLY +) diff --git a/cmake/rust-project.json.in b/cmake/rust-project.json.in new file mode 100644 index 0000000..c5217fc --- /dev/null +++ b/cmake/rust-project.json.in @@ -0,0 +1,28 @@ +{ + "sysroot": "@RUST_SYSROOT@", + "sysroot_src": "@RUST_SYSROOT_SRC@", + "crates": [ + { + "display_name": "rslibc", + "root_module": "src/lib.rs", + "edition": "2021", + "deps": [] + }, + { + "display_name": "rslibc_macros", + "root_module": "macros/src/lib.rs", + "edition": "2021", + "is_proc_macro": true, + "deps": [] + }, + { + "display_name": "rslibc_example", + "root_module": "runtime/main.rs", + "edition": "2021", + "deps": [ + { "crate": 0, "name": "rslibc" }, + { "crate": 1, "name": "rslibc_macros" } + ] + } + ] +}