add some info

This commit is contained in:
nora 2024-02-06 19:54:00 +01:00
parent 0db7e723a4
commit 33748193aa
5 changed files with 372 additions and 1 deletions

146
Cargo.lock generated
View file

@ -2,6 +2,152 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "glob-match"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d"
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "indexmap"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "memchr"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.196"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.196"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_spanned"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
"serde",
]
[[package]]
name = "syn"
version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "target-docs" name = "target-docs"
version = "0.1.0" version = "0.1.0"
dependencies = [
"glob-match",
"serde",
"toml",
]
[[package]]
name = "toml"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "winnow"
version = "0.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cad8365489051ae9f054164e459304af2e7e9bb407c958076c8bf4aef52da5"
dependencies = [
"memchr",
]

View file

@ -6,3 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
glob-match = "0.2.1"
serde = { version = "1.0.196", features = ["derive"] }
toml = "0.8.10"

23
README.md Normal file
View file

@ -0,0 +1,23 @@
# target tier docs experiment
Experiment with automatically generating target tier docs.
## Problems
Currenly, the [target tier docs](https://doc.rust-lang.org/rustc/platform-support.html) are hard to navigate.
If you want to find information about a specific target, you first need to do some glob-search yourself and then also hope
that the target actually exists. This is super annoying (`:(`). Additionally, some targets are completely missing and there
is no reason to believe that the documentation won't suddenly start being out of date.
Pages are also inconsistent about which sections exist and which ones don't.
## Solution
Enter: adding yet another preprocessing step.
By adding yet another preprocessing step, we can solve all these problems.
- Have a *dedicated* page for *every single* target including information about maintainers etc.
This makes it super easy to find things when there are problems.
- Ensure that no target is completely undocumented, at least having a stub page pointing out the undocumentedness
- Error when there is documentation that is not needed anymore, for example a removed target
- Still keep the nice and easy-to-organize glob structure in the source
- Use a unified structure for all the pages

View file

@ -1,8 +1,75 @@
use std::io;
struct TargetDocs {
name: String,
maintainers: Vec<String>,
requirements: Option<String>,
testing: Option<String>,
building_the_target: Option<String>,
cross_compilation: Option<String>,
building_rust_programs: Option<String>,
tier: u8,
}
fn render_target_md(target: &TargetDocs) -> String {
let mut doc = format!("# {}\n**Tier: {}**", target.name, target.tier);
let maintainers_str = if target.maintainers.is_empty() {
"\n## Maintainers\nThis target does not have any maintainers!\n".to_owned()
} else {
format!(
"\n## Maintainers\nThis target is maintained by:\n{}\n",
target
.maintainers
.iter()
.map(|maintainer| {
let maintainer = if maintainer.starts_with('@') && !maintainer.contains(" ") {
format!(
"[@{0}](https://github.com/{0})",
maintainer.strip_prefix("@").unwrap()
)
} else {
maintainer.to_owned()
};
format!("- {maintainer}")
})
.collect::<Vec<_>>()
.join("\n")
)
};
doc.push_str(&maintainers_str);
let mut section = |value: &Option<String>, name| {
let section_str = match value {
Some(value) => format!("## {name}\n{value}\n"),
None => format!("## {name}\nUnknown.\n"),
};
doc.push_str(&section_str)
};
section(&target.requirements, "Requirements");
section(&target.testing, "Testing");
section(&target.building_the_target, "Building");
section(&target.cross_compilation, "Cross Compilation");
section(&target.building_rust_programs, "Building Rust Programs");
doc
}
fn main() { fn main() {
let targets = include_str!("../targets.txt").lines().collect::<Vec<_>>(); let targets = include_str!("../targets.txt").lines().collect::<Vec<_>>();
match std::fs::create_dir("targets/src") {
Ok(()) => {}
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {}
e @ _ => e.unwrap(),
}
for target in &targets { for target in &targets {
let doc = format!("# {target}\nthis is a target."); let doc = render_target_md(&target_info(target));
std::fs::write(format!("targets/src/{target}.md"), doc).unwrap(); std::fs::write(format!("targets/src/{target}.md"), doc).unwrap();
} }
@ -11,6 +78,7 @@ fn main() {
format!( format!(
"\ "\
# All targets # All targets
- [Info About This Thing](./information.md)
{} {}
", ",
targets targets
@ -21,5 +89,87 @@ fn main() {
), ),
) )
.unwrap(); .unwrap();
std::fs::write("targets/src/information.md", "\
# platform support generated
This is an experiment of what target tier documentation could look like.
See https://github.com/Nilstrieb/target-tier-docs-experiment for the source.
").unwrap();
println!("generated some target docs :3"); println!("generated some target docs :3");
} }
#[derive(Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct TargetMaintainerTable {
target: Vec<TargetMaintainerEntry>,
}
#[derive(Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct TargetMaintainerEntry {
pattern: String,
tier: Option<u8>,
requirements: Option<String>,
testing: Option<String>,
building_the_target: Option<String>,
cross_compilation: Option<String>,
building_rust_programs: Option<String>,
maintainers: Vec<String>,
}
fn target_info(target: &str) -> TargetDocs {
let file = include_str!("../target_info.toml");
let table = toml::from_str::<TargetMaintainerTable>(file).unwrap();
let mut tier = None;
let mut maintainers = Vec::new();
let mut requirements = None;
let mut testing = None;
let mut building_the_target = None;
let mut cross_compilation = None;
let mut building_rust_programs = None;
for target_pattern in table.target {
if glob_match::glob_match(&target_pattern.pattern, target) {
maintainers.extend_from_slice(&target_pattern.maintainers);
fn set_once<T>(
target: &str,
pattern_value: Option<T>,
to_insert: &mut Option<T>,
name: &str,
) {
if let Some(pattern_value) = pattern_value {
if to_insert.is_some() {
panic!("target {target} inherits a {name} from multiple patterns, create a more specific pattern and add it there");
}
*to_insert = Some(pattern_value);
}
}
#[rustfmt::skip]
{
set_once(target, target_pattern.tier, &mut tier, "tier");
set_once(target, target_pattern.requirements, &mut requirements, "requirements");
set_once(target, target_pattern.testing, &mut testing, "testing");
set_once(target, target_pattern.building_the_target, &mut building_the_target, "building_the_target");
set_once(target, target_pattern.cross_compilation, &mut cross_compilation, "cross_compilation");
set_once(target, target_pattern.building_rust_programs, &mut building_rust_programs, "building_rust_programs");
};
}
}
// we should give errors for unused patterns.
TargetDocs {
name: target.to_owned(),
maintainers,
requirements,
testing,
building_the_target,
cross_compilation,
building_rust_programs,
// tier: tier.expect(&format!("no tier found for target {target}")),
tier: tier.unwrap_or(0),
}
}

49
target_info.toml Normal file
View file

@ -0,0 +1,49 @@
[[target]]
pattern = "*-apple-tvos"
tier = 2
maintainers = ["@thomcc"]
requirements = """
These targets are cross-compiled. You will need appropriate versions of Xcode and the SDKs for tvOS (AppleTVOS.sdk) and/or the tvOS Simulator (AppleTVSimulator.sdk) to build a toolchain and target these platforms.
The targets support most (see below) of the standard library including the allocator to the best of my knowledge, however they are very new, not yet well-tested, and it is possible that there are various bugs.
In theory we support back to tvOS version 7.0, although the actual minimum version you can target may be newer than this, for example due to the versions of Xcode and your SDKs.
As with the other Apple targets, rustc respects the common environment variables used by Xcode to configure this, in this case TVOS_DEPLOYMENT_TARGET.
Incompletely supported library functionality
As mentioned, "most" of the standard library is supported, which means that some portions are known to be unsupported. The following APIs are currently known to have missing or incomplete support:
std::process::Command's API will return an error if it is configured in a manner which cannot be performed using posix_spawn
-- this is because the more flexible fork/exec-based approach is prohibited on these platforms in favor of posix_spawn{,p}
(which still probably will get you rejected from app stores, so is likely sideloading-only).
A concrete set of cases where this will occur is difficult to enumerate (and would quickly become stale), but in some cases it may be worked around by tweaking the manner in which Command is invoked.
"""
testing = """
There is no support for running the Rust or standard library testsuite on tvOS or the simulators at the moment. Testing has mostly been done manually with builds of static libraries called from Xcode or a simulator.
It hopefully will be possible to improve this in the future.
"""
cross_compilation = """
This target can be cross-compiled from x86_64 or aarch64 macOS hosts.
Other hosts are not supported for cross-compilation, but might work when also providing the required Xcode SDK.
"""
[[target]]
pattern = "powerpc64-ibm-aix"
tier = 3
maintainers = [
"QIU Chaofan `qiucofan@cn.ibm.com`, https://github.com/ecnelises",
"Kai LUO, `lkail@cn.ibm.com`, https://github.com/bzEq",
]
requirements = """
This target supports host tools, std and alloc. This target cannot be cross-compiled as for now, mainly because of the unavailability of system linker on other platforms.
Binary built for this target is expected to run on Power7 or newer CPU, and AIX 7.2 or newer version.
Binary format of this platform is XCOFF. Archive file format is 'AIX big format'.
"""
testing = """
This target supports running test suites natively, but it's not available to cross-compile and execute in emulator.
"""