rls icon indicating copy to clipboard operation
rls copied to clipboard

RLS doesn't seem to understand no_std

Open polybuildr opened this issue 7 years ago • 18 comments

(Background: I installed RLS through VSCode and I'm using the nightly channel which I installed using rustup and then selected by putting "nightly" in a rust-toolchain file.)

#![feature(panic_implementation)]
#![no_std]
#![no_main]

use core::panic::PanicInfo;

#[panic_implementation]
#[no_mangle]
pub fn panic(_info: &PanicInfo) -> ! {
    loop {}
}

This gives me the error: duplicate lang item found: panic_impl. note: first defined in crate std.

I assumed that having the no_std attribute would mean that I wouldn't have this error and this seems to work fine when I build it with cargo. RLS, however, doesn't seem to like it.

polybuildr avatar Jun 10 '18 21:06 polybuildr

The same issue occurs with the oom lang item:

duplicate lang item found: `oom`.
note: first defined in crate `std`.

Like @polybuildr, I have #![no_std] in my main.rs.

cgm616 avatar Jul 25 '18 02:07 cgm616

FWIW, I was getting this error until I added rls.toml and set the target to the correct triple and sysroot to use the xbuild sysroot.

I still have one problem left where rls expects to find the test crate, but I don't have it because I'm building with no_std.

edit: A better workaround was posted by 0paIescent: https://github.com/rust-lang/rls/issues/904#issuecomment-432332991

parasyte avatar Jul 25 '18 04:07 parasyte

@parasyte I just set my target to the right target using the VSCode settings, but I can't find any documentation on rls.toml. I now have the test crate problem too.

cgm616 avatar Jul 27 '18 23:07 cgm616

@cgm616 Sorry, I neglected to mention that I'm using the atom-rust-ide package for Atom. That's why I used rls.toml. For VS Code, you're going to use settings.json.

parasyte avatar Jul 28 '18 20:07 parasyte

@parasyte What settings, specifically, are you setting? I'm having trouble finding the options available in rls.toml/settings.json (and I assume whatever atom uses).

edit: nvm. I'm using xargo, so it appears that settings contained in settings.json won't result in a successful rls build using cargo.

nebulaeonline avatar Jul 28 '18 21:07 nebulaeonline

@cgm616 the same will happen for any language item, there's no need to explicitly mention each one that fails.

mqudsi avatar Jul 29 '18 02:07 mqudsi

I'm also currently tripping over this. @parasyte's suggestions are helpful but it complains about the missing test crate for me too.

In case that helps anyone, my settings for VS Code are:

{
    "rust.sysroot": "target/sysroot",
    "rust.target": <the-target-name>
}

teskje avatar Oct 12 '18 20:10 teskje

I had the same issues, for me setting "rust.all_targets": false fixed it.

0paIescent avatar Oct 23 '18 17:10 0paIescent

The problem is #[!no_std] doesn't get along well with test target (which cargo check --all-targets brings in), like here

lijinpei avatar Feb 12 '19 18:02 lijinpei

Another possibility (probably only useful for unconditionally no_std lib crates as the additional cfgs will quickly get out of hand elsewhere) is #![cfg_attr(not(test), no_std)]. RLS still checks #[cfg(test)] code this way without erroring :)

jplatte avatar May 29 '19 18:05 jplatte

Just chiming in with another solution, in case it can help anyone. As per the instructions in this guide, I use cargo xbuild to build my #![no_std]/#![no_main] project, which is working fine. The RLS however was showing the panic_impl error. Using the solutions suggested above that problem went away, but now it started complaining about the core crate not being found and even crashing regularly. I managed to fix that by adding the following option to my .vscode/settings.json:

"rust.rustflags": "-L dependency=$project/target/sysroot/lib/rustlib/$target/lib"

Substitute $project for your project path (an absolute path seems to be necessary) and $target for the target triple. Run cargo xbuild once, which will build the necessary standard crates and put them in that path, where a normal cargo build can find them if you pass the above rustflag.

TuurDutoit avatar Jun 28 '19 07:06 TuurDutoit

Just to be clear, here are the files that make this workaround work. Don't forget to run cargo xbuild at least once, so the core crates are compiled for the custom target and can be found by the normal cargo build and RLS!

x86_64-unknown-none.json:

{
    "llvm-target": "x86_64-unknown-none",
    "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
    "arch": "x86_64",
    "target-endian": "little",
    "target-pointer-width": "64",
    "target-c-int-width": "32",
    "os": "none",
    "executables": true,
    "linker-flavor": "ld.lld",
    "linker": "rust-lld",
    "panic-strategy": "abort",
    "disable-redzone": true,
    "features": "-mmx,-sse,+soft-float"
}

rust-toolchain:

nightly

.cargo/config:

[build]
target = "x86_64-unknown-none.json"

.vscode/settings.json:

{
    "rust.all_targets": false,
    "rust.sysroot": "/Users/tuur/Documents/dev/os/rust-os/target/sysroot",
    "rust.rustflags": "-L dependency=/Users/tuur/Documents/dev/os/rust-os/target/sysroot/lib/rustlib/x86_64-unknown-none/lib"
}

TuurDutoit avatar Jun 28 '19 08:06 TuurDutoit

Until someone implements https://github.com/microsoft/vscode/issues/2809 then unfortunately we're stuck with absolute paths in VS Code settings.json. Being able to use ${workspaceFolder} instead of absolute paths would be much better for portability, teams, and multiple build machines.

For Windows users who don't like absolute paths:

This isn't working. See the edit at the bottom

If you don't want to hard code machine-specific absolute paths into your settings.json, then you can just include this .bat file in your project and use it to launch VS Code. This takes the place of the rust.sysroot and rust.rustflags properties in settings.json:

launch editor.bat

@echo off
echo Launching VS Code with RUSTFLAGS...
set RUSTFLAGS=--sysroot %~dp0target\sysroot
cmd /C code %~dp0

(Details on %~dp0 here... basically it gets the absolute path of the current directory)

The basic idea is to derive the sysroot directory from the current directory and set that using the RUSTFLAGS environment variable which then gets picked up by cargo build and RLS when they are run within the VS Code process.

You can adjust the set RUSTFLAGS=... line to include dynamic -L argument paths in a similar manner if you need.


Edit:

Well, even this doesn't seem to work. RLS was working but then I noticed that cargo xbuild no longer works. It fails with this error message (replaced sensitive stuff with <me> and <project root>):

Compiling ...
Compiling ...
Compiling alloc v0.0.0 (C:\Users\<me>\AppData\Local\Temp\xargo.omihKiksYCDK)
    Finished release [optimized] target(s) in 30.88s
error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `rustc - --crate-name ___ --print=file-names --sysroot <project root>\target\sysroot --sysroot <project root>\target/sysroot --target <project root>\x86_64-unknown-none.json --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro` (exit code: 1)
--- stderr
error: Option 'sysroot' given more than once

So it looks like these are the choices, unless anyone can figure out something that checks all the boxes?

RLS cargo build cargo xbuild Flexible paths
RUSTFLAGS environment variable ⬜️
.vscode/settings.json settings ⬜️ ⬜️

matthew-a-thomas avatar Jul 10 '19 20:07 matthew-a-thomas

cargo-xbuild 0.5.14 droppedcargo xbuild now works with the environment variable!

But it turns out RLS actually wasn't working with the environment variable. Something about sysroot being passed twice.

So here's an updated table. Pick your poison:

RLS cargo build cargo xbuild Flexible paths
RUSTFLAGS environment variable ⬜️
.vscode/settings.json settings ⬜️ ⬜️
RUSTFLAGS + settings.json ⬜️ ¯\_(ツ)_/¯

Here's my current setup (because RLS is more important to me than flexible paths):

Launch VS Code with RUSTFLAGS environment variable

launch editor.bat:

@echo off
echo Launching VS Code with RUSTFLAGS...
set RUSTFLAGS=--sysroot %~dp0target\sysroot
cmd /C code %~dp0

And also...

Do what @TuurDutoit does

https://github.com/rust-lang/rls/issues/904#issuecomment-506642400

Can we check all the boxes?

I see three paths forward. Any one of these ought to check all the boxes:

  1. Make RLS not pass a sysroot argument when it's already specified in RUSTFLAGS. Related?
  2. Implement https://github.com/microsoft/vscode/issues/2809 so we can use variables in .vscode/settings.json. Then we could use ${workspaceFolder} instead of absolute paths
  3. Make RLS interpret variables in its own settings. Then we could use a variable instead of absolute paths

matthew-a-thomas avatar Jul 11 '19 13:07 matthew-a-thomas

Has anybody gotten RLS to work on vim with no_std? I use coc.nvim with https://github.com/neoclide/coc-rls with the above settings and it still tells me that it can't build core.

YuhanLiin avatar Sep 14 '19 12:09 YuhanLiin

grafik same problem

deeprobin avatar Nov 14 '19 16:11 deeprobin

I'm not a super experienced Rust person, so I have no idea what any of these settings mean yet.

My questions is: what's up with this? 😄 It's been a while since the last activity on here so I thought it was fine to bump.

So... Bump?

RWOverdijk avatar Jul 30 '20 17:07 RWOverdijk

Any chance this could work with the unstable build-std? I get the can't find test crate error with both xbuild and build-std currently.

ajrpayne avatar Oct 27 '20 21:10 ajrpayne