Skip to content
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

Add build support for Cargo's build-std feature. #74033

Merged
merged 7 commits into from
Jul 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2056,6 +2056,7 @@ dependencies = [
name = "panic_abort"
version = "0.0.0"
dependencies = [
"cfg-if",
"compiler_builtins",
"core",
"libc",
Expand Down Expand Up @@ -4552,6 +4553,7 @@ dependencies = [
name = "test"
version = "0.0.0"
dependencies = [
"cfg-if",
"core",
"getopts",
"libc",
Expand Down
1 change: 1 addition & 0 deletions src/libpanic_abort/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ bench = false
doc = false

[dependencies]
cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
core = { path = "../libcore" }
libc = { version = "0.2", default-features = false }
compiler_builtins = "0.1.0"
35 changes: 19 additions & 16 deletions src/libpanic_abort/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,26 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen
pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 {
abort();

#[cfg(any(unix, target_os = "cloudabi"))]
unsafe fn abort() -> ! {
libc::abort();
}

#[cfg(any(windows, all(target_arch = "wasm32", not(target_os = "emscripten"))))]
unsafe fn abort() -> ! {
core::intrinsics::abort();
}

#[cfg(any(target_os = "hermit", all(target_vendor = "fortanix", target_env = "sgx")))]
unsafe fn abort() -> ! {
// call std::sys::abort_internal
extern "C" {
pub fn __rust_abort() -> !;
cfg_if::cfg_if! {
if #[cfg(any(unix, target_os = "cloudabi"))] {
unsafe fn abort() -> ! {
libc::abort();
}
} else if #[cfg(any(target_os = "hermit",
all(target_vendor = "fortanix", target_env = "sgx")
))] {
unsafe fn abort() -> ! {
// call std::sys::abort_internal
extern "C" {
pub fn __rust_abort() -> !;
}
__rust_abort();
}
} else {
unsafe fn abort() -> ! {
core::intrinsics::abort();
}
}
__rust_abort();
}
}

Expand Down
20 changes: 16 additions & 4 deletions src/libpanic_unwind/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,33 @@ cfg_if::cfg_if! {
if #[cfg(target_os = "emscripten")] {
#[path = "emcc.rs"]
mod real_imp;
} else if #[cfg(target_arch = "wasm32")] {
#[path = "dummy.rs"]
mod real_imp;
} else if #[cfg(target_os = "hermit")] {
#[path = "hermit.rs"]
mod real_imp;
} else if #[cfg(target_env = "msvc")] {
#[path = "seh.rs"]
mod real_imp;
} else {
} else if #[cfg(any(
all(target_family = "windows", target_env = "gnu"),
target_os = "cloudabi",
target_family = "unix",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target_family = "unix" FWIW I think is the same as unix, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is the same. I have been waffling on which style I like better, and I think I ended up being really inconsistent. I think part of the issue is that I've run into a number of users being confused what cfg(unix) means, which makes me feel it is better to be explicit. But unix and windows is conveniently short.

One thing that surprises me is that it is possible to have family="unix" and os="none" at the same time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh either way is fine by me, I figured unix is a bit more idiomatic though. For unix, target_os = "none" being true that seems like it's either a mistake or something that hasn't been reviewed since it was added

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x86_64-linux-kernel is the only one. I'm not sure what values would make sense for that, since it is unusual.

Copy link
Member

@eddyb eddyb Jul 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the Linux kernel even have an UNIX API inside of itself? That doesn't sound right but maybe I just haven't seen it before.

(To be clear, I'm thinking that family="unix" is as valid for inside an OS kernel as os="thatosname" - if os="none" is used then surely there should also not be a family? Maybe we should enforce that the family is derived from the OS name and therefore means "OS family")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #74247 for further discussion.

Copy link
Member

@eddyb eddyb Jul 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it was related or coincidental but I just saw #74257 being open. Oh, highly relevant, just likely accidentally pointing to the wrong #.

all(target_vendor = "fortanix", target_env = "sgx"),
))] {
// Rust runtime's startup objects depend on these symbols, so make them public.
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
pub use real_imp::eh_frame_registry::*;
#[path = "gcc.rs"]
mod real_imp;
} else {
// Targets that don't support unwinding.
// - arch=wasm32
// - os=none ("bare metal" targets)
// - os=uefi
// - nvptx64-nvidia-cuda
// - avr-unknown-unknown
// - mipsel-sony-psp
#[path = "dummy.rs"]
mod real_imp;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#![feature(in_band_lifetimes)]
#![feature(negative_impls)]
#![feature(optin_builtin_traits)]
#![feature(restricted_std)]
#![feature(rustc_attrs)]
#![feature(min_specialization)]
#![recursion_limit = "256"]
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_passes/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,8 @@ impl Visitor<'tcx> for Checker<'tcx> {
match item.kind {
hir::ItemKind::ExternCrate(_) => {
// compiler-generated `extern crate` items have a dummy span.
if item.span.is_dummy() {
// `std` is still checked for the `restricted-std` feature.
if item.span.is_dummy() && item.ident.as_str() != "std" {
return;
}

Expand Down
24 changes: 24 additions & 0 deletions src/libstd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,29 @@ fn main() {
}
println!("cargo:rustc-link-lib=c");
println!("cargo:rustc-link-lib=compiler_rt");
} else if (target.contains("sgx") && target.contains("fortanix"))
|| target.contains("hermit")
|| target.contains("l4re")
|| target.contains("redox")
|| target.contains("haiku")
|| target.contains("vxworks")
|| target.contains("wasm32")
|| target.contains("asmjs")
{
// These platforms don't have any special requirements.
} else {
// This is for Cargo's build-std support, to mark std as unstable for
// typically no_std platforms.
// This covers:
// - os=none ("bare metal" targets)
// - mipsel-sony-psp
// - nvptx64-nvidia-cuda
// - avr-unknown-unknown
// - tvos (aarch64-apple-tvos, x86_64-apple-tvos)
// - uefi (x86_64-unknown-uefi, i686-unknown-uefi)
// - JSON targets
// - Any new targets that have not been explicitly added above.
println!("cargo:rustc-cfg=feature=\"restricted-std\"");
alexcrichton marked this conversation as resolved.
Show resolved Hide resolved
}
println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());
}
77 changes: 1 addition & 76 deletions src/libstd/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ pub mod consts {
/// - s390x
/// - sparc64
#[stable(feature = "env", since = "1.0.0")]
pub const ARCH: &str = super::arch::ARCH;
pub const ARCH: &str = env!("STD_ENV_ARCH");

/// The family of the operating system. Example value is `unix`.
///
Expand Down Expand Up @@ -966,81 +966,6 @@ pub mod consts {
pub const EXE_EXTENSION: &str = os::EXE_EXTENSION;
}

#[cfg(target_arch = "x86")]
mod arch {
pub const ARCH: &str = "x86";
}

#[cfg(target_arch = "x86_64")]
mod arch {
pub const ARCH: &str = "x86_64";
}

#[cfg(target_arch = "arm")]
mod arch {
pub const ARCH: &str = "arm";
}

#[cfg(target_arch = "aarch64")]
mod arch {
pub const ARCH: &str = "aarch64";
}

#[cfg(target_arch = "mips")]
mod arch {
pub const ARCH: &str = "mips";
}

#[cfg(target_arch = "mips64")]
mod arch {
pub const ARCH: &str = "mips64";
}

#[cfg(target_arch = "powerpc")]
mod arch {
pub const ARCH: &str = "powerpc";
}

#[cfg(target_arch = "powerpc64")]
mod arch {
pub const ARCH: &str = "powerpc64";
}

#[cfg(target_arch = "s390x")]
mod arch {
pub const ARCH: &str = "s390x";
}

#[cfg(target_arch = "sparc64")]
mod arch {
pub const ARCH: &str = "sparc64";
}

#[cfg(target_arch = "le32")]
mod arch {
pub const ARCH: &str = "le32";
}

#[cfg(target_arch = "asmjs")]
mod arch {
pub const ARCH: &str = "asmjs";
}

#[cfg(target_arch = "wasm32")]
mod arch {
pub const ARCH: &str = "wasm32";
}

#[cfg(target_arch = "hexagon")]
mod arch {
pub const ARCH: &'static str = "hexagon";
}

#[cfg(target_arch = "riscv64")]
mod arch {
pub const ARCH: &'static str = "riscv64";
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
9 changes: 8 additions & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@
//! [primitive types]: ../book/ch03-02-data-types.html
//! [rust-discord]: https://discord.gg/rust-lang

#![stable(feature = "rust1", since = "1.0.0")]
#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
Expand Down Expand Up @@ -552,3 +553,9 @@ include!("primitive_docs.rs");
// the rustdoc documentation for the existing keywords. Using `include!`
// because rustdoc only looks for these modules at the crate level.
include!("keyword_docs.rs");

// This is required to avoid an unstable error when `restricted-std` is not
alexcrichton marked this conversation as resolved.
Show resolved Hide resolved
// enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std
// is unconditional, so the unstable feature needs to be defined somewhere.
#[cfg_attr(not(feature = "restricted-std"), unstable(feature = "restricted_std", issue = "none"))]
mod __restricted_std_workaround {}
3 changes: 2 additions & 1 deletion src/libstd/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ cfg_if::cfg_if! {
mod sgx;
pub use self::sgx::*;
} else {
compile_error!("libstd doesn't compile for this platform yet");
mod unsupported;
pub use self::unsupported::*;
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/libstd/sys/unsupported/alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::alloc::{GlobalAlloc, Layout, System};

#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
0 as *mut u8
}

#[inline]
unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 {
0 as *mut u8
}

#[inline]
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}

#[inline]
unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 {
0 as *mut u8
}
}
38 changes: 38 additions & 0 deletions src/libstd/sys/unsupported/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::ffi::OsString;

pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
pub unsafe fn cleanup() {}

pub struct Args {}

pub fn args() -> Args {
Args {}
}

impl Args {
pub fn inner_debug(&self) -> &[OsString] {
&[]
}
}

impl Iterator for Args {
type Item = OsString;
fn next(&mut self) -> Option<OsString> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}

impl ExactSizeIterator for Args {
fn len(&self) -> usize {
0
}
}

impl DoubleEndedIterator for Args {
fn next_back(&mut self) -> Option<OsString> {
None
}
}
File renamed without changes.
48 changes: 48 additions & 0 deletions src/libstd/sys/unsupported/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use crate::io as std_io;

pub mod memchr {
pub use core::slice::memchr::{memchr, memrchr};
}

pub use crate::sys_common::os_str_bytes as os_str;

// This is not necessarily correct. May want to consider making it part of the
// spec definition?
use crate::os::raw::c_char;

#[cfg(not(test))]
pub fn init() {}

pub fn unsupported<T>() -> std_io::Result<T> {
Err(unsupported_err())
}

pub fn unsupported_err() -> std_io::Error {
std_io::Error::new(std_io::ErrorKind::Other, "operation not supported on this platform")
}

pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Other
}

pub fn abort_internal() -> ! {
core::intrinsics::abort();
}

pub fn hashmap_random_keys() -> (u64, u64) {
(1, 2)
}

// This enum is used as the storage for a bunch of types which can't actually
// exist.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum Void {}

pub unsafe fn strlen(mut s: *const c_char) -> usize {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
}
return n;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ impl Condvar {
pub unsafe fn notify_all(&self) {}

pub unsafe fn wait(&self, _mutex: &Mutex) {
panic!("can't block with web assembly")
panic!("condvar wait not supported")
}

pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
panic!("can't block with web assembly");
panic!("condvar wait not supported");
}

#[inline]
Expand Down
Loading