Skip to content

Commit c5b80e6

Browse files
committed
bootstrap: add an initial stdarch test step
1 parent 5b61449 commit c5b80e6

File tree

10 files changed

+417
-73
lines changed

10 files changed

+417
-73
lines changed

src/bootstrap/src/core/build_steps/doc.rs

Lines changed: 233 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -621,12 +621,20 @@ impl Step for SharedAssets {
621621
}
622622
}
623623

624+
/// Document the standard library using `build_compiler`.
625+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
626+
enum StdWorkspace {
627+
Std,
628+
Stdarch,
629+
}
630+
624631
/// Document the standard library using `build_compiler`.
625632
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
626633
pub struct Std {
627634
build_compiler: Compiler,
628635
target: TargetSelection,
629636
format: DocumentationFormat,
637+
workspace: StdWorkspace,
630638
crates: Vec<String>,
631639
}
632640

@@ -636,7 +644,7 @@ impl Std {
636644
target: TargetSelection,
637645
format: DocumentationFormat,
638646
) -> Self {
639-
Std { build_compiler, target, format, crates: vec![] }
647+
Std { build_compiler, target, format, workspace: StdWorkspace::Std, crates: vec![] }
640648
}
641649
}
642650

@@ -645,29 +653,88 @@ impl Step for Std {
645653
type Output = PathBuf;
646654

647655
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
648-
run.crate_or_deps("sysroot").path("library")
656+
run.crate_or_deps("sysroot")
657+
.path("library")
658+
.path("library/stdarch")
659+
.path("library/stdarch/crates/core_arch")
660+
.path("library/stdarch/examples")
649661
}
650662

651663
fn is_default_step(builder: &Builder<'_>) -> bool {
652664
builder.config.docs
653665
}
654666

655667
fn make_run(run: RunConfig<'_>) {
656-
let crates = compile::std_crates_for_run_make(&run);
657-
let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false);
658-
if crates.is_empty() && target_is_no_std {
668+
let builder = run.builder;
669+
let build_compiler = builder.compiler_for_std(builder.top_stage);
670+
let format = if builder.config.cmd.json() {
671+
DocumentationFormat::Json
672+
} else {
673+
DocumentationFormat::Html
674+
};
675+
676+
if run.paths.is_empty() {
677+
let crates = compile::std_crates_for_run_make(&run);
678+
let target_is_no_std = builder.no_std(run.target).unwrap_or(false);
679+
if crates.is_empty() && target_is_no_std {
680+
return;
681+
}
682+
builder.ensure(Std {
683+
build_compiler,
684+
target: run.target,
685+
format,
686+
workspace: StdWorkspace::Std,
687+
crates,
688+
});
659689
return;
660690
}
661-
run.builder.ensure(Std {
662-
build_compiler: run.builder.compiler_for_std(run.builder.top_stage),
663-
target: run.target,
664-
format: if run.builder.config.cmd.json() {
665-
DocumentationFormat::Json
666-
} else {
667-
DocumentationFormat::Html
668-
},
669-
crates,
670-
});
691+
692+
let mut std_crates = Vec::new();
693+
let mut stdarch_crates = Vec::new();
694+
let mut stdarch_requested = false;
695+
696+
for pathset in &run.paths {
697+
let path = &pathset.assert_single_path().path;
698+
if path.starts_with("library/stdarch") {
699+
stdarch_requested = true;
700+
if let Some(krate) = builder.crate_paths.get(path) {
701+
stdarch_crates.push(krate.clone());
702+
}
703+
} else if let Some(krate) = builder.crate_paths.get(path) {
704+
std_crates.push(krate.clone());
705+
}
706+
}
707+
708+
std_crates.sort();
709+
std_crates.dedup();
710+
stdarch_crates.sort();
711+
stdarch_crates.dedup();
712+
713+
if stdarch_requested && stdarch_crates.is_empty() {
714+
stdarch_crates.push("core_arch".to_owned());
715+
if !builder.no_std(run.target).unwrap_or(false) {
716+
stdarch_crates.push("stdarch_examples".to_owned());
717+
}
718+
}
719+
720+
if !std_crates.is_empty() {
721+
builder.ensure(Std {
722+
build_compiler,
723+
target: run.target,
724+
format,
725+
workspace: StdWorkspace::Std,
726+
crates: std_crates,
727+
});
728+
}
729+
if !stdarch_crates.is_empty() {
730+
builder.ensure(Std {
731+
build_compiler,
732+
target: run.target,
733+
format,
734+
workspace: StdWorkspace::Stdarch,
735+
crates: stdarch_crates,
736+
});
737+
}
671738
}
672739

673740
/// Compile all standard library documentation.
@@ -676,14 +743,29 @@ impl Step for Std {
676743
/// dependencies. This is largely just a wrapper around `cargo doc`.
677744
fn run(self, builder: &Builder<'_>) -> Self::Output {
678745
let target = self.target;
679-
let crates = if self.crates.is_empty() {
680-
builder
681-
.in_tree_crates("sysroot", Some(target))
682-
.iter()
683-
.map(|c| c.name.to_string())
684-
.collect()
685-
} else {
686-
self.crates
746+
let crates = match self.workspace {
747+
StdWorkspace::Std => {
748+
if self.crates.is_empty() {
749+
builder
750+
.in_tree_crates("sysroot", Some(target))
751+
.iter()
752+
.map(|c| c.name.to_string())
753+
.collect()
754+
} else {
755+
self.crates
756+
}
757+
}
758+
StdWorkspace::Stdarch => {
759+
if self.crates.is_empty() {
760+
let mut crates = vec!["core_arch".to_owned()];
761+
if !builder.no_std(target).unwrap_or(false) {
762+
crates.push("stdarch_examples".to_owned());
763+
}
764+
crates
765+
} else {
766+
self.crates
767+
}
768+
}
687769
};
688770

689771
let out = match self.format {
@@ -693,45 +775,72 @@ impl Step for Std {
693775

694776
t!(fs::create_dir_all(&out));
695777

696-
if self.format == DocumentationFormat::Html {
778+
if self.format == DocumentationFormat::Html && self.workspace == StdWorkspace::Std {
697779
builder.ensure(SharedAssets { target: self.target });
698780
}
699781

700-
let index_page = builder
701-
.src
702-
.join("src/doc/index.md")
703-
.into_os_string()
704-
.into_string()
705-
.expect("non-utf8 paths are unsupported");
706-
let mut extra_args = match self.format {
707-
DocumentationFormat::Html => {
708-
vec!["--markdown-css", "rust.css", "--markdown-no-toc", "--index-page", &index_page]
709-
}
710-
DocumentationFormat::Json => vec!["--output-format", "json"],
711-
};
782+
match self.workspace {
783+
StdWorkspace::Std => {
784+
let index_page = builder
785+
.src
786+
.join("src/doc/index.md")
787+
.into_os_string()
788+
.into_string()
789+
.expect("non-utf8 paths are unsupported");
790+
let mut extra_args = match self.format {
791+
DocumentationFormat::Html => vec![
792+
"--markdown-css",
793+
"rust.css",
794+
"--markdown-no-toc",
795+
"--index-page",
796+
&index_page,
797+
],
798+
DocumentationFormat::Json => vec!["--output-format", "json"],
799+
};
712800

713-
if !builder.config.docs_minification {
714-
extra_args.push("--disable-minification");
715-
}
716-
// For `--index-page` and `--output-format=json`.
717-
extra_args.push("-Zunstable-options");
801+
if !builder.config.docs_minification {
802+
extra_args.push("--disable-minification");
803+
}
804+
// For `--index-page` and `--output-format=json`.
805+
extra_args.push("-Zunstable-options");
718806

719-
doc_std(builder, self.format, self.build_compiler, target, &out, &extra_args, &crates);
807+
doc_std(
808+
builder,
809+
self.format,
810+
self.build_compiler,
811+
target,
812+
&out,
813+
&extra_args,
814+
&crates,
815+
);
816+
}
817+
StdWorkspace::Stdarch => {
818+
doc_stdarch(builder, self.format, self.build_compiler, target, &out, &crates);
819+
}
820+
}
720821

721822
// Open if the format is HTML
722823
if let DocumentationFormat::Html = self.format {
723-
if builder.paths.iter().any(|path| path.ends_with("library")) {
724-
// For `x.py doc library --open`, open `std` by default.
725-
let index = out.join("std").join("index.html");
726-
builder.maybe_open_in_browser::<Self>(index);
727-
} else {
728-
for requested_crate in crates {
729-
if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
730-
let index = out.join(requested_crate).join("index.html");
824+
match self.workspace {
825+
StdWorkspace::Std => {
826+
if builder.paths.iter().any(|path| path.ends_with("library")) {
827+
// For `x.py doc library --open`, open `std` by default.
828+
let index = out.join("std").join("index.html");
731829
builder.maybe_open_in_browser::<Self>(index);
732-
break;
830+
} else {
831+
for requested_crate in crates {
832+
if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
833+
let index = out.join(requested_crate).join("index.html");
834+
builder.maybe_open_in_browser::<Self>(index);
835+
break;
836+
}
837+
}
733838
}
734839
}
840+
StdWorkspace::Stdarch => {
841+
let index = out.join(&crates[0]).join("index.html");
842+
builder.maybe_open_in_browser::<Self>(index);
843+
}
735844
}
736845
}
737846

@@ -740,13 +849,33 @@ impl Step for Std {
740849

741850
fn metadata(&self) -> Option<StepMetadata> {
742851
Some(
743-
StepMetadata::doc("std", self.target)
744-
.built_by(self.build_compiler)
745-
.with_metadata(format!("crates=[{}]", self.crates.join(","))),
852+
StepMetadata::doc(
853+
match self.workspace {
854+
StdWorkspace::Std => "std",
855+
StdWorkspace::Stdarch => "stdarch",
856+
},
857+
self.target,
858+
)
859+
.built_by(self.build_compiler)
860+
.with_metadata(format!("crates=[{}]", self.crates.join(","))),
746861
)
747862
}
748863
}
749864

865+
#[cfg(test)]
866+
impl Std {
867+
pub(crate) fn workspace_name(&self) -> &'static str {
868+
match self.workspace {
869+
StdWorkspace::Std => "std",
870+
StdWorkspace::Stdarch => "stdarch",
871+
}
872+
}
873+
874+
pub(crate) fn crate_names(&self) -> &[String] {
875+
&self.crates
876+
}
877+
}
878+
750879
/// Name of the crates that are visible to consumers of the standard library.
751880
/// Documentation for internal crates is handled by the rustc step, so internal crates will show
752881
/// up there.
@@ -829,6 +958,56 @@ fn doc_std(
829958
builder.cp_link_r(&out_dir, out);
830959
}
831960

961+
fn doc_stdarch(
962+
builder: &Builder<'_>,
963+
format: DocumentationFormat,
964+
build_compiler: Compiler,
965+
target: TargetSelection,
966+
out: &Path,
967+
requested_crates: &[String],
968+
) {
969+
let target_doc_dir_name =
970+
if format == DocumentationFormat::Json { "stdarch-json-doc" } else { "stdarch-doc" };
971+
let target_dir =
972+
builder.stage_out(build_compiler, Mode::Std).join(target).join(target_doc_dir_name);
973+
let out_dir = target_dir.join(target).join("doc");
974+
975+
let mut cargo = builder::Cargo::new(
976+
builder,
977+
build_compiler,
978+
Mode::Std,
979+
SourceType::InTree,
980+
target,
981+
Kind::Doc,
982+
);
983+
cargo.arg("--manifest-path").arg(builder.src.join("library/stdarch/Cargo.toml"));
984+
for krate in requested_crates {
985+
cargo.arg("-p").arg(krate);
986+
}
987+
cargo
988+
.arg("--no-deps")
989+
.arg("--target-dir")
990+
.arg(&*target_dir.to_string_lossy())
991+
.arg("-Zskip-rustdoc-fingerprint")
992+
.rustdocflag("--resource-suffix")
993+
.rustdocflag(&builder.version);
994+
995+
if format == DocumentationFormat::Json {
996+
cargo.arg("--output-format").arg("json").rustdocflag("-Zunstable-options");
997+
}
998+
999+
if builder.config.library_docs_private_items {
1000+
cargo.rustdocflag("--document-private-items").rustdocflag("--document-hidden-items");
1001+
}
1002+
1003+
let description =
1004+
format!("stdarch{} in {} format", crate_description(requested_crates), format.as_str());
1005+
let _guard = builder.msg(Kind::Doc, description, Mode::Std, build_compiler, target);
1006+
1007+
cargo.into_cmd().run(builder);
1008+
builder.cp_link_r(&out_dir, out);
1009+
}
1010+
8321011
/// Prepare a compiler that will be able to document something for `target` at `stage`.
8331012
pub fn prepare_doc_compiler(
8341013
builder: &Builder<'_>,

0 commit comments

Comments
 (0)