Move some #[no_std] info to stable book.
This feature is partially stabilized, so describe each part in the appropriate place.
This commit is contained in:
parent
5b3a75fe56
commit
0394418752
3 changed files with 52 additions and 89 deletions
|
@ -51,6 +51,7 @@
|
||||||
* [FFI](ffi.md)
|
* [FFI](ffi.md)
|
||||||
* [Borrow and AsRef](borrow-and-asref.md)
|
* [Borrow and AsRef](borrow-and-asref.md)
|
||||||
* [Release Channels](release-channels.md)
|
* [Release Channels](release-channels.md)
|
||||||
|
* [Using Rust without the standard library](using-rust-without-the-standard-library.md)
|
||||||
* [Nightly Rust](nightly-rust.md)
|
* [Nightly Rust](nightly-rust.md)
|
||||||
* [Compiler Plugins](compiler-plugins.md)
|
* [Compiler Plugins](compiler-plugins.md)
|
||||||
* [Inline Assembly](inline-assembly.md)
|
* [Inline Assembly](inline-assembly.md)
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
% No stdlib
|
% No stdlib
|
||||||
|
|
||||||
By default, `std` is linked to every Rust crate. In some contexts,
|
Rust’s standard library provides a lot of useful functionality, but assumes
|
||||||
this is undesirable, and can be avoided with the `#![no_std]`
|
support for various features of its host system: threads, networking, heap
|
||||||
attribute attached to the crate.
|
allocation, and others. There are systems that do not have these features,
|
||||||
|
however, and Rust can work with those too! To do so, we tell Rust that we
|
||||||
|
don’t want to use the standard library via an attribute: `#![no_std]`.
|
||||||
|
|
||||||
|
> Note: This feature is technically stable, but there are some caveats. For
|
||||||
|
> one, you can build a `#![no_std]` _library_ on stable, but not a _binary_.
|
||||||
|
> For details on libraries without the standard library, see [the chapter on
|
||||||
|
> `#![no_std]`](using-rust-without-the-standard-library.html)
|
||||||
|
|
||||||
Obviously there's more to life than just libraries: one can use
|
Obviously there's more to life than just libraries: one can use
|
||||||
`#[no_std]` with an executable, controlling the entry point is
|
`#[no_std]` with an executable, controlling the entry point is
|
||||||
|
@ -77,89 +84,3 @@ personality function (see the
|
||||||
information), but crates which do not trigger a panic can be assured
|
information), but crates which do not trigger a panic can be assured
|
||||||
that this function is never called. The second function, `panic_fmt`, is
|
that this function is never called. The second function, `panic_fmt`, is
|
||||||
also used by the failure mechanisms of the compiler.
|
also used by the failure mechanisms of the compiler.
|
||||||
|
|
||||||
## Using libcore
|
|
||||||
|
|
||||||
> **Note**: the core library's structure is unstable, and it is recommended to
|
|
||||||
> use the standard library instead wherever possible.
|
|
||||||
|
|
||||||
With the above techniques, we've got a bare-metal executable running some Rust
|
|
||||||
code. There is a good deal of functionality provided by the standard library,
|
|
||||||
however, that is necessary to be productive in Rust. If the standard library is
|
|
||||||
not sufficient, then [libcore](../core/index.html) is designed to be used
|
|
||||||
instead.
|
|
||||||
|
|
||||||
The core library has very few dependencies and is much more portable than the
|
|
||||||
standard library itself. Additionally, the core library has most of the
|
|
||||||
necessary functionality for writing idiomatic and effective Rust code. When
|
|
||||||
using `#![no_std]`, Rust will automatically inject the `core` crate, like
|
|
||||||
we do for `std` when we’re using it.
|
|
||||||
|
|
||||||
As an example, here is a program that will calculate the dot product of two
|
|
||||||
vectors provided from C, using idiomatic Rust practices.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
# #![feature(libc)]
|
|
||||||
#![feature(lang_items)]
|
|
||||||
#![feature(start)]
|
|
||||||
#![feature(raw)]
|
|
||||||
#![no_std]
|
|
||||||
|
|
||||||
extern crate libc;
|
|
||||||
|
|
||||||
use core::mem;
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern fn dot_product(a: *const u32, a_len: u32,
|
|
||||||
b: *const u32, b_len: u32) -> u32 {
|
|
||||||
use core::raw::Slice;
|
|
||||||
|
|
||||||
// Convert the provided arrays into Rust slices.
|
|
||||||
// The core::raw module guarantees that the Slice
|
|
||||||
// structure has the same memory layout as a &[T]
|
|
||||||
// slice.
|
|
||||||
//
|
|
||||||
// This is an unsafe operation because the compiler
|
|
||||||
// cannot tell the pointers are valid.
|
|
||||||
let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
|
|
||||||
mem::transmute((
|
|
||||||
Slice { data: a, len: a_len as usize },
|
|
||||||
Slice { data: b, len: b_len as usize },
|
|
||||||
))
|
|
||||||
};
|
|
||||||
|
|
||||||
// Iterate over the slices, collecting the result
|
|
||||||
let mut ret = 0;
|
|
||||||
for (i, j) in a_slice.iter().zip(b_slice.iter()) {
|
|
||||||
ret += (*i) * (*j);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[lang = "panic_fmt"]
|
|
||||||
extern fn panic_fmt(args: &core::fmt::Arguments,
|
|
||||||
file: &str,
|
|
||||||
line: u32) -> ! {
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
|
||||||
# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
|
|
||||||
# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
|
|
||||||
# #[no_mangle] pub extern fn rust_eh_register_frames () {}
|
|
||||||
# #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
|
|
||||||
# fn main() {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that there is one lang item here whose signature differs from the examples
|
|
||||||
above, `panic_fmt`. This must be defined by consumers of libcore because the
|
|
||||||
core library declares panics, but it does not define it. The `panic_fmt`
|
|
||||||
lang item is this crate's definition of panic, and it must be guaranteed to
|
|
||||||
never return.
|
|
||||||
|
|
||||||
As can be seen in this example, the core library is intended to provide the
|
|
||||||
power of Rust in all circumstances, regardless of platform requirements. Further
|
|
||||||
libraries, such as liballoc, add functionality to libcore which make other
|
|
||||||
platform-specific assumptions, but continue to be more portable than the
|
|
||||||
standard library itself.
|
|
||||||
|
|
||||||
|
|
41
src/doc/book/using-rust-without-the-standard-library.md
Normal file
41
src/doc/book/using-rust-without-the-standard-library.md
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
% Using Rust Without the Standard Library
|
||||||
|
|
||||||
|
Rust’s standard library provides a lot of useful functionality, but assumes
|
||||||
|
support for various features of its host system: threads, networking, heap
|
||||||
|
allocation, and others. There are systems that do not have these features,
|
||||||
|
however, and Rust can work with those too! To do so, we tell Rust that we
|
||||||
|
don’t want to use the standard library via an attribute: `#![no_std]`.
|
||||||
|
|
||||||
|
> Note: This feature is technically stable, but there are some caveats. For
|
||||||
|
> one, you can build a `#![no_std]` _library_ on stable, but not a _binary_.
|
||||||
|
> For details on binaries without the standard library, see [the nightly
|
||||||
|
> chapter on `#![no_std]`](no-stdlib.html)
|
||||||
|
|
||||||
|
To use `#![no_std]`, add a it to your crate root:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
fn plus_one(x: i32) -> i32 {
|
||||||
|
x + 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Much of the functionality that’s exposed in the standard library is also
|
||||||
|
available via the [`core` crate](../core/). When we’re using the standard
|
||||||
|
library, Rust automatically brings `std` into scope, allowing you to use
|
||||||
|
its features without an explicit import. By the same token, when using
|
||||||
|
`!#[no_std]`, Rust will bring `core` into scope for you, as well as [its
|
||||||
|
prelude](../core/prelude/v1/). This means that a lot of code will Just Work:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
fn may_fail(failure: bool) -> Result<(), &'static str> {
|
||||||
|
if failure {
|
||||||
|
Err("this didn’t work!")
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
Loading…
Add table
Add a link
Reference in a new issue