about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kugelman <john@kugelman.name>2021-10-10 10:15:16 -0400
committerGitHub <noreply@github.com>2021-10-10 10:15:16 -0400
commitecd7ea8a9c4abd3c3d0b23eda9e1a35bbe70215a (patch)
treed5e629669b27c4cd861aae8e5aff710b1ebcf334
parent58cc18c56b9d9422b376fdf5c51c20fb0e494e66 (diff)
parent9e8356c6adf119f983651d533d2b307544086cf9 (diff)
downloadrust-ecd7ea8a9c4abd3c3d0b23eda9e1a35bbe70215a.tar.gz
rust-ecd7ea8a9c4abd3c3d0b23eda9e1a35bbe70215a.zip
Merge branch 'rust-lang:master' into must-use-alloc-constructors
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs24
-rw-r--r--compiler/rustc_target/src/spec/mod.rs2
-rw-r--r--library/std/src/sys/unix/mod.rs3
-rw-r--r--library/std/src/sys/unix/thread.rs3
-rw-r--r--library/unwind/src/lib.rs4
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md66
-rw-r--r--src/librustdoc/html/render/context.rs12
-rw-r--r--src/librustdoc/html/render/mod.rs1
-rw-r--r--src/librustdoc/html/render/print_item.rs107
-rw-r--r--src/librustdoc/html/render/templates.rs20
-rw-r--r--src/librustdoc/html/static_files.rs2
-rw-r--r--src/librustdoc/html/templates/print_item.html26
15 files changed, 216 insertions, 61 deletions
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 5d68d2b77d4..1bc924d3b90 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -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);
             }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 0bdf70b3ec4..d0c7379c2d9 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -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
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs
new file mode 100644
index 00000000000..d230f77bde2
--- /dev/null
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs
@@ -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
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 5276da1ba5a..ff5dfa3f746 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -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`.
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 1c37f4ee498..2ba6c8d830e 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -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" {}
     }
 }
 
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 891f3413e91..6f4863057ab 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -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
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 25be9e7cc6c..e263780bf38 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -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"
 ))]
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 26fef889462..bbeab598f22 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -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` | ? |  |
diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
new file mode 100644
index 00000000000..b3a4275c6ee
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
@@ -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
+```
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index b99d2fe5aa0..011d3cfcf72 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -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
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 4f189159747..dc5aec3b084 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -31,6 +31,7 @@ mod tests;
 mod context;
 mod print_item;
 mod span_map;
+mod templates;
 mod write_shared;
 
 crate use context::*;
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index cab3fca708b..4cfc57ac995 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -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\">&#x2212;</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 };
+
+    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(),
+    };
 
-    buf.write_str("</span></h1>"); // out-of-band
+    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),
diff --git a/src/librustdoc/html/render/templates.rs b/src/librustdoc/html/render/templates.rs
new file mode 100644
index 00000000000..d1f18239447
--- /dev/null
+++ b/src/librustdoc/html/render/templates.rs
@@ -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)
+}
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 6f3d08ea655..ccc25e6cc49 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -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
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
new file mode 100644
index 00000000000..5a468f3cc1e
--- /dev/null
+++ b/src/librustdoc/html/templates/print_item.html
@@ -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">&#x2212;</span>] {#- -#}
+            </a> {#- -#}
+        </span> {#- -#}
+        {%- if src_href -%}
+        <a class="srclink" href="{{src_href | safe}}" title="goto source code">[src]</a>
+        {%- endif -%}
+    </span> {#- -#}
+</h1> {#- -#}