Skip to content

Commit 8d39b0b

Browse files
authored
Support stable Rust, and reduce dependence on internal Rust features. (#132)
Put all code that depends on nightly-only features behind a new "nightly" feature, and add support for stable Rust. And, add implementations of `memcpy` and other functions that LLVM calls so that origin and its users no longer need to depend on the compiler_internals crate. And, introduce new "panic-handler", "panic-handler-abort", "eh-personality", and "eh-personality-continue" features, so that users no longer need to use `#[panic_handler]` or `#[lang = "eh_personality"]` in common cases. And, add `origin::program::abort`, eliminating the need for users to use `core::intrinsics::abort()`. Together, these changes mean that origin and most of the example crates no longer need `#![allow(internal_features)]`, `#![feature(lang_items)]`, or `#![feature(core_intrinsics)]`, or the associated boilerplate code with `#[panic_handler]` or `#[lang = "eh_personality"]`, or the explicit dependency on `compiler_builtins` or the `extern crate compiler_builtins;`.
1 parent 05f7269 commit 8d39b0b

56 files changed

Lines changed: 1771 additions & 438 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# install-rust
2+
3+
A small github action to install `rustup` and a Rust toolchain. This is
4+
generally expressed inline, but it was repeated enough in this repository it
5+
seemed worthwhile to extract.
6+
7+
Some gotchas:
8+
9+
* Can't `--self-update` on Windows due to permission errors (a bug in Github
10+
Actions)
11+
* `rustup` isn't installed on macOS (a bug in Github Actions)
12+
13+
When the above are fixed we should delete this action and just use this inline:
14+
15+
```yml
16+
- run: rustup update $toolchain && rustup default $toolchain
17+
shell: bash
18+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: 'Install Rust toolchain'
2+
description: 'Install both `rustup` and a Rust toolchain'
3+
4+
inputs:
5+
toolchain:
6+
description: 'Default toolchan to install'
7+
required: false
8+
default: 'stable'
9+
10+
runs:
11+
using: node20
12+
main: 'main.js'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const child_process = require('child_process');
2+
const toolchain = process.env.INPUT_TOOLCHAIN;
3+
const fs = require('fs');
4+
5+
function set_env(name, val) {
6+
fs.appendFileSync(process.env['GITHUB_ENV'], `${name}=${val}\n`)
7+
}
8+
9+
// Needed for now to get 1.24.2 which fixes a bug in 1.24.1 that causes issues
10+
// on Windows.
11+
if (process.platform === 'win32') {
12+
child_process.execFileSync('rustup', ['self', 'update']);
13+
}
14+
15+
child_process.execFileSync('rustup', ['set', 'profile', 'minimal']);
16+
child_process.execFileSync('rustup', ['update', toolchain, '--no-self-update']);
17+
child_process.execFileSync('rustup', ['default', toolchain]);
18+
19+
// Deny warnings on CI to keep our code warning-free as it lands in-tree. Don't
20+
// do this on nightly though since there's a fair amount of warning churn there.
21+
// RUSTIX: Disable this so that it doesn't overwrite RUSTFLAGS for setting
22+
// "--cfg rustix_use_libc". We re-add it manually in the workflow.
23+
//if (!toolchain.startsWith('nightly')) {
24+
// set_env("RUSTFLAGS", "-D warnings");
25+
//}
26+
27+
// Save disk space by avoiding incremental compilation, and also we don't use
28+
// any caching so incremental wouldn't help anyway.
29+
set_env("CARGO_INCREMENTAL", "0");
30+
31+
// Turn down debuginfo from 2 to 1 to help save disk space
32+
set_env("CARGO_PROFILE_DEV_DEBUG", "1");
33+
set_env("CARGO_PROFILE_TEST_DEBUG", "1");
34+
35+
if (process.platform === 'darwin') {
36+
set_env("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO", "unpacked");
37+
set_env("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO", "unpacked");
38+
}

.github/workflows/main.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
strategy:
2424
matrix:
2525
build: [ubuntu, i686-linux, aarch64-linux, riscv64-linux]
26+
rust: [1.78, nightly-2024-10-06]
2627
include:
2728
- build: ubuntu
2829
os: ubuntu-latest
@@ -50,8 +51,14 @@ jobs:
5051
qemu: qemu-riscv64 -L /usr/riscv64-linux-gnu
5152
qemu_target: riscv64-linux-user
5253
host_target: riscv64gc-unknown-linux-gnu
54+
- rust: nightly-2024-10-06
55+
features: nightly
5356
steps:
5457
- uses: actions/checkout@v4
58+
- uses: ./.github/actions/install-rust
59+
with:
60+
toolchain: ${{ matrix.rust }}
61+
5562
- name: Configure Cargo target
5663
run: |
5764
echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV
@@ -113,6 +120,6 @@ jobs:
113120

114121
- name: cargo test
115122
run: |
116-
cargo test
123+
cargo test --features=${{ matrix.features }}
117124
env:
118125
RUST_BACKTRACE: 1

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
# origin 0.21
2+
3+
## Changes
4+
5+
Origin now supports stable Rust as well as nightly Rust, and nightly-only
6+
features such as unwinding are now behind a "nightly" feature.
7+
8+
In "take-charge" mode, origin now defines `memcpy`, `memset` and other
9+
functions needed by rustc and internal Rust libraries, so it's no longer
10+
necessary to use `compiler_builtins` to provide these.
11+
112
# origin 0.20
213

314
## Changes

Cargo.toml

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ edition = "2021"
1212
keywords = ["linux"]
1313
categories = ["no-std"]
1414
include = ["src", "Cargo.toml", "COPYRIGHT", "LICENSE*", "/*.md"]
15+
rust-version = "1.78"
1516

1617
[dependencies]
1718
linux-raw-sys = { version = "0.4.9", default-features = false, features = ["general", "no_std", "elf"] }
@@ -39,13 +40,19 @@ errno = { version = "0.3.3", default-features = false, optional = true }
3940
# Special dependencies used in rustc-dep-of-std mode.
4041
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
4142
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
42-
# Enable "no-f16-f128" for now, to work around lack of support on some targets.
43-
compiler_builtins = { version = "0.1.112", features = ["no-f16-f128"], optional = true }
4443

4544
[target.'cfg(not(target_arch = "arm"))'.dependencies.unwinding]
4645
version = "0.2.0"
4746
default-features = false
4847
features = ["unwinder"]
48+
optional = true
49+
50+
# On aarch64, compiler_builtins depends on `getauxval`, so we need rustix with
51+
# the "param" feature.
52+
[target.'cfg(target_arch = "aarch64")'.dependencies.rustix]
53+
version = "0.38.35"
54+
default-features = false
55+
features = ["param"]
4956

5057
[dev-dependencies]
5158
assert_cmd = "2.0.12"
@@ -59,10 +66,9 @@ rustc-dep-of-std = [
5966
"linux-raw-sys/rustc-dep-of-std",
6067
"bitflags/rustc-dep-of-std",
6168
"rustix/rustc-dep-of-std",
62-
"unwinding/rustc-dep-of-std",
69+
"unwinding?/rustc-dep-of-std",
6370
"libc?/rustc-dep-of-std",
6471
"rustix-futex-sync/rustc-dep-of-std",
65-
"dep:compiler_builtins",
6672
]
6773

6874
# Use origin's implementation of program and thread startup and shutdown as
@@ -121,5 +127,48 @@ experimental-relocate = ["rustix/mm", "rustix/runtime"]
121127
# until a dynamic linker is written in Rust.
122128
unstable-errno = ["thread"]
123129

130+
# If you're using nightly Rust, enable this feature to let origin use
131+
# nightly-only features, which include proper support for unwinding, better
132+
# safety checks, and better optimizations.
133+
nightly = ["unwinding"]
134+
135+
# Enable optimizations that reduce code size (at the cost of performance).
136+
optimize_for_size = []
137+
138+
# Provide a `#[lang = eh_personality]` function suitable for unwinding (for
139+
# no-std).
140+
#
141+
# If you know your program never unwinds and want smaller code size, use
142+
# "eh-personality-continue" instead.
143+
#
144+
# This is only needed in no-std builds, as std provides a personality. See
145+
# [the "personality" feature of the unwinding crate] for more details.
146+
#
147+
# [the "personality" feature of the unwinding crate]: https://crates.io/crates/unwinding#personality-and-other-utilities
148+
eh-personality = ["unwinding?/personality"]
149+
150+
# Provide a `#[lang = eh_personality]` function that just returns
151+
# `CONTINUE_UNWIND` (for no-std). Use this if you know your program will never
152+
# unwind and don't want any extra code.
153+
eh-personality-continue = ["unwinding?/personality-dummy"]
154+
155+
# Provide a `#[panic_handler]` function suitable for unwinding (for no-std).
156+
#
157+
# If you know your program never panics and want smaller code size, use
158+
# "panic-handler-abort" instead.
159+
#
160+
# This is only needed in no-std builds, as std provides a panic handler. See
161+
# [the "panic-handler" feature of the unwinding crate] for more details.
162+
#
163+
# [the "panic-handler" feature of the unwinding crate]: https://crates.io/crates/unwinding#personality-and-other-utilities
164+
panic-handler = ["unwinding?/panic-handler"]
165+
166+
# Provide a `#[panic_handler]` function that just aborts (for no-std). Use this
167+
# if you know your program will never panic and don't want any extra code.
168+
panic-handler-abort = ["unwinding?/panic-handler-dummy"]
169+
170+
# Enable this to define the `getauxval` function.
171+
getauxval = ["rustix/param"]
172+
124173
[package.metadata.docs.rs]
125-
features = ["take-charge", "origin-start", "thread", "signal"]
174+
features = ["take-charge", "origin-start", "thread", "signal", "nightly"]

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ This is used by [Mustang] and [Eyra] in their libc implementations, and in the
2828
[Origin Studio] project in its std implementation, which are three different
2929
ways to support building Rust programs written entirely in Rust.
3030

31+
It works with both stable (currently Rust >= 1.78) and nightly Rust. If you're
32+
using nightly Rust, enable the feature "nightly" to let origin use nightly-only
33+
features, which include proper support for unwinding, better safety checks, and
34+
better optimizations.
35+
3136
## Example crates
3237

3338
Origin can also be used on its own, in several different configurations:

example-crates/external-start/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ publish = false
77
[dependencies]
88
# Origin can be depended on just like any other crate. For no_std, disable
99
# the default features, and the desired features.
10-
origin = { path = "../..", default-features = false, features = ["take-charge", "external-start", "thread", "alloc"] }
10+
origin = { path = "../..", default-features = false, features = ["take-charge", "external-start", "thread", "alloc", "eh-personality-continue", "panic-handler-abort", "nightly"] }
1111

1212
# Ensure that libc gets linked.
1313
libc = { version = "0.2", default-features = false }
1414

1515
# Crates to help writing no_std code.
1616
atomic-dbg = { version = "0.1.8", default-features = false }
1717
rustix-dlmalloc = { version = "0.1.0", features = ["global"] }
18-
compiler_builtins = { version = "0.1.112", features = ["mem", "no-f16-f128"] }
1918

2019
# This is just an example crate, and not part of the origin workspace.
2120
[workspace]

example-crates/external-start/src/main.rs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,15 @@
22
33
#![no_std]
44
#![no_main]
5-
#![allow(internal_features)]
6-
#![feature(lang_items)]
7-
#![feature(core_intrinsics)]
85

96
extern crate alloc;
10-
extern crate compiler_builtins;
117
extern crate libc;
128

139
use alloc::boxed::Box;
14-
use atomic_dbg::{dbg, eprintln};
10+
use atomic_dbg::eprintln;
1511
use core::sync::atomic::{AtomicBool, Ordering};
1612
use origin::{program, thread};
1713

18-
#[panic_handler]
19-
fn panic(panic: &core::panic::PanicInfo<'_>) -> ! {
20-
dbg!(panic);
21-
core::intrinsics::abort();
22-
}
23-
24-
#[lang = "eh_personality"]
25-
extern "C" fn eh_personality() {}
26-
2714
#[global_allocator]
2815
static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc;
2916

@@ -90,5 +77,5 @@ unsafe fn origin_main(_argc: usize, _argv: *mut *mut u8, _envp: *mut *mut u8) ->
9077
#[no_mangle]
9178
unsafe fn main(_argc: i32, _argv: *mut *mut u8, _envp: *mut *mut u8) -> i32 {
9279
eprintln!("Main was not supposed to be called!");
93-
core::intrinsics::abort();
80+
program::abort();
9481
}

example-crates/no-std/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ publish = false
77
[dependencies]
88
# Origin can be depended on just like any other crate. For no_std, disable
99
# the default features. And enable "libc" to enable the libc implementations.
10-
origin = { path = "../..", default-features = false, features = ["libc", "thread", "alloc"] }
10+
origin = { path = "../..", default-features = false, features = ["libc", "thread", "alloc", "eh-personality-continue", "panic-handler-abort", "nightly"] }
1111

1212
# Crates to help writing no_std code.
1313
atomic-dbg = { version = "0.1.8", default-features = false }

0 commit comments

Comments
 (0)