Change:
Problem I'm working in Rust on a Pinebook Pro running ARM64 Debian GNU/Linux. I've been Rusty for a few years now, and one of my favorite features is the extensive offline documentation. However, on this computer: gives an error message instead of documentation; the documentation doesn't appear to be present; and attempts to explicitly install the documentation have all failed. Steps Rust the usual way on ARM64 Linux (pipe a shell) (it fails) (it fails) (it fails) I installed Rust about a month ago and noticed the lack of documentation then, it's only now that it's become a major problem for me. I attempted steps 2-4 just now after , rather than after a completely fresh install. Notes Output of : Output of : Output of (even though rust-lang/rustup should be in effect?): Output of :
I can confirm the behaviour you're stating - that aarch64-unknown-linux-gnu lacks the component. The stable channel is only offering for the tier one platforms right now. I'm not sure if that's intentional, but it's not 's fault.
I'm not sure whose responsibility it is to decide which platforms get the component offered to them, but clearly would like them available on aarch64 linux.
This issue is not ARM only, of all non tier1 platforms is disable on dist CI builders in If the the documentations have no difference on each linux target, we can let download from EDIT A workaround is install a toolchain in rustup and create a soft link in
Given the relatively low demand for non-tier-1 doc packages, I would be happy if rustup were just a little smarter about this. Ideally, ought to say something like "documentation is not built for non-tier-1 targets". Perhaps it could also be extended to automatically download and use the documentation for an "equivalent" tier 1 platform, or maybe to steer the user toward instructions for building their own documentation package.
In theory, if the channel manifest were extended to contain enough information for rustup to know that then sure it'd be possible. However platforms move between tiers of support without necessarily needing to be involved so it wouldn't be part of itself. If you make that link, there's the possibility will get confused in the future, just to warn you.
I don't understand, why not just build all the documentation (rustdoc & the books) once and then share it between all triples? I guess documentation is same for all architectures.
There are differences. The big one I know about is CPU-specific inlines for SIMD and such. 's size also differs between 32- and 64-bit architectures. Both of these are reflected in the documentation.
A year later, with Apple M1 bringing ARM to more developer's desktops, this is a more pressing issue.
At some point in the last year, became a tier 1 platform, which would have solved this problem for me personally, but not for people on other platforms that are still tier 2 or more. But now, against everyone's predictions, I find myself using an machine. Which is tier 2. Which means I'm in the same boat again. Heh. I assume it's not an easy process to just build the docs myself on my own machine?

Discussion:
- name: dist-aarch64-apple env: SCRIPT: "./x.py dist --stage 2" <del> RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --host=aarch64-apple-darwin --target=aarch64-apple-darwin --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" </del> <ins> RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --host=aarch64-apple-darwin --target=aarch64-apple-darwin --enable-full-tools --enable-sanitizers --enable-profiler --disable-docs --set rust.jemalloc --set llvm.ninja=false" </ins> RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 USE_XCODE_CLANG: 1 MACOSX_DEPLOYMENT_TARGET: 11.0

}; prepare("rustc"); prepare("cargo"); <del> prepare("rust-docs"); </del> prepare("rust-std"); prepare("rust-analysis"); prepare("clippy"); <del> for tool in &["rust-demangler", "rls", "rust-analyzer", "miri"] { </del> <ins> for tool in &["rust-docs", "rust-demangler", "rls", "rust-analyzer", "miri"] { </ins> if built_tools.contains(tool) { prepare(tool); }

--enable-full-tools --enable-sanitizers --enable-profiler <ins> --disable-docs </ins> --set rust.jemalloc --set llvm.ninja=false RUSTC_RETRY_LINKER_ON_SEGFAULT: 1

`path/to/output` with: ``` <del> $ cargo +nightly run path/to/dist path/to/output 1970-01-01 http://example.com  CHANNEL VERSION </del> <ins> $ cargo +nightly run path/to/dist path/to/output 1970-01-01 http://example.com CHANNEL </ins> ``` Remember to replace `CHANNEL` with the channel you produced dist artifacts of

"x86_64-unknown-hermit", ]; <del> static DOCS_TARGETS: &[&str] = &[ "aarch64-unknown-linux-gnu", "i686-apple-darwin", "i686-pc-windows-gnu", "i686-pc-windows-msvc", "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-pc-windows-gnu", "x86_64-pc-windows-msvc", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", </del> <ins> /// This allows the manifest to contain rust-docs for hosts that don't build /// docs. /// /// Tuples of `(host_partial, host_instead)`. If the host does not have the /// rust-docs component available, then if the host name contains /// `host_partial`, it will use the docs from `host_instead` instead. /// /// The order here matters, more specific entries should be first. static DOCS_FALLBACK: &[(&str, &str)] = &[ ("-apple-", "x86_64-apple-darwin"), ("aarch64", "aarch64-unknown-linux-gnu"), ("arm-", "aarch64-unknown-linux-gnu"), ("", "x86_64-unknown-linux-gnu"), </ins> ]; static MSI_INSTALLERS: &[&str] = &[

} fn add_packages_to(&mut self, manifest: &mut Manifest) { <del> let mut package = |name, targets| self.package(name, &mut manifest.pkg, targets); package("rustc", HOSTS); package("rustc-dev", HOSTS); package("reproducible-artifacts", HOSTS); package("rustc-docs", HOSTS); package("cargo", HOSTS); package("rust-mingw", MINGW); package("rust-std", TARGETS); package("rust-docs", DOCS_TARGETS); package("rust-src", &["*"]); package("rls-preview", HOSTS); package("rust-analyzer-preview", HOSTS); package("clippy-preview", HOSTS); package("miri-preview", HOSTS); package("rustfmt-preview", HOSTS); package("rust-analysis", TARGETS); package("llvm-tools-preview", TARGETS); </del> <ins> macro_rules! package { ($name:expr, $targets:expr) => { self.package($name, &mut manifest.pkg, $targets, &[]) }; } package!("rustc", HOSTS); package!("rustc-dev", HOSTS); package!("reproducible-artifacts", HOSTS); package!("rustc-docs", HOSTS); package!("cargo", HOSTS); package!("rust-mingw", MINGW); package!("rust-std", TARGETS); self.package("rust-docs", &mut manifest.pkg, HOSTS, DOCS_FALLBACK); package!("rust-src", &["*"]); package!("rls-preview", HOSTS); package!("rust-analyzer-preview", HOSTS); package!("clippy-preview", HOSTS); package!("miri-preview", HOSTS); package!("rustfmt-preview", HOSTS); package!("rust-analysis", TARGETS); package!("llvm-tools-preview", TARGETS); </ins> } fn add_artifacts_to(&mut self, manifest: &mut Manifest) {

.extend(pkgs.iter().map(|s| (*s).to_owned())); } <del> fn package(&mut self, pkgname: &str, dst: &mut BTreeMap<String, Package>, targets: &[&str]) { </del> <ins> fn package( &mut self, pkgname: &str, dst: &mut BTreeMap<String, Package>, targets: &[&str], fallback: &[(&str, &str)], ) { </ins> let version_info = self .versions .version(&PkgType::from_component(pkgname))

is_present = false; // Pretend the component is entirely missing. } <ins> macro_rules! tarball_name { ($target_name:expr) => { self.versions.tarball_name(&PkgType::from_component(pkgname), $target_name).unwrap() }; } let mut target_from_compressed_tar = |target_name| { let target = Target::from_compressed_tar(self, &tarball_name!(target_name)); if target.available { return target; } for (substr, fallback_target) in fallback { if target_name.contains(substr) { let t = Target::from_compressed_tar(self, &tarball_name!(fallback_target)); // Fallbacks must always be available. assert!(t.available); return t; } } Target::unavailable() }; </ins> let targets = targets .iter() .map(|name| { let target = if is_present { <del> let filename = self .versions .tarball_name(&PkgType::from_component(pkgname), name) .unwrap(); Target::from_compressed_tar(self, &filename) </del> <ins> target_from_compressed_tar(name) </ins> } else { // If the component is not present for this build add it anyway but mark it as // unavailable -- this way rustup won't allow upgrades without --force

} pub(crate) fn archive_name( <del> &mut self, </del> <ins> &self, </ins> package: &PkgType, target: &str, extension: &str,

} } <del> pub(crate) fn tarball_name( &mut self, package: &PkgType, target: &str, ) -> Result<String, Error> { </del> <ins> pub(crate) fn tarball_name(&self, package: &PkgType, target: &str) -> Result<String, Error> { </ins> self.archive_name(package, target, "tar.gz") }