Compare commits

...

2 Commits

Author SHA1 Message Date
portersky d5728334d6 feat: generate rust-project.json for LSP
Add a CMake module that writes rust-project.json on every configure so
rust-analyzer can resolve the no-Cargo crate layout, sysroot crates,
and proc-macro attributes without Cargo.

Co-Authored-By: qwen (lmstudio/qwen3.8-27b@q3_k_xl): LSP setup
2026-09-05 05:29:23 +02:00
portersky c3a7680e36 docs: note why native CMake Rust is skipped
CMake 4.4's experimental Rust support compiles each source as its own
crate, links libraries into executables as native .lib inputs instead
of --extern, and has no proc-macro crate type. Keep direct rustc.

Co-Authored-By: qwen (lmstudio/qwen3.8-27b@q3_k_xl): documented decision
2026-09-05 05:17:16 +02:00
5 changed files with 89 additions and 1 deletions
+1
View File
@@ -2,3 +2,4 @@
/target
.env
/build
/rust-project.json
+21 -1
View File
@@ -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
@@ -63,7 +64,13 @@ The project contains:
## Build System
CMake is configured with `LANGUAGES NONE` and invokes `rustc` through three
custom commands:
custom commands. CMake 4.4's experimental native Rust support
(`CMAKE_EXPERIMENTAL_RUST`) was evaluated and rejected: it compiles each
source file as its own crate, so multi-module crates break; it links Rust
libraries into executables as native `.lib` inputs instead of `--extern`;
and it has no `proc-macro` crate type. Keep the direct `rustc` commands.
The three custom commands are:
1. Compile `macros/src/lib.rs` as a host procedural macro.
2. Compile `src/lib.rs` and its modules to `librslibc.rlib`.
@@ -106,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
+3
View File
@@ -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")
+36
View File
@@ -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
)
+28
View File
@@ -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" }
]
}
]
}