mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 22:53:28 +00:00
Merge branch 'rust-lang:master' into must-use-alloc-constructors
This commit is contained in:
commit
ecd7ea8a9c
@ -175,7 +175,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
|
||||
// should use dllimport for functions.
|
||||
if cx.use_dll_storage_attrs
|
||||
&& tcx.is_dllimport_foreign_item(instance_def_id)
|
||||
&& tcx.sess.target.env != "gnu"
|
||||
&& !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc")
|
||||
{
|
||||
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
|
||||
}
|
||||
|
@ -3012,7 +3012,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
};
|
||||
|
||||
let target = &self.tcx.sess.target;
|
||||
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl");
|
||||
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
|
||||
let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
|
||||
let linux_s390x_gnu_like =
|
||||
target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
|
||||
@ -3110,7 +3110,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
if arg.layout.is_zst() {
|
||||
// For some forsaken reason, x86_64-pc-windows-gnu
|
||||
// doesn't ignore zero-sized struct arguments.
|
||||
// The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl}.
|
||||
// The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}.
|
||||
if is_return
|
||||
|| rust_abi
|
||||
|| (!win_x64_gnu
|
||||
|
@ -0,0 +1,24 @@
|
||||
use crate::spec::{Target, TargetOptions};
|
||||
|
||||
// This target is for uclibc Linux on ARMv7 without NEON or
|
||||
// thumb-mode. See the thumbv7neon variant for enabling both.
|
||||
|
||||
pub fn target() -> Target {
|
||||
let base = super::linux_uclibc_base::opts();
|
||||
Target {
|
||||
llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
|
||||
pointer_width: 32,
|
||||
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||
arch: "arm".to_string(),
|
||||
|
||||
options: TargetOptions {
|
||||
// Info about features at https://wiki.debian.org/ArmHardFloatPort
|
||||
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
|
||||
cpu: "generic".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
mcount: "_mcount".to_string(),
|
||||
abi: "eabihf".to_string(),
|
||||
..base
|
||||
},
|
||||
}
|
||||
}
|
@ -952,6 +952,8 @@ supported_targets! {
|
||||
("bpfel-unknown-none", bpfel_unknown_none),
|
||||
|
||||
("armv6k-nintendo-3ds", armv6k_nintendo_3ds),
|
||||
|
||||
("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf),
|
||||
}
|
||||
|
||||
/// Warnings encountered when parsing the target `json`.
|
||||
|
@ -307,6 +307,9 @@ cfg_if::cfg_if! {
|
||||
#[link(name = "zircon")]
|
||||
#[link(name = "fdio")]
|
||||
extern "C" {}
|
||||
} else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] {
|
||||
#[link(name = "dl")]
|
||||
extern "C" {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,7 +594,8 @@ pub mod guard {
|
||||
Some(stackaddr - guardsize..stackaddr)
|
||||
} else if cfg!(all(target_os = "linux", target_env = "musl")) {
|
||||
Some(stackaddr - guardsize..stackaddr)
|
||||
} else if cfg!(all(target_os = "linux", target_env = "gnu")) {
|
||||
} else if cfg!(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))
|
||||
{
|
||||
// glibc used to include the guard area within the stack, as noted in the BUGS
|
||||
// section of `man pthread_attr_getguardsize`. This has been corrected starting
|
||||
// with glibc 2.27, and in some distro backports, so the guard is now placed at the
|
||||
|
@ -63,7 +63,7 @@ cfg_if::cfg_if! {
|
||||
// don't want to duplicate it here.
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
target_env = "gnu",
|
||||
any(target_env = "gnu", target_env = "uclibc"),
|
||||
not(feature = "llvm-libunwind"),
|
||||
not(feature = "system-llvm-libunwind")
|
||||
))]
|
||||
@ -72,7 +72,7 @@ extern "C" {}
|
||||
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
target_env = "gnu",
|
||||
any(target_env = "gnu", target_env = "uclibc"),
|
||||
not(feature = "llvm-libunwind"),
|
||||
feature = "system-llvm-libunwind"
|
||||
))]
|
||||
|
@ -220,6 +220,7 @@ target | std | host | notes
|
||||
`armv6-unknown-netbsd-eabihf` | ? | |
|
||||
`armv6k-nintendo-3ds` | * | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
|
||||
`armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8
|
||||
`armv7-unknown-linux-uclibceabihf` | ✓ | ? | ARMv7 Linux uClibc
|
||||
`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
|
||||
`armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
|
||||
`armv7-wrs-vxworks-eabihf` | ? | |
|
||||
|
@ -0,0 +1,66 @@
|
||||
# armv7-unknown-linux-uclibceabihf
|
||||
|
||||
**Tier: 3**
|
||||
|
||||
This tier supports the ARMv7 processor running a Linux kernel and uClibc-ng standard library. It provides full support for rust and the rust standard library.
|
||||
|
||||
## Designated Developers
|
||||
|
||||
* [@skrap](https://github.com/skrap)
|
||||
|
||||
## Requirements
|
||||
|
||||
This target is cross compiled, and requires a cross toolchain. You can find suitable pre-built toolchains at [bootlin](https://toolchains.bootlin.com/) or build one yourself via [buildroot](https://buildroot.org).
|
||||
|
||||
## Building
|
||||
|
||||
### Get a C toolchain
|
||||
|
||||
Compiling rust for this target has been tested on `x86_64` linux hosts. Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them.
|
||||
|
||||
If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2020.08-1.tar.bz2), and unpack it into a directory.
|
||||
|
||||
### Configure rust
|
||||
|
||||
The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = ["armv7-unknown-linux-uclibceabihf"]
|
||||
stage = 2
|
||||
|
||||
[target.armv7-unknown-linux-uclibceabihf]
|
||||
# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
|
||||
cc = "/TOOLCHAIN_PATH/bin/arm-buildroot-linux-uclibcgnueabihf-gcc"
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```sh
|
||||
# in rust dir
|
||||
./x.py build --stage 2
|
||||
```
|
||||
|
||||
## Building and Running Rust Programs
|
||||
|
||||
To test cross-compiled binaries on a `x86_64` system, you can use the `qemu-arm` [userspace emulation](https://qemu-project.gitlab.io/qemu/user/main.html) program. This avoids having a full emulated ARM system by doing dynamic binary translation and dynamic system call translation. It lets you run ARM programs directly on your `x86_64` kernel. It's very convenient!
|
||||
|
||||
To use:
|
||||
|
||||
* Install `qemu-arm` according to your distro.
|
||||
* Link your built toolchain via:
|
||||
* `rustup toolchain link stage2 ${RUST}/build/x86_64-unknown-linux-gnu/stage2`
|
||||
* Create a test program
|
||||
|
||||
```sh
|
||||
cargo new hello_world
|
||||
cd hello_world
|
||||
```
|
||||
|
||||
* Build and run
|
||||
|
||||
```sh
|
||||
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_RUNNER="qemu-arm -L ${TOOLCHAIN}/arm-buildroot-linux-uclibcgnueabihf/sysroot/" \
|
||||
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_LINKER=${TOOLCHAIN}/bin/arm-buildroot-linux-uclibcgnueabihf-gcc \
|
||||
cargo +stage2 run --target armv7-unknown-linux-uclibceabihf
|
||||
```
|
@ -1,6 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::error::Error as StdError;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
@ -16,6 +15,7 @@ use rustc_span::symbol::sym;
|
||||
|
||||
use super::cache::{build_index, ExternalLocation};
|
||||
use super::print_item::{full_path, item_path, print_item};
|
||||
use super::templates;
|
||||
use super::write_shared::write_shared;
|
||||
use super::{
|
||||
collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
|
||||
@ -33,7 +33,6 @@ use crate::formats::FormatRenderer;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::format::Buffer;
|
||||
use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
|
||||
use crate::html::static_files::PAGE;
|
||||
use crate::html::{layout, sources};
|
||||
|
||||
/// Major driving force in all rustdoc rendering. This contains information
|
||||
@ -225,7 +224,7 @@ impl<'tcx> Context<'tcx> {
|
||||
&self.shared.layout,
|
||||
&page,
|
||||
|buf: &mut _| print_sidebar(self, it, buf),
|
||||
|buf: &mut _| print_item(self, it, buf, &page),
|
||||
|buf: &mut _| print_item(self, &self.shared.templates, it, buf, &page),
|
||||
&self.shared.style_files,
|
||||
)
|
||||
} else {
|
||||
@ -416,12 +415,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
};
|
||||
let mut issue_tracker_base_url = None;
|
||||
let mut include_sources = true;
|
||||
|
||||
let mut templates = tera::Tera::default();
|
||||
templates.add_raw_template("page.html", PAGE).map_err(|e| Error {
|
||||
file: "page.html".into(),
|
||||
error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
|
||||
})?;
|
||||
let templates = templates::load()?;
|
||||
|
||||
// Crawl the crate attributes looking for attributes which control how we're
|
||||
// going to emit HTML
|
||||
|
@ -31,6 +31,7 @@ mod tests;
|
||||
mod context;
|
||||
mod print_item;
|
||||
mod span_map;
|
||||
mod templates;
|
||||
mod write_shared;
|
||||
|
||||
crate use context::*;
|
||||
|
@ -32,16 +32,41 @@ use crate::html::highlight;
|
||||
use crate::html::layout::Page;
|
||||
use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
const ITEM_TABLE_OPEN: &'static str = "<div class=\"item-table\">";
|
||||
const ITEM_TABLE_CLOSE: &'static str = "</div>";
|
||||
const ITEM_TABLE_ROW_OPEN: &'static str = "<div class=\"item-row\">";
|
||||
const ITEM_TABLE_ROW_CLOSE: &'static str = "</div>";
|
||||
|
||||
pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
|
||||
// A component in a `use` path, like `string` in std::string::ToString
|
||||
#[derive(Serialize)]
|
||||
struct PathComponent<'a> {
|
||||
path: String,
|
||||
name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct ItemVars<'a> {
|
||||
page: &'a Page<'a>,
|
||||
static_root_path: &'a str,
|
||||
typ: &'a str,
|
||||
name: &'a str,
|
||||
item_type: &'a str,
|
||||
path_components: Vec<PathComponent<'a>>,
|
||||
stability_since_raw: &'a str,
|
||||
src_href: Option<&'a str>,
|
||||
}
|
||||
|
||||
pub(super) fn print_item(
|
||||
cx: &Context<'_>,
|
||||
templates: &tera::Tera,
|
||||
item: &clean::Item,
|
||||
buf: &mut Buffer,
|
||||
page: &Page<'_>,
|
||||
) {
|
||||
debug_assert!(!item.is_stripped());
|
||||
// Write the breadcrumb trail header for the top
|
||||
buf.write_str("<h1 class=\"fqn\"><span class=\"in-band\">");
|
||||
let name = match *item.kind {
|
||||
let typ = match *item.kind {
|
||||
clean::ModuleItem(_) => {
|
||||
if item.is_crate() {
|
||||
"Crate "
|
||||
@ -73,48 +98,15 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
buf.write_str(name);
|
||||
if !item.is_primitive() && !item.is_keyword() {
|
||||
let cur = &cx.current;
|
||||
let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
|
||||
for (i, component) in cur.iter().enumerate().take(amt) {
|
||||
write!(
|
||||
buf,
|
||||
"<a href=\"{}index.html\">{}</a>::<wbr>",
|
||||
"../".repeat(cur.len() - i - 1),
|
||||
component
|
||||
);
|
||||
}
|
||||
}
|
||||
write!(buf, "<a class=\"{}\" href=\"#\">{}</a>", item.type_(), item.name.as_ref().unwrap());
|
||||
write!(
|
||||
buf,
|
||||
"<button id=\"copy-path\" onclick=\"copy_path(this)\" title=\"Copy item path to clipboard\">\
|
||||
<img src=\"{static_root_path}clipboard{suffix}.svg\" \
|
||||
width=\"19\" height=\"18\" \
|
||||
alt=\"Copy item path\">\
|
||||
</button>",
|
||||
static_root_path = page.get_static_root_path(),
|
||||
suffix = page.resource_suffix,
|
||||
);
|
||||
|
||||
buf.write_str("</span>"); // in-band
|
||||
buf.write_str("<span class=\"out-of-band\">");
|
||||
let mut stability_since_raw = Buffer::new();
|
||||
render_stability_since_raw(
|
||||
buf,
|
||||
&mut stability_since_raw,
|
||||
item.stable_since(cx.tcx()).as_deref(),
|
||||
item.const_stability(cx.tcx()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
buf.write_str(
|
||||
"<span id=\"render-detail\">\
|
||||
<a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
|
||||
title=\"collapse all docs\">\
|
||||
[<span class=\"inner\">−</span>]\
|
||||
</a>\
|
||||
</span>",
|
||||
);
|
||||
let stability_since_raw: String = stability_since_raw.into_inner();
|
||||
|
||||
// Write `src` tag
|
||||
//
|
||||
@ -122,11 +114,38 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
|
||||
// [src] link in the downstream documentation will actually come back to
|
||||
// this page, and this link will be auto-clicked. The `id` attribute is
|
||||
// used to find the link to auto-click.
|
||||
if cx.include_sources && !item.is_primitive() {
|
||||
write_srclink(cx, item, buf);
|
||||
}
|
||||
let src_href =
|
||||
if cx.include_sources && !item.is_primitive() { cx.src_href(item) } else { None };
|
||||
|
||||
buf.write_str("</span></h1>"); // out-of-band
|
||||
let path_components = if item.is_primitive() || item.is_keyword() {
|
||||
vec![]
|
||||
} else {
|
||||
let cur = &cx.current;
|
||||
let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
|
||||
cur.iter()
|
||||
.enumerate()
|
||||
.take(amt)
|
||||
.map(|(i, component)| PathComponent {
|
||||
path: "../".repeat(cur.len() - i - 1),
|
||||
name: component,
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
let item_vars = ItemVars {
|
||||
page: page,
|
||||
static_root_path: page.get_static_root_path(),
|
||||
typ: typ,
|
||||
name: &item.name.as_ref().unwrap().as_str(),
|
||||
item_type: &item.type_().to_string(),
|
||||
path_components: path_components,
|
||||
stability_since_raw: &stability_since_raw,
|
||||
src_href: src_href.as_deref(),
|
||||
};
|
||||
|
||||
let teractx = tera::Context::from_serialize(item_vars).unwrap();
|
||||
let heading = templates.render("print_item.html", &teractx).unwrap();
|
||||
buf.write_str(&heading);
|
||||
|
||||
match *item.kind {
|
||||
clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),
|
||||
|
20
src/librustdoc/html/render/templates.rs
Normal file
20
src/librustdoc/html/render/templates.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use std::error::Error as StdError;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
pub(crate) fn load() -> Result<tera::Tera, Error> {
|
||||
let mut templates = tera::Tera::default();
|
||||
|
||||
macro_rules! include_template {
|
||||
($file:literal, $fullpath:literal) => {
|
||||
templates.add_raw_template($file, include_str!($fullpath)).map_err(|e| Error {
|
||||
file: $file.into(),
|
||||
error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
|
||||
})?
|
||||
};
|
||||
}
|
||||
|
||||
include_template!("page.html", "../templates/page.html");
|
||||
include_template!("print_item.html", "../templates/print_item.html");
|
||||
Ok(templates)
|
||||
}
|
@ -70,8 +70,6 @@ crate static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg
|
||||
crate static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png");
|
||||
crate static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png");
|
||||
|
||||
crate static PAGE: &str = include_str!("templates/page.html");
|
||||
|
||||
/// The built-in themes given to every documentation site.
|
||||
crate mod themes {
|
||||
/// The "light" theme, selected by default when no setting is available. Used as the basis for
|
||||
|
26
src/librustdoc/html/templates/print_item.html
Normal file
26
src/librustdoc/html/templates/print_item.html
Normal file
@ -0,0 +1,26 @@
|
||||
<h1 class="fqn"> {#- -#}
|
||||
<span class="in-band"> {#- -#}
|
||||
{{-typ-}}
|
||||
{#- The breadcrumbs of the item path, like std::string -#}
|
||||
{%- for component in path_components -%}
|
||||
<a href="{{component.path | safe}}index.html">{{component.name}}</a>::<wbr>
|
||||
{%- endfor -%}
|
||||
<a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
|
||||
<button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
|
||||
<img src="{{static_root_path | safe}}clipboard{{page.resource_suffix}}.svg" {# -#}
|
||||
width="19" height="18" {# -#}
|
||||
alt="Copy item path"> {#- -#}
|
||||
</button> {#- -#}
|
||||
</span> {#- -#}
|
||||
<span class="out-of-band"> {#- -#}
|
||||
{{- stability_since_raw | safe -}}
|
||||
<span id="render-detail"> {#- -#}
|
||||
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
|
||||
[<span class="inner">−</span>] {#- -#}
|
||||
</a> {#- -#}
|
||||
</span> {#- -#}
|
||||
{%- if src_href -%}
|
||||
<a class="srclink" href="{{src_href | safe}}" title="goto source code">[src]</a>
|
||||
{%- endif -%}
|
||||
</span> {#- -#}
|
||||
</h1> {#- -#}
|
Loading…
Reference in New Issue
Block a user