Auto merge of #94916 - matthiaskrgr:rollup-s6zedfl, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #93292 (Implement `BITS` constant for non-zero integers) - #94777 (Update armv7-unknown-linux-uclibceabi platform support page.) - #94816 (Add `Atomic*::get_mut_slice`) - #94844 (Reduce rustbuild bloat caused by serde_derive) - #94907 (Omit stdarch test crates from the rust-src component) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e95b10ba4a
@ -465,7 +465,7 @@ macro_rules! nonzero_unsigned_operations {
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn log2(self) -> u32 {
|
||||
<$Int>::BITS - 1 - self.leading_zeros()
|
||||
Self::BITS - 1 - self.leading_zeros()
|
||||
}
|
||||
|
||||
/// Returns the base 10 logarithm of the number, rounded down.
|
||||
@ -1090,3 +1090,41 @@ nonzero_min_max_signed! {
|
||||
NonZeroI128(i128);
|
||||
NonZeroIsize(isize);
|
||||
}
|
||||
|
||||
macro_rules! nonzero_bits {
|
||||
( $( $Ty: ident($Int: ty); )+ ) => {
|
||||
$(
|
||||
impl $Ty {
|
||||
/// The size of this non-zero integer type in bits.
|
||||
///
|
||||
#[doc = concat!("This value is equal to [`", stringify!($Int), "::BITS`].")]
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(nonzero_bits)]
|
||||
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||
///
|
||||
#[doc = concat!("assert_eq!(", stringify!($Ty), "::BITS, ", stringify!($Int), "::BITS);")]
|
||||
/// ```
|
||||
#[unstable(feature = "nonzero_bits", issue = "94881")]
|
||||
pub const BITS: u32 = <$Int>::BITS;
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
nonzero_bits! {
|
||||
NonZeroU8(u8);
|
||||
NonZeroI8(i8);
|
||||
NonZeroU16(u16);
|
||||
NonZeroI16(i16);
|
||||
NonZeroU32(u32);
|
||||
NonZeroI32(i32);
|
||||
NonZeroU64(u64);
|
||||
NonZeroI64(i64);
|
||||
NonZeroU128(u128);
|
||||
NonZeroI128(i128);
|
||||
NonZeroUsize(usize);
|
||||
NonZeroIsize(isize);
|
||||
}
|
||||
|
@ -340,6 +340,40 @@ impl AtomicBool {
|
||||
unsafe { &mut *(v as *mut bool as *mut Self) }
|
||||
}
|
||||
|
||||
/// Get non-atomic access to a `&mut [AtomicBool]` slice.
|
||||
///
|
||||
/// This is safe because the mutable reference guarantees that no other threads are
|
||||
/// concurrently accessing the atomic data.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(atomic_from_mut, inline_const, scoped_threads)]
|
||||
/// use std::sync::atomic::{AtomicBool, Ordering};
|
||||
///
|
||||
/// let mut some_bools = [const { AtomicBool::new(false) }; 10];
|
||||
///
|
||||
/// let view: &mut [bool] = AtomicBool::get_mut_slice(&mut some_bools);
|
||||
/// assert_eq!(view, [false; 10]);
|
||||
/// view[..5].copy_from_slice(&[true; 5]);
|
||||
///
|
||||
/// std::thread::scope(|s| {
|
||||
/// for t in &some_bools[..5] {
|
||||
/// s.spawn(move || assert_eq!(t.load(Ordering::Relaxed), true));
|
||||
/// }
|
||||
///
|
||||
/// for f in &some_bools[5..] {
|
||||
/// s.spawn(move || assert_eq!(f.load(Ordering::Relaxed), false));
|
||||
/// }
|
||||
/// });
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "atomic_from_mut", issue = "76314")]
|
||||
pub fn get_mut_slice(this: &mut [Self]) -> &mut [bool] {
|
||||
// SAFETY: the mutable reference guarantees unique ownership.
|
||||
unsafe { &mut *(this as *mut [Self] as *mut [bool]) }
|
||||
}
|
||||
|
||||
/// Get atomic access to a `&mut [bool]` slice.
|
||||
///
|
||||
/// # Examples
|
||||
@ -971,6 +1005,46 @@ impl<T> AtomicPtr<T> {
|
||||
unsafe { &mut *(v as *mut *mut T as *mut Self) }
|
||||
}
|
||||
|
||||
/// Get non-atomic access to a `&mut [AtomicPtr]` slice.
|
||||
///
|
||||
/// This is safe because the mutable reference guarantees that no other threads are
|
||||
/// concurrently accessing the atomic data.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(atomic_from_mut, inline_const, scoped_threads)]
|
||||
/// use std::ptr::null_mut;
|
||||
/// use std::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let mut some_ptrs = [const { AtomicPtr::new(null_mut::<String>()) }; 10];
|
||||
///
|
||||
/// let view: &mut [*mut String] = AtomicPtr::get_mut_slice(&mut some_ptrs);
|
||||
/// assert_eq!(view, [null_mut::<String>(); 10]);
|
||||
/// view
|
||||
/// .iter_mut()
|
||||
/// .enumerate()
|
||||
/// .for_each(|(i, ptr)| *ptr = Box::into_raw(Box::new(format!("iteration#{i}"))));
|
||||
///
|
||||
/// std::thread::scope(|s| {
|
||||
/// for ptr in &some_ptrs {
|
||||
/// s.spawn(move || {
|
||||
/// let ptr = ptr.load(Ordering::Relaxed);
|
||||
/// assert!(!ptr.is_null());
|
||||
///
|
||||
/// let name = unsafe { Box::from_raw(ptr) };
|
||||
/// println!("Hello, {name}!");
|
||||
/// });
|
||||
/// }
|
||||
/// });
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "atomic_from_mut", issue = "76314")]
|
||||
pub fn get_mut_slice(this: &mut [Self]) -> &mut [*mut T] {
|
||||
// SAFETY: the mutable reference guarantees unique ownership.
|
||||
unsafe { &mut *(this as *mut [Self] as *mut [*mut T]) }
|
||||
}
|
||||
|
||||
/// Get atomic access to a slice of pointers.
|
||||
///
|
||||
/// # Examples
|
||||
@ -1521,6 +1595,42 @@ macro_rules! atomic_int {
|
||||
unsafe { &mut *(v as *mut $int_type as *mut Self) }
|
||||
}
|
||||
|
||||
#[doc = concat!("Get non-atomic access to a `&mut [", stringify!($atomic_type), "]` slice")]
|
||||
///
|
||||
/// This is safe because the mutable reference guarantees that no other threads are
|
||||
/// concurrently accessing the atomic data.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(atomic_from_mut, inline_const, scoped_threads)]
|
||||
#[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
|
||||
///
|
||||
#[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
|
||||
///
|
||||
#[doc = concat!("let view: &mut [", stringify!($int_type), "] = ", stringify!($atomic_type), "::get_mut_slice(&mut some_ints);")]
|
||||
/// assert_eq!(view, [0; 10]);
|
||||
/// view
|
||||
/// .iter_mut()
|
||||
/// .enumerate()
|
||||
/// .for_each(|(idx, int)| *int = idx as _);
|
||||
///
|
||||
/// std::thread::scope(|s| {
|
||||
/// some_ints
|
||||
/// .iter()
|
||||
/// .enumerate()
|
||||
/// .for_each(|(idx, int)| {
|
||||
/// s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
|
||||
/// })
|
||||
/// });
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "atomic_from_mut", issue = "76314")]
|
||||
pub fn get_mut_slice(this: &mut [Self]) -> &mut [$int_type] {
|
||||
// SAFETY: the mutable reference guarantees unique ownership.
|
||||
unsafe { &mut *(this as *mut [Self] as *mut [$int_type]) }
|
||||
}
|
||||
|
||||
#[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")]
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -17,7 +17,7 @@ use crate::channel::GitInfo;
|
||||
pub use crate::flags::Subcommand;
|
||||
use crate::flags::{Color, Flags};
|
||||
use crate::util::{exe, t};
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
macro_rules! check_ci_llvm {
|
||||
($name:expr) => {
|
||||
@ -362,13 +362,13 @@ impl Merge for TomlConfig {
|
||||
|
||||
// We are using a decl macro instead of a derive proc macro here to reduce the compile time of
|
||||
// rustbuild.
|
||||
macro_rules! derive_merge {
|
||||
macro_rules! define_config {
|
||||
($(#[$attr:meta])* struct $name:ident {
|
||||
$($field:ident: $field_ty:ty,)*
|
||||
$($field:ident: Option<$field_ty:ty> = $field_key:literal,)*
|
||||
}) => {
|
||||
$(#[$attr])*
|
||||
struct $name {
|
||||
$($field: $field_ty,)*
|
||||
$($field: Option<$field_ty>,)*
|
||||
}
|
||||
|
||||
impl Merge for $name {
|
||||
@ -380,115 +380,173 @@ macro_rules! derive_merge {
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
// The following is a trimmed version of what serde_derive generates. All parts not relevant
|
||||
// for toml deserialization have been removed. This reduces the binary size and improves
|
||||
// compile time of rustbuild.
|
||||
impl<'de> Deserialize<'de> for $name {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct Field;
|
||||
impl<'de> serde::de::Visitor<'de> for Field {
|
||||
type Value = $name;
|
||||
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(concat!("struct ", stringify!($name)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: serde::de::MapAccess<'de>,
|
||||
{
|
||||
$(let mut $field: Option<$field_ty> = None;)*
|
||||
while let Some(key) =
|
||||
match serde::de::MapAccess::next_key::<String>(&mut map) {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match &*key {
|
||||
$($field_key => {
|
||||
if $field.is_some() {
|
||||
return Err(<A::Error as serde::de::Error>::duplicate_field(
|
||||
$field_key,
|
||||
));
|
||||
}
|
||||
$field = match serde::de::MapAccess::next_value::<$field_ty>(
|
||||
&mut map,
|
||||
) {
|
||||
Ok(val) => Some(val),
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
})*
|
||||
key => {
|
||||
return Err(serde::de::Error::unknown_field(key, FIELDS));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok($name { $($field),* })
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &[
|
||||
$($field_key,)*
|
||||
];
|
||||
Deserializer::deserialize_struct(
|
||||
deserializer,
|
||||
stringify!($name),
|
||||
FIELDS,
|
||||
Field,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
derive_merge! {
|
||||
define_config! {
|
||||
/// TOML representation of various global build decisions.
|
||||
#[derive(Deserialize, Default)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
#[derive(Default)]
|
||||
struct Build {
|
||||
build: Option<String>,
|
||||
host: Option<Vec<String>>,
|
||||
target: Option<Vec<String>>,
|
||||
build_dir: Option<String>,
|
||||
cargo: Option<String>,
|
||||
rustc: Option<String>,
|
||||
rustfmt: Option<PathBuf>,
|
||||
docs: Option<bool>,
|
||||
compiler_docs: Option<bool>,
|
||||
docs_minification: Option<bool>,
|
||||
submodules: Option<bool>,
|
||||
fast_submodules: Option<bool>,
|
||||
gdb: Option<String>,
|
||||
nodejs: Option<String>,
|
||||
npm: Option<String>,
|
||||
python: Option<String>,
|
||||
locked_deps: Option<bool>,
|
||||
vendor: Option<bool>,
|
||||
full_bootstrap: Option<bool>,
|
||||
extended: Option<bool>,
|
||||
tools: Option<HashSet<String>>,
|
||||
verbose: Option<usize>,
|
||||
sanitizers: Option<bool>,
|
||||
profiler: Option<bool>,
|
||||
cargo_native_static: Option<bool>,
|
||||
low_priority: Option<bool>,
|
||||
configure_args: Option<Vec<String>>,
|
||||
local_rebuild: Option<bool>,
|
||||
print_step_timings: Option<bool>,
|
||||
print_step_rusage: Option<bool>,
|
||||
check_stage: Option<u32>,
|
||||
doc_stage: Option<u32>,
|
||||
build_stage: Option<u32>,
|
||||
test_stage: Option<u32>,
|
||||
install_stage: Option<u32>,
|
||||
dist_stage: Option<u32>,
|
||||
bench_stage: Option<u32>,
|
||||
patch_binaries_for_nix: Option<bool>,
|
||||
build: Option<String> = "build",
|
||||
host: Option<Vec<String>> = "host",
|
||||
target: Option<Vec<String>> = "target",
|
||||
build_dir: Option<String> = "build-dir",
|
||||
cargo: Option<String> = "cargo",
|
||||
rustc: Option<String> = "rustc",
|
||||
rustfmt: Option<PathBuf> = "rustfmt",
|
||||
docs: Option<bool> = "docs",
|
||||
compiler_docs: Option<bool> = "compiler-docs",
|
||||
docs_minification: Option<bool> = "docs-minification",
|
||||
submodules: Option<bool> = "submodules",
|
||||
fast_submodules: Option<bool> = "fast-submodules",
|
||||
gdb: Option<String> = "gdb",
|
||||
nodejs: Option<String> = "nodejs",
|
||||
npm: Option<String> = "npm",
|
||||
python: Option<String> = "python",
|
||||
locked_deps: Option<bool> = "locked-deps",
|
||||
vendor: Option<bool> = "vendor",
|
||||
full_bootstrap: Option<bool> = "full-bootstrap",
|
||||
extended: Option<bool> = "extended",
|
||||
tools: Option<HashSet<String>> = "tools",
|
||||
verbose: Option<usize> = "verbose",
|
||||
sanitizers: Option<bool> = "sanitizers",
|
||||
profiler: Option<bool> = "profiler",
|
||||
cargo_native_static: Option<bool> = "cargo-native-static",
|
||||
low_priority: Option<bool> = "low-priority",
|
||||
configure_args: Option<Vec<String>> = "configure-args",
|
||||
local_rebuild: Option<bool> = "local-rebuild",
|
||||
print_step_timings: Option<bool> = "print-step-timings",
|
||||
print_step_rusage: Option<bool> = "print-step-rusage",
|
||||
check_stage: Option<u32> = "check-stage",
|
||||
doc_stage: Option<u32> = "doc-stage",
|
||||
build_stage: Option<u32> = "build-stage",
|
||||
test_stage: Option<u32> = "test-stage",
|
||||
install_stage: Option<u32> = "install-stage",
|
||||
dist_stage: Option<u32> = "dist-stage",
|
||||
bench_stage: Option<u32> = "bench-stage",
|
||||
patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
|
||||
}
|
||||
}
|
||||
|
||||
derive_merge! {
|
||||
define_config! {
|
||||
/// TOML representation of various global install decisions.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
struct Install {
|
||||
prefix: Option<String>,
|
||||
sysconfdir: Option<String>,
|
||||
docdir: Option<String>,
|
||||
bindir: Option<String>,
|
||||
libdir: Option<String>,
|
||||
mandir: Option<String>,
|
||||
datadir: Option<String>,
|
||||
prefix: Option<String> = "prefix",
|
||||
sysconfdir: Option<String> = "sysconfdir",
|
||||
docdir: Option<String> = "docdir",
|
||||
bindir: Option<String> = "bindir",
|
||||
libdir: Option<String> = "libdir",
|
||||
mandir: Option<String> = "mandir",
|
||||
datadir: Option<String> = "datadir",
|
||||
}
|
||||
}
|
||||
|
||||
derive_merge! {
|
||||
define_config! {
|
||||
/// TOML representation of how the LLVM build is configured.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
struct Llvm {
|
||||
skip_rebuild: Option<bool>,
|
||||
optimize: Option<bool>,
|
||||
thin_lto: Option<bool>,
|
||||
release_debuginfo: Option<bool>,
|
||||
assertions: Option<bool>,
|
||||
tests: Option<bool>,
|
||||
plugins: Option<bool>,
|
||||
ccache: Option<StringOrBool>,
|
||||
version_check: Option<bool>,
|
||||
static_libstdcpp: Option<bool>,
|
||||
ninja: Option<bool>,
|
||||
targets: Option<String>,
|
||||
experimental_targets: Option<String>,
|
||||
link_jobs: Option<u32>,
|
||||
link_shared: Option<bool>,
|
||||
version_suffix: Option<String>,
|
||||
clang_cl: Option<String>,
|
||||
cflags: Option<String>,
|
||||
cxxflags: Option<String>,
|
||||
ldflags: Option<String>,
|
||||
use_libcxx: Option<bool>,
|
||||
use_linker: Option<String>,
|
||||
allow_old_toolchain: Option<bool>,
|
||||
polly: Option<bool>,
|
||||
clang: Option<bool>,
|
||||
download_ci_llvm: Option<StringOrBool>,
|
||||
build_config: Option<HashMap<String, String>>,
|
||||
skip_rebuild: Option<bool> = "skip-rebuild",
|
||||
optimize: Option<bool> = "optimize",
|
||||
thin_lto: Option<bool> = "thin-lto",
|
||||
release_debuginfo: Option<bool> = "release-debuginfo",
|
||||
assertions: Option<bool> = "assertions",
|
||||
tests: Option<bool> = "tests",
|
||||
plugins: Option<bool> = "plugins",
|
||||
ccache: Option<StringOrBool> = "ccache",
|
||||
version_check: Option<bool> = "version-check",
|
||||
static_libstdcpp: Option<bool> = "static-libstdcpp",
|
||||
ninja: Option<bool> = "ninja",
|
||||
targets: Option<String> = "targets",
|
||||
experimental_targets: Option<String> = "experimental-targets",
|
||||
link_jobs: Option<u32> = "link-jobs",
|
||||
link_shared: Option<bool> = "link-shared",
|
||||
version_suffix: Option<String> = "version-suffix",
|
||||
clang_cl: Option<String> = "clang-cl",
|
||||
cflags: Option<String> = "cflags",
|
||||
cxxflags: Option<String> = "cxxflags",
|
||||
ldflags: Option<String> = "ldflags",
|
||||
use_libcxx: Option<bool> = "use-libcxx",
|
||||
use_linker: Option<String> = "use-linker",
|
||||
allow_old_toolchain: Option<bool> = "allow-old-toolchain",
|
||||
polly: Option<bool> = "polly",
|
||||
clang: Option<bool> = "clang",
|
||||
download_ci_llvm: Option<StringOrBool> = "download-ci-llvm",
|
||||
build_config: Option<HashMap<String, String>> = "build-config",
|
||||
}
|
||||
}
|
||||
|
||||
derive_merge! {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
define_config! {
|
||||
struct Dist {
|
||||
sign_folder: Option<String>,
|
||||
gpg_password_file: Option<String>,
|
||||
upload_addr: Option<String>,
|
||||
src_tarball: Option<bool>,
|
||||
missing_tools: Option<bool>,
|
||||
compression_formats: Option<Vec<String>>,
|
||||
sign_folder: Option<String> = "sign-folder",
|
||||
gpg_password_file: Option<String> = "gpg-password-file",
|
||||
upload_addr: Option<String> = "upload-addr",
|
||||
src_tarball: Option<bool> = "src-tarball",
|
||||
missing_tools: Option<bool> = "missing-tools",
|
||||
compression_formats: Option<Vec<String>> = "compression-formats",
|
||||
}
|
||||
}
|
||||
|
||||
@ -505,83 +563,79 @@ impl Default for StringOrBool {
|
||||
}
|
||||
}
|
||||
|
||||
derive_merge! {
|
||||
define_config! {
|
||||
/// TOML representation of how the Rust build is configured.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
struct Rust {
|
||||
optimize: Option<bool>,
|
||||
debug: Option<bool>,
|
||||
codegen_units: Option<u32>,
|
||||
codegen_units_std: Option<u32>,
|
||||
debug_assertions: Option<bool>,
|
||||
debug_assertions_std: Option<bool>,
|
||||
overflow_checks: Option<bool>,
|
||||
overflow_checks_std: Option<bool>,
|
||||
debug_logging: Option<bool>,
|
||||
debuginfo_level: Option<u32>,
|
||||
debuginfo_level_rustc: Option<u32>,
|
||||
debuginfo_level_std: Option<u32>,
|
||||
debuginfo_level_tools: Option<u32>,
|
||||
debuginfo_level_tests: Option<u32>,
|
||||
run_dsymutil: Option<bool>,
|
||||
backtrace: Option<bool>,
|
||||
incremental: Option<bool>,
|
||||
parallel_compiler: Option<bool>,
|
||||
default_linker: Option<String>,
|
||||
channel: Option<String>,
|
||||
description: Option<String>,
|
||||
musl_root: Option<String>,
|
||||
rpath: Option<bool>,
|
||||
verbose_tests: Option<bool>,
|
||||
optimize_tests: Option<bool>,
|
||||
codegen_tests: Option<bool>,
|
||||
ignore_git: Option<bool>,
|
||||
dist_src: Option<bool>,
|
||||
save_toolstates: Option<String>,
|
||||
codegen_backends: Option<Vec<String>>,
|
||||
lld: Option<bool>,
|
||||
use_lld: Option<bool>,
|
||||
llvm_tools: Option<bool>,
|
||||
deny_warnings: Option<bool>,
|
||||
backtrace_on_ice: Option<bool>,
|
||||
verify_llvm_ir: Option<bool>,
|
||||
thin_lto_import_instr_limit: Option<u32>,
|
||||
remap_debuginfo: Option<bool>,
|
||||
jemalloc: Option<bool>,
|
||||
test_compare_mode: Option<bool>,
|
||||
llvm_libunwind: Option<String>,
|
||||
control_flow_guard: Option<bool>,
|
||||
new_symbol_mangling: Option<bool>,
|
||||
profile_generate: Option<String>,
|
||||
profile_use: Option<String>,
|
||||
optimize: Option<bool> = "optimize",
|
||||
debug: Option<bool> = "debug",
|
||||
codegen_units: Option<u32> = "codegen-units",
|
||||
codegen_units_std: Option<u32> = "codegen-units-std",
|
||||
debug_assertions: Option<bool> = "debug-assertions",
|
||||
debug_assertions_std: Option<bool> = "debug-assertions-std",
|
||||
overflow_checks: Option<bool> = "overflow-checks",
|
||||
overflow_checks_std: Option<bool> = "overflow-checks-std",
|
||||
debug_logging: Option<bool> = "debug-logging",
|
||||
debuginfo_level: Option<u32> = "debuginfo-level",
|
||||
debuginfo_level_rustc: Option<u32> = "debuginfo-level-rustc",
|
||||
debuginfo_level_std: Option<u32> = "debuginfo-level-std",
|
||||
debuginfo_level_tools: Option<u32> = "debuginfo-level-tools",
|
||||
debuginfo_level_tests: Option<u32> = "debuginfo-level-tests",
|
||||
run_dsymutil: Option<bool> = "run-dsymutil",
|
||||
backtrace: Option<bool> = "backtrace",
|
||||
incremental: Option<bool> = "incremental",
|
||||
parallel_compiler: Option<bool> = "parallel-compiler",
|
||||
default_linker: Option<String> = "default-linker",
|
||||
channel: Option<String> = "channel",
|
||||
description: Option<String> = "description",
|
||||
musl_root: Option<String> = "musl-root",
|
||||
rpath: Option<bool> = "rpath",
|
||||
verbose_tests: Option<bool> = "verbose-tests",
|
||||
optimize_tests: Option<bool> = "optimize-tests",
|
||||
codegen_tests: Option<bool> = "codegen-tests",
|
||||
ignore_git: Option<bool> = "ignore-git",
|
||||
dist_src: Option<bool> = "dist-src",
|
||||
save_toolstates: Option<String> = "save-toolstates",
|
||||
codegen_backends: Option<Vec<String>> = "codegen-backends",
|
||||
lld: Option<bool> = "lld",
|
||||
use_lld: Option<bool> = "use-lld",
|
||||
llvm_tools: Option<bool> = "llvm-tools",
|
||||
deny_warnings: Option<bool> = "deny-warnings",
|
||||
backtrace_on_ice: Option<bool> = "backtrace-on-ice",
|
||||
verify_llvm_ir: Option<bool> = "verify-llvm-ir",
|
||||
thin_lto_import_instr_limit: Option<u32> = "thin-lto-import-instr-limit",
|
||||
remap_debuginfo: Option<bool> = "remap-debuginfo",
|
||||
jemalloc: Option<bool> = "jemalloc",
|
||||
test_compare_mode: Option<bool> = "test-compare-mode",
|
||||
llvm_libunwind: Option<String> = "llvm-libunwind",
|
||||
control_flow_guard: Option<bool> = "control-flow-guard",
|
||||
new_symbol_mangling: Option<bool> = "new-symbol-mangling",
|
||||
profile_generate: Option<String> = "profile-generate",
|
||||
profile_use: Option<String> = "profile-use",
|
||||
// ignored; this is set from an env var set by bootstrap.py
|
||||
download_rustc: Option<StringOrBool>,
|
||||
download_rustc: Option<StringOrBool> = "download-rustc",
|
||||
}
|
||||
}
|
||||
|
||||
derive_merge! {
|
||||
define_config! {
|
||||
/// TOML representation of how each build target is configured.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
struct TomlTarget {
|
||||
cc: Option<String>,
|
||||
cxx: Option<String>,
|
||||
ar: Option<String>,
|
||||
ranlib: Option<String>,
|
||||
default_linker: Option<PathBuf>,
|
||||
linker: Option<String>,
|
||||
llvm_config: Option<String>,
|
||||
llvm_filecheck: Option<String>,
|
||||
android_ndk: Option<String>,
|
||||
sanitizers: Option<bool>,
|
||||
profiler: Option<bool>,
|
||||
crt_static: Option<bool>,
|
||||
musl_root: Option<String>,
|
||||
musl_libdir: Option<String>,
|
||||
wasi_root: Option<String>,
|
||||
qemu_rootfs: Option<String>,
|
||||
no_std: Option<bool>,
|
||||
cc: Option<String> = "cc",
|
||||
cxx: Option<String> = "cxx",
|
||||
ar: Option<String> = "ar",
|
||||
ranlib: Option<String> = "ranlib",
|
||||
default_linker: Option<PathBuf> = "default-linker",
|
||||
linker: Option<String> = "linker",
|
||||
llvm_config: Option<String> = "llvm-config",
|
||||
llvm_filecheck: Option<String> = "llvm-filecheck",
|
||||
android_ndk: Option<String> = "android-ndk",
|
||||
sanitizers: Option<bool> = "sanitizers",
|
||||
profiler: Option<bool> = "profiler",
|
||||
crt_static: Option<bool> = "crt-static",
|
||||
musl_root: Option<String> = "musl-root",
|
||||
musl_libdir: Option<String> = "musl-libdir",
|
||||
wasi_root: Option<String> = "wasi-root",
|
||||
qemu_rootfs: Option<String> = "qemu-rootfs",
|
||||
no_std: Option<bool> = "no-std",
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,7 +703,11 @@ impl Config {
|
||||
|
||||
let contents =
|
||||
t!(fs::read_to_string(file), format!("config file {} not found", file.display()));
|
||||
match toml::from_str(&contents) {
|
||||
// Deserialize to Value and then TomlConfig to prevent the Deserialize impl of
|
||||
// TomlConfig and sub types to be monomorphized 5x by toml.
|
||||
match toml::from_str(&contents)
|
||||
.and_then(|table: toml::Value| TomlConfig::deserialize(table))
|
||||
{
|
||||
Ok(table) => table,
|
||||
Err(err) => {
|
||||
println!("failed to parse TOML configuration '{}': {}", file.display(), err);
|
||||
|
@ -821,6 +821,11 @@ impl Step for Src {
|
||||
// not needed and contains symlinks which rustup currently
|
||||
// chokes on when unpacking.
|
||||
"library/backtrace/crates",
|
||||
// these are 30MB combined and aren't necessary for building
|
||||
// the standard library.
|
||||
"library/stdarch/crates/Cargo.toml",
|
||||
"library/stdarch/crates/stdarch-verify",
|
||||
"library/stdarch/crates/intrinsic-test",
|
||||
],
|
||||
&dst_src,
|
||||
);
|
||||
|
@ -36,8 +36,8 @@ target = ["armv7-unknown-linux-uclibceabi"]
|
||||
cc = "/path/to/arm-unknown-linux-uclibcgnueabi-gcc"
|
||||
cxx = "/path/to/arm-unknown-linux-uclibcgnueabi-g++"
|
||||
ar = "path/to/arm-unknown-linux-uclibcgnueabi-ar"
|
||||
ranlib = "path/to/arm-unknown-linux-uclibcgnueabi-"
|
||||
linker = "/path/to/arm-unknown-linux-uclibcgnueabi-"
|
||||
ranlib = "path/to/arm-unknown-linux-uclibcgnueabi-ranlib"
|
||||
linker = "/path/to/arm-unknown-linux-uclibcgnueabi-gcc"
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
@ -75,27 +75,37 @@ To cross compile, you'll need to:
|
||||
```
|
||||
* Build with:
|
||||
```text
|
||||
CC=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-gcc \
|
||||
CXX=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-g++ \
|
||||
AR=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-ar \
|
||||
CC_armv7_unknown_linux_uclibceabi=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-gcc \
|
||||
CXX_armv7_unknown_linux_uclibceabi=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-g++ \
|
||||
AR_armv7_unknown_linux_uclibceabi=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-ar \
|
||||
CFLAGS_armv7_unknown_linux_uclibceabi="-march=armv7-a -mtune=cortex-a9" \
|
||||
CXXFLAGS_armv7_unknown_linux_uclibceabi="-march=armv7-a -mtune=cortex-a9" \
|
||||
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABI_LINKER=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-gcc \
|
||||
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABI_RUSTFLAGS='-Clink-arg=-s -Clink-arg=-Wl,--dynamic-linker=/mmc/lib/ld-uClibc.so.1 -Clink-arg=-Wl,-rpath,/mmc/lib' \
|
||||
cargo +stage2 build --target armv7-unknown-linux-uclibceabi --release
|
||||
cargo +stage2 \
|
||||
build \
|
||||
--target armv7-unknown-linux-uclibceabi \
|
||||
--release
|
||||
```
|
||||
* Copy the binary to your target device and run.
|
||||
|
||||
We specify `CC`, `CXX`, and `AR` because somtimes a project or a subproject requires the use of your `'C'` cross toolchain. Since Tomatoware has a modified sysroot we also pass via RUSTFLAGS the location of the dynamic-linker and rpath.
|
||||
We specify `CC`, `CXX`, `AR`, `CFLAGS`, and `CXXFLAGS` environment variables because somtimes a project or a subproject requires the use of your `'C'` cross toolchain. Since Tomatoware has a modified sysroot we also pass via RUSTFLAGS the location of the dynamic-linker and rpath.
|
||||
|
||||
### Test with QEMU
|
||||
|
||||
To test a cross-compiled binary on your build system follow the instructions for `Cross Compilation`, install `qemu-arm-static`, and run with the following.
|
||||
```text
|
||||
CC=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-gcc \
|
||||
CXX=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-g++ \
|
||||
AR=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-ar \
|
||||
CC_armv7_unknown_linux_uclibceabi=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-gcc \
|
||||
CXX_armv7_unknown_linux_uclibceabi=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-g++ \
|
||||
AR_armv7_unknown_linux_uclibceabi=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-ar \
|
||||
CFLAGS_armv7_unknown_linux_uclibceabi="-march=armv7-a -mtune=cortex-a9" \
|
||||
CXXFLAGS_armv7_unknown_linux_uclibceabi="-march=armv7-a -mtune=cortex-a9" \
|
||||
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABI_LINKER=/opt/tomatoware/arm-soft-mmc/bin/arm-linux-gcc \
|
||||
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABI_RUNNER="qemu-arm-static -L /opt/tomatoware/arm-soft-mmc/arm-tomatoware-linux-uclibcgnueabi/sysroot/" \
|
||||
cargo +stage2 run --target armv7-unknown-linux-uclibceabi --release
|
||||
cargo +stage2 \
|
||||
run \
|
||||
--target armv7-unknown-linux-uclibceabi \
|
||||
--release
|
||||
```
|
||||
### Run in a chroot
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user