Open emberian opened 8 years ago
What needs to be done to get this to work?
I'll do the work, but I'll need some pointers where to start
So, I must admit I am not really sure how Xargo works, so this might all be pretty wrong, but afaik...
AIUI, Xargo manages the build via Cargo and the sysroot. We currently find the sysroot using rustc --print sysroot
. However, beyond that I have no idea what would need to change in the RLS. Perhaps @japaric might know?
We are pretty deeply integrated with Cargo - we call its API rather than shelling out to it, so we cannot use Xargo as a drop-in replacement. I'm not sure even what the UI would look like here. I assume we would need a way to specify cross-compilation (in rls.toml to start with, I guess). We would then shell out to Xargo to setup the sysroot and pass some extra parameters to Cargo? I don't know what those extra-parameters might be.
Supporting --target
would be much easier! (And probably a good first step to support here). We would just need to add a target
option to the config (see config.rs) and then when we call cargo (in build.rs), set the target on our CompileOptions
object (if you grep for build_lib
you should see all the places we touch that option, I think target
would follow that quite closely).
I haven't used the RLS yet so I can't give any pointers about how to integrate it with Xargo. But, I can provide more details about how Xargo works.
xargo build --target $T
does two things: It builds a sysroot (using Cargo) for the target $T
and then invokes cargo build --target $T
with RUSTFLAGS='--sysroot ~/.xargo'
(note that the sysroot path doesn't include the target $T
in it) to make it use the Xargo sysroot.
Now, sysroots are cached so when you are working on the same project the sysroot will most likely be built once and then be reused for every subsequent Xargo command. The only cases where the sysroot gets rebuilt is when Xargo.toml changes or when you change [profile.release.*] options in Cargo.toml. The Xargo.toml indicates Xargo which crates it should build and put in the custom sysroot. By default, Xargo just builds the core crate.
Thanks @japaric!
So, it sounds like the RLS will have to shell out to Xargo before using Cargo if we are in 'xargo-mode', get the RUSTFLAGS from xargo (this might mean modifying Xargo to not call Cargo if it is not possible to use Xargo in a dry-run mode), then pass these RUSTFLAGS to Cargo. Alternatively, we could link Xargo into the RLS and use it as a library to find the flags (not sure which is easier without knowing the code better). Both approaches feel very doable, although making this a good user experience might be a bit harder.
cargo automatically reads the target from ".cargo/config". I think it would be a good first step to support .cargo/config in general.
I'll work on that now
Ok. I got it working without modifying rls:
I executed RLS from the rust vscode extension with the following settings
"rust.rls": {
"executable": "path/to/rls/target/debug/rls.exe",
"env": {
"RUSTFLAGS": "--sysroot your/home/dir/.xargo",
"PATH": "your/home/dir/.rustup/toolchains/nightly-x86_64-pc-windows-msvc/bin"
}
}
but this method only works on windows so far, due to the cargo calls not being able to run rustc:
thread '<unnamed>' panicked at 'could not run cargo: ChainedError { error: failed to run `rustc` to learn about target-specific information, cause: process didn't exit successfully: `rustc - --crate-name ___ --print=file-names -Zunstable-options -Zsave-analysis --error-format=json -Zcontinue-parse-after-error --crate-type bin --crate-type rlib --target stm32f7` (exit code: 101)
--- stderr
{"message":"Error loading target specification: Could not find specification for target \"stm32f7\"","code":null,"level":"error","spans":[],"children":[{"message":"Use `--print target-list` for a list of built-in targets","code":null,"level":"help","spans":[],"children":[],"rendered":null}],"rendered":null}
}', /checkout/src/libcore/result.rs:859
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
0: <core::result::Result<T, E>>::expect
at /checkout/src/libcore/result.rs:761
1: rls::build::BuildQueue::cargo::{{closure}}
at ./coding/rls/src/build.rs:433
2: <std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once
at /checkout/src/libstd/panic.rs:296
3: std::panicking::try::do_call
at /checkout/src/libstd/panicking.rs:454
4: __rust_maybe_catch_panic
at /checkout/src/libpanic_unwind/lib.rs:98
5: std::panicking::try
at /checkout/src/libstd/panicking.rs:433
6: std::panic::catch_unwind
at /checkout/src/libstd/panic.rs:361
7: std::thread::Builder::spawn::{{closure}}
at /checkout/src/libstd/thread/mod.rs:360
8: <F as alloc::boxed::FnBox<A>>::call_box
at /checkout/src/liballoc/boxed.rs:640
9: std::sys::imp::thread::Thread::new::thread_start
at /checkout/src/liballoc/boxed.rs:650
at /checkout/src/libstd/sys_common/thread.rs:21
at /checkout/src/libstd/sys/unix/thread.rs:84
10: start_thread
11: clone
I'll investigate what causes the failure to run rustc on linux
I think the relevant parts are
Error loading target specification: Could not find specification for target \"stm32f7\"
Which I can reproduce by running
RUSTFLAGS="--sysroot path/to/home/.xargo" cargo build
Ah no, just a typo... it works fine when running cargo directly with RUSTFLAGS set to "--sysroot some/path"
So the RUSTFLAGS env var is not used:
rustc - --crate-name ___ --print=file-names -Zunstable-options -Zsave-analysis --error-format=json -Zcontinue-parse-after-error --crate-type bin --crate-type rlib --target stm32f
related to https://github.com/rust-lang-nursery/rls/issues/238 ?
Unrelated to #238, I think. But things are kind of complex here.
In the last comment I'm not sure what you're quoting. I suspect the calls from Cargo to rustc for dependent crates? We set RUSTFLAGS ourself before calling Cargo (search build.rs for RUSTFLAGS). The easy solution is to combine our flags with anything the user has set already. However, note that we also set the sysroot explicitly when calling rustc, so I think you'll have to do something there too.
Indeed these were the relevant locations! Thanks
It works mostly now. The only issue left is that sometimes we pass --sysroot
twice
DEBUG:rls::server: Language Server Starting up
TRACE:rls::server: reading: 154 bytes
TRACE:rls::server: command(init): InitializeParams { process_id: Some(25020), root_path: Some("/home/oliver/Projects/rust/blinky"), initialization_options: None, capabilities: Object({}) }
DEBUG:rls::server: response: "Content-Length: 487\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":0,\"result\":{\"capabilities\":{\"textDocumentSync\":2,\"hoverProvider\":true,\"completionProvider\":{\"resolveProvider\":true,\"triggerCharacters\":[\".\",\":\"]},\"signatureHelpProvider\":{\"triggerCharacters\":[]},\"definitionProvider\":true,\"referencesProvider\":true,\"documentHighlightProvider\":true,\"documentSymbolProvider\":true,\"workspaceSymbolProvider\":true,\"codeActionProvider\":false,\"documentFormattingProvider\":true,\"documentRangeFormattingProvider\":true,\"renameProvider\":true}}}"
DEBUG:rls::server: response: "Content-Length: 72\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"rustDocument/diagnosticsBegin\",\"params\":null}"
DEBUG:rls::actions: build "/home/oliver/Projects/rust/blinky"
TRACE:rls::build: cargo - `"/home/oliver/Projects/rust/blinky"`
TRACE:rls::build: manifest_path: "/home/oliver/Projects/rust/blinky/Cargo.toml"
TRACE:rls::server: reading: 76 bytes
TRACE:rls::server: parsing invalid message: ParseError { kind: InvalidData, message: "setTraceNotification", id: None }
TRACE:rls::server: reading: 112 bytes
TRACE:rls::server: parsing invalid message: ParseError { kind: InvalidData, message: "didChangeConfiguration", id: None }
TRACE:rls::server: reading: 281 bytes
TRACE:rls::server: notification(open): DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: "file:///home/oliver/Projects/rust/blinky/src/main.rs", language_id: Some("rust"), version: Some(1), text: "#![no_std]\nextern crate stm32f7_discovery as stm32f7;\n\nfn main() {\n let x = 5;\n x = 6\n}\n" } }
TRACE:rls::actions: on_open: "/home/oliver/Projects/rust/blinky/src/main.rs"
DEBUG:rls::server: response: "Content-Length: 72\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"rustDocument/diagnosticsBegin\",\"params\":null}"
DEBUG:rls::actions: build "/home/oliver/Projects/rust/blinky"
TRACE:rls::build: intercepted rustc, args: ["--crate-name", "blinky", "src/main.rs", "--color", "never", "--crate-type", "bin", "--emit=dep-info,metadata", "-C", "debuginfo=2", "-C", "metadata=699e03a8048af6a0", "-C", "extra-filename=-699e03a8048af6a0", "--out-dir", "/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps", "--target", "stm32f7", "-L", "dependency=/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps", "-L", "dependency=/home/oliver/Projects/rust/blinky/target/rls/debug/deps", "--extern", "stm32f7_discovery=/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps/libstm32f7_discovery-bee06a8a5940ae81.rmeta", "--sysroot", "/home/oliver/.xargo", "-Zunstable-options", "-Zsave-analysis", "--error-format=json", "-Zcontinue-parse-after-error"]
TRACE:rls::build: envs: {"CARGO_PKG_DESCRIPTION": Some(""), "CARGO_MANIFEST_DIR": Some("/home/oliver/Projects/rust/blinky"), "CARGO_PKG_VERSION_PATCH": Some("0"), "LD_LIBRARY_PATH": Some("/home/oliver/Projects/rust/blinky/target/rls/debug/deps:/home/oliver/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib"), "CARGO_PKG_VERSION_MINOR": Some("1"), "CARGO": Some("/home/oliver/Projects/rust/rls/target/debug/rls"), "CARGO_PKG_VERSION_PRE": Some(""), "CARGO_PKG_VERSION_MAJOR": Some("0"), "CARGO_PKG_HOMEPAGE": Some(""), "CARGO_PKG_NAME": Some("blinky"), "CARGO_PKG_VERSION": Some("0.1.0"), "CARGO_PKG_AUTHORS": Some("Oliver Schneider <git-no-reply-9879165716479413131@oli-obk.de>")}
TRACE:rls::build: rustc - args: `["rustc", "--crate-name", "blinky", "src/main.rs", "--color", "never", "--crate-type", "bin", "--emit=dep-info,metadata", "-C", "debuginfo=2", "-C", "metadata=699e03a8048af6a0", "-C", "extra-filename=-699e03a8048af6a0", "--out-dir", "/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps", "--target", "stm32f7", "-L", "dependency=/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps", "-L", "dependency=/home/oliver/Projects/rust/blinky/target/rls/debug/deps", "--extern", "stm32f7_discovery=/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps/libstm32f7_discovery-bee06a8a5940ae81.rmeta", "--sysroot", "/home/oliver/.xargo", "-Zunstable-options", "-Zsave-analysis", "--error-format=json", "-Zcontinue-parse-after-error", "--test", "--sysroot", "/home/oliver/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu"]`, envs: {"CARGO_PKG_DESCRIPTION": Some(""), "CARGO_MANIFEST_DIR": Some("/home/oliver/Projects/rust/blinky"), "CARGO_PKG_VERSION_PATCH": Some("0"), "LD_LIBRARY_PATH": Some("/home/oliver/Projects/rust/blinky/target/rls/debug/deps:/home/oliver/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib"), "CARGO_PKG_VERSION_MINOR": Some("1"), "CARGO": Some("/home/oliver/Projects/rust/rls/target/debug/rls"), "CARGO_PKG_VERSION_PRE": Some(""), "CARGO_PKG_VERSION_MAJOR": Some("0"), "CARGO_PKG_HOMEPAGE": Some(""), "CARGO_PKG_NAME": Some("blinky"), "CARGO_PKG_VERSION": Some("0.1.0"), "CARGO_PKG_AUTHORS": Some("Oliver Schneider <git-no-reply-9879165716479413131@oli-obk.de>")}, build dir: "/home/oliver/Projects/rust/blinky"
error: Option 'sysroot' given more than once.
DEBUG:rls::actions: build - Success
TRACE:rls::actions: reload analysis: "/home/oliver/Projects/rust/blinky"
INFO:rls_analysis: reload "/home/oliver/Projects/rust/blinky" "/home/oliver/Projects/rust/blinky"
INFO:rls_analysis::lowering: Total lowering time: 0.00s
INFO:rls_analysis::lowering: Diff in rss: 0.00KB
DEBUG:rls::server: response: "Content-Length: 70\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"rustDocument/diagnosticsEnd\",\"params\":null}"
TRACE:rls::build: rustc - args: `["rustc", "--crate-name", "blinky", "src/main.rs", "--color", "never", "--crate-type", "bin", "--emit=dep-info,metadata", "-C", "debuginfo=2", "-C", "metadata=699e03a8048af6a0", "-C", "extra-filename=-699e03a8048af6a0", "--out-dir", "/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps", "--target", "stm32f7", "-L", "dependency=/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps", "-L", "dependency=/home/oliver/Projects/rust/blinky/target/rls/debug/deps", "--extern", "stm32f7_discovery=/home/oliver/Projects/rust/blinky/target/rls/stm32f7/debug/deps/libstm32f7_discovery-bee06a8a5940ae81.rmeta", "--sysroot", "/home/oliver/.xargo", "-Zunstable-options", "-Zsave-analysis", "--error-format=json", "-Zcontinue-parse-after-error", "--test", "--sysroot", "/home/oliver/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu"]`, envs: {"CARGO_PKG_DESCRIPTION": Some(""), "CARGO_MANIFEST_DIR": Some("/home/oliver/Projects/rust/blinky"), "CARGO_PKG_VERSION_PATCH": Some("0"), "LD_LIBRARY_PATH": Some("/home/oliver/Projects/rust/blinky/target/rls/debug/deps:/home/oliver/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib"), "CARGO_PKG_VERSION_MINOR": Some("1"), "CARGO": Some("/home/oliver/Projects/rust/rls/target/debug/rls"), "CARGO_PKG_VERSION_PRE": Some(""), "CARGO_PKG_VERSION_MAJOR": Some("0"), "CARGO_PKG_HOMEPAGE": Some(""), "CARGO_PKG_NAME": Some("blinky"), "CARGO_PKG_VERSION": Some("0.1.0"), "CARGO_PKG_AUTHORS": Some("Oliver Schneider <git-no-reply-9879165716479413131@oli-obk.de>")}, build dir: "/home/oliver/Projects/rust/blinky"
error: Option 'sysroot' given more than once.
It works mostly now. The only issue left is that sometimes we pass --sysroot twice
Is this even the case with your PR? (It looks like that should fix the double systroot issue).
Nope, the PR fixes this
To summarise: setting the sysroot and RUSTFLAGS now work. We can't yet set --target
. I'm not sure about .cargo/config
- I assume that works though?
Yes, it's possible to add sysroot = "/home/user/.xargo"
so rls can use a sysroot built by xargo. There's no way currently to run xargo automatically, but once it has been run, rls can use the artifacts built by it.
--target
works now as an rls.toml option
double sysroot is back :(
double sysroot is back :(
I'm curious what the status of this is? I'm also running into a double sysroot issue in the context of https://github.com/rust-lang/rls/issues/904
Apart from #1578, I got it working now. There are two important points:
SYSROOT
rls
via rustup
If you run rustup run nightly rls
it will set RUSTUP_HOME
and other environment variables, so that rls
does not consider SYSROOT
.
Therefore, the command line I'm using is:
LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH SYSROOT=<mysysroot> RUST_TARGET_PATH=<target-json-dir> $(rustc --print sysroot)/bin/rls
When working on Robigalia, I need to build with
xargo build --target i686-sel4-unknown
(as an example), to getcore
etc built for my custom target. This prevents me from using RLS.