-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add rust-analyzer-proc-macro-srv
binary, use it if found in sysroot
#12858
Conversation
Wouldn't a server binary accessible from |
Right! I edited the original message to read "makes this issue less pressing" instead of "closes this issue". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
proc-macro-srv-cli
seems fine to me, though I don't really have any hard feelings on the matter.
One hesitation I have is.. should we bring an args parsing library in there? I'm thinking of future-proofing it: if we add a different format, maybe we'll want it to support |
Hmm, I don't think there is a need for this now until we think a bit about versioning in general? Not sure tbh |
Yeah I suppose the versioning can happen in the protocol itself. I'm just slightly uncomfortable that the default behavior of the CLI is to sit there waiting for stdin, with zero output whatsoever and no argument handling at all. But I suppose we can get started without that. |
Not a rust-analyzer maintainers, but I have some ideas on this PR (feel free to ignore them):
|
@pietroalbini I agree on all these. I turned the PR back to draft because I want to address these + start implementing "look into sysroot" functionality — it probably doesn't need to be spread over multiple PRs / syncs |
@fasterthanlime it will be hard to test before we've landed the binary because it won't be in the sysroot yet. You can test everything else by adding some way to override the path of the macro client, though. |
@jyn514 I was thinking of using a specialized tool to test that locally ( |
eacccf7
to
4364531
Compare
…, start looking in there for a rust-analyzer-proc-macro-srv binary
This works for me locally:
After doing: cargo +nightly-2022-07-23 build --release -p proc-macro-srv-cli --features proc-macro-srv/sysroot-abi
cp ./target/release/rust-analyzer-proc-macro-srv ~/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/libexec/ This is good for review! |
rust-analyzer-proc-macro-srv
binary, use it if found in sysroot
crates/project-model/src/sysroot.rs
Outdated
/// Returns sysroot directory, where `bin/`, `etc/`, `lib/`, `libexec/` | ||
/// subfolder live, like: | ||
/// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library` | ||
pub fn src_root(&self) -> &AbsPath { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the names of this and root
should be swapped. Also it did be nice if path/to/sysroot/lib/rustlib/src/rust
could be derived from path/to/sysroot
if the former is not given.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I got my comments mixed up, hang on
(I already did the name swap - thankfully ProjectJson
already had the proper naming)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, comments fixed in 6967751
Also it did be nice if
path/to/sysroot/lib/rustlib/src/rust
could be derived frompath/to/sysroot
if the former is not given.
We never have a case where root
is given but src_root
is missing: previously, Sysroot
could only be built when passing src_root
. And simply joining lib/rustlib/src/rust
is not a great idea. We already have a method for that (discover_sysroot_src_dir
) and it respects RUST_SRC_PATH
.
I considered making it so that building a Sysroot
always takes root
and an optional src_root
(and if src_root
is missing, we use the "discover" method), but decided against it, since:
- There's a test case with a fake sysroot that only specifies
src_root
(it doesn't reproduce the directory structure of a real sysroot). We could fix that test case, no big deal, but... - We support
rust-project.json
, which up until now only allowed asysroot_src
field, not asysroot
field.
And going from sysroot_src
to sysroot
seems like a bad idea - it would involve checking that the last few path components are ["lib", "rustlib", "src", "rust]
, and removing them. I don't feel great about that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should allow only giving the sysroot
field and skipping sysroot_src
.
And simply joining lib/rustlib/src/rust is not a great idea.
Why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not?
Because non-cargo projects (ProjectWorkspace::Json
) might have "libstd sources" somewhere but not a "sysroot" like we expect for cargo projects, maybe? I'm not sure.
I think we should allow only giving the
sysroot
field and skippingsysroot_src
.
The question is where?
For cargo projects, we already call discover_*
functions for both root
and src_root
. Those respect RUST_SRC_PATH
for example.
For ProjectWorkspace::Json
projects, I'm not sure who sets the standard (maybe RA does?), but the rust-project.json
format currently only has a sysroot_src
field. Is that the case where you want to allow passing sysroot
and "guess" sysroot_src
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because non-cargo projects (ProjectWorkspace::Json) might have "libstd sources" somewhere but not a "sysroot" like we expect for cargo projects, maybe? I'm not sure.
Using sysroot + lib/rustlib/src/rust as fallback for sysroot_src would work fine in that case, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because non-cargo projects (ProjectWorkspace::Json) might have "libstd sources" somewhere but not a "sysroot" like we expect for cargo projects, maybe? I'm not sure.
Using sysroot + lib/rustlib/src/rust as fallback for sysroot_src would work fine in that case, right?
No, they specify the lib/rustlib/src/rust
- we can't get what we need by joining additional path segments, we need to strip some, and that feels really iffy (but we can do it if we want)
There's zero codepaths where we have sysroot
but not sysroot_src
.
sysroot
is a directory with src/
, lib/
, libexec/
, etc/
, etc. sysroot_src
is a deeper path with libstd sources (sorry about the initial confusion, my comments were swapped).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have sysroot_src if the user didn't specify one. I think the behavior should be:
if user specifies sysroot_src => use it, else use sysroot + lib/rustlib/src/rust
Or to put it another way:
sysroot_src is not specified by the user, set it to sysroot + lib/rustlib/src/rust
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have sysroot_src if the user didn't specify one.
Ah, right. But right now no one is specifying sysroot
either. That would require bazel (or other build systems that generate rust-project.json
files) to set that field.
We should really discuss the Cargo
/ Json
cases separately 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bjorn3 so, to summarize: For cargo projects, For
As a reminder, we need:
|
@bors r+ |
☀️ Test successful - checks-actions |
Find standalone proc-macro-srv on windows too I forgot that executables end with `.exe` on Windows in: * #12858
for historically, we've had the sysroot as the first crate (due to how we generate
and so we would just need to add:
and the appending of |
@woody77 that's an excellent point, I hadn't really thought about cross compilation when working on this. For sure, proc macros must compile and run on the host platform. However for regular (non-build and non-proc-macro) dependencies, RA should probably be looking at the target platform's sysroot. We probably need to introduce more fields to properly support cross compilation, unless I'm missing something. |
@fasterthanlime I don't understand how cross-compilation is related. RA is only looking for the |
@jyn514 that's the "sysroot use" I added, yes. But before that, RA was already detecting sysroot for cargo projects (and accepting a sysroot path for rust-project.json workspaces) so it could index libstd sources — those need to be for the target, not for the host (afaict). |
We have had to explicitly add the sysroot crates as I'm testing a change with GN right now that adds the |
The only time the host and target sysroot can be different is when you build a sysroot for the target yourself. Regular Edit: that was in reply to @fasterthanlime |
@woody77 I'm curious. What is GN short for? |
Generate Ninja - https://gn.googlesource.com/gn/ |
let mut args = args.clone(); | ||
let mut path = path.clone(); | ||
|
||
if let ProjectWorkspace::Cargo { sysroot, .. } = ws { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So at this point in time, we don't have any support for ProjectWorkspace::Json
, even if sysroot
is set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did proc-macros ever work for project.json workspaces actually? From the looks of it we never even build build scripts for them since we can't really do that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, proc macros should work with project.json workspaces. We have a field that allows specifying the path of the compiled proc macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you point me to where the proc-macro-srv is spawned for ProjectWorkspace::Json workspaces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some(it) => load_proc_macro( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@woody77 that match is definitely missing an arm I forgot to add when I added the additional field to rust-project.json's schema. I also didn't have any projects to test it with. I encourage you to open the small PR to fix it!
This adds a
bin
crate which simply runsproc_macro_srv::cli::run()
(it does no CLI argument parsing, nothing).The intent is to build that crate in Rust CI as part of the
dist::Rustc
component, then ship it in the sysroot: it would probably land in something like~/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/libexec/proc-macro-srv-cli
.This makes rust-lang/rustup#3022 less pressing. (Instead of teaching RA about rustup components, we simply teach it to look in the sysroot via
rustc --print sysroot
. If it can't findproc-macro-srv-cli
, it falls back to its ownproc-macro
subcommand).This is closely related to #12803 (but doesn't close it yet).
Things to address now:
[bin]
in theCargo.toml
Things to address later:
rust-lang/rust
)Things to address much, much later:
When built with
--features sysroot
onnightly-2022-07-23-x86_64-unknown-linux-gnu
, the binary is 7.4MB. After stripping debuginfo, it's 2.6MB. When compressed to.tar.xz
, it's 619KB.In a Zulip discussion, @jyn514 and @Mark-Simulacrum seemed to think that those sizes weren't a stopper for including the binary in the rustc component, even before we shrink it down further.