-
Notifications
You must be signed in to change notification settings - Fork 98
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
List of #![no_std]
issues
#64
Comments
I'm pro-facade. With, that, the solution looks like having these libraries always be
Cargo's
There is a general problem in
Eventually I could see the portability lint discovering this and providing a hint, but first I think we should just focusing on making no-std libraries no harder to maintain so people when prodded switch. [If we could only get rid of
We should be able to query via dependencies.
That is definitely one of the hardest parts in the short term. Custom preludes or similar is the best I can think of. |
As a concrete example, I wanted a Duration type in my measurements crate
but it's in std, not core. I tried the time crate, but that depends on libc
which isn't no_std unless you give it a flag. It compiles and tests pass on
my PC, but it doesn't build for ARM with Xargo.
…On 15 Mar 2018 01:53, "John Ericson" ***@***.***> wrote:
I'm pro-facade. With, that, the solution looks like having these libraries
always be !#[no_std] and just optimally extern alloc or std. After that,
the main ergonomics problem is prelude management.
Adding #![no_std] to a crate doesn't mean it doesn't depend on std...
Cargo's [patch] should be able to remove a create, just as it can add
more or override ones. Then with stdlib-aware cargo we can ban std from a
workspace root.
They have to disable the std feature via default-features = false plus
re-enabling all the other default features.
There is a general problem in Cargo.toml of wanting do to "I'll depend on
this library only if something else needs it too". std should ideally not
be a special case with whatever is the best the solution.
A lot of crates on crates.io are not compatible with #![no_std] because
they depend on std
even though they don't necessarily need to.
*Eventually* I could see the portability lint discovering this and
providing a hint, but first I think we should just focusing on making
no-std libraries no harder to maintain so people when prodded switch. [If
we could only get rid of std and just have creates beneath it, that would
also help greatly, but alas we cannot. Good thing the
portability-lint-suggestion solution is equivalent though much more work to
implement.]
It's hard to find no_std crates on crates.io.
We should be able to query via dependencies. std should be just another
dependency.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#64 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA6lj0mQGAvtNj_jOrpa5Itg86NL2Yrwks5tecmigaJpZM4SrZjv>
.
|
|
@japaric Do the problems with compile time sized stack objects count? I hope (but am not sure) that const generics will be sufficient to address the problem that it is currently very unergonomic and cumbersome (via In my humble opinion this could eliminate a lot of |
Also there's this cargo limitation: rust-lang/cargo#2589 Cargo feature resolving for dependencies is done across both build-deps (native target) as well as code deps (embedded target) in a single pass. This means you basically can't use crates that are used by proc-macro or other compiler plugins (the case I hit was |
A few more sharp-edges / missing primitives i have run into (some of which are mentioned above):
|
This is a list issues related to
#![no_std]
that embedded developers tend to encounter inpractice. The main goal of this ticket is to make the portability WG aware of these issues.
#![no_std]
. Addressing ergonomics around Rust and embedded/no_std development #26 goesinto detail but to summarize the main problems:
Adding
#![no_std]
to a crate doesn't mean it doesn't depend onstd
. If a dependency depends onstd
(i.e. it's not#![no_std]
) then the top crates does as well. The only way to be reallysure is to compile the crate for a target that doesn't have
std
in its sysroot (e.g. usingXargo).
The current practice for providing features that depend on
std
in a crate is to provide thembehind an opt-out
std
Cargo feature. This means thatno_std
developers have to do extra workto depend on such crate: they have to disable the
std
feature viadefault-features = false
plus re-enabling all the other default features.
A lot of crates on crates.io are not compatible with
#![no_std]
because they depend onstd
even though they don't necessarily need to, e.g. the author just forgot to add
#![no_std]
to thecrate. This section of my embedded Rust in 2018 blog post goes into more detail
about the problem.
no_std
crates on crates.io. There's a no-std category on crates.io but not everyone uses it, or is aware of it (see previous bullet). It would be better if
no_std
-ness was checked and displayed on crates.io without human intervention.std
,no_std
andno_std
+alloc
is a tough job. Just having to deal with thedifferences in the core vs std prelude is a lot of work. For example, see the manually crafted
prelude that the serde project is using.
All these issues might disappear or be fixed with the elimination of the
std
facade and#![no_std]
, or they might not. I do not know.std
facade and#![no_std]
are gone it's pretty important that libraries support ano dynamic memory allocation mode. Microcontrollers are resource constrained devices and
sometimes a memory allocator is too heavyweight a dependency; also there application spaces (e.g.
safety critical) where dynamic memory allocation is downright banned (cf. MISRA standard).
It's already hard to figure out whether something allocates or not.
#![no_std]
and the lack ofextern crate alloc
is a good indicator that a crates doesn't allocate. Not compiling thealloc
crate as part of the Xargo sysroot is a sure way to exclude the memory allocator. I'm afraid it may
become impossible to tell whether a dependency allocates if
#![no_std]
and thestd
facade aregone.
I don't know if the portability lint could help with this (
#![deny(alloc)]
?) or if we should havea guideline about making a no dynamic memory allocation mode available via a Cargo feature then you
can simply look for the presence of such Cargo feature, but I guess it would be hard to make sure
everyone follows the guideline.
no_std
.sqrt
,sin
and friends are not available inno_std
programs. Instd
these functions comefrom the system
libm.a
, which is a C dependency. It's not convenient to use a C implementation inno_std
because it requires you to get a full C toolchain (whereas normally you only need a linker)that contains
libm.a
(assuming there's a pre-compiledlibm.a
available for your system) andyou'll likely will have to tweak the linker invocation to link the right
libm.a
to your program(e.g. the ARM Cortex-M toolchain ships with like 4 different
libm.a
binaries compiled usingdifferent profiles).
There are pure Rust implementations of
libm
like them
crate andmath-rs
which are moreconvenient to use as you don't need a full C toolchain or mess with the linking process. If the
std
facade is to be eliminated there should be some mechanism to be able to use such crate insteadof the C
libm.a
that thestd
crate pulls in.Another alternative would be to have a rust-lang's Rust implementation of
libm
but that's a lotof work. Though such implementation could be done incrementally by compiling the functions not yet
implemented in Rust from some C code base (e.g. Julia's openlibm) which is the approach we are using
for
compiler_builtins
.compiler_builtins
.In
no_std
programs you have to explicitly link to thecompiler_builtins
crate or at least one ofyour dependencies has to. The
std
crate depends oncompiler_builtins
so you don't need aexplicit
extern crate compiler_builtins
instd
programs.compiler_builtins
is an implementation detail of the LLVM backend and no Rust user should everneed to deal with it. Ideally if you link to
core
thencompiler_builtins
should also be linkedin but it's complicated.
The LLVM interface demands that the compiler intrinsics in
compiler_builtins
are linked in as aseparate object file and that such object file is passed as the last object file argument to the
linker. The
compiler_builtins
crate is marked with a special attribute (#![compiler_builtins]
,iirc) so that this holds true even in the presence of LTO (where you would expect a single object
file to be produced -- due to
compiler_builtins
you end with two object files).Furthermore
compiler_builtins
depends oncore
so you can't makecore
depend oncompiler_builtins
; also thecore
crate isn't suppose to have any dependency. The separate objectfile requirement also means that
compiler_builtins
can't be merged intocore
. This means thateven if you don't need anything other than
core
you still have to depend on the forever unstablecompiler_builtins
crate to build ano_std
binary.I don't know what are the plans of the portability WG wrt to the
compiler_builtins
crate (it can'tbe merged into
std
for the same reason it can't be merged intocore
) but from our point of viewit needs to disappear (*) (easier said than done) as it ties development of
no_std
binaries tothe nightly channel.
(*) iirc, @eddyb had some ideas to put the compiler intrinsics in
core
while preserving therequirement of a separate object file but I don't remember the details.
no_std
forks of stuff that's provided bystd
. For example,cty
,cstr_core
,hashmap_core
, etc. These should be provided by rust-lang to avoid codeduplication and bitrot (of the forks).
cc @jethrogb rust-lang-nursery/portability-wg#9
Community, if there's anything you think is missing from this list feel free to leave a comment
below and I'll add it to the list.
The text was updated successfully, but these errors were encountered: