Skip to content

Commit 7629bd8

Browse files
committed
fix the actual bug
- only skip `--target` for proc-macros - don't try build non-host targets for proc-macros, since they're not supported anyway.
1 parent 8772e1a commit 7629bd8

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

crates/metadata/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,26 @@ impl Metadata {
197197
/// If `include_default_targets` is `true` and `targets` is unset, this also includes
198198
/// [`DEFAULT_TARGETS`]. Otherwise, if `include_default_targets` is `false` and `targets`
199199
/// is unset, `other_targets` will be empty.
200+
///
201+
/// All of the above is ignored for proc-macros, which are always only compiled for the host.
200202
pub fn targets(&self, include_default_targets: bool) -> BuildTargets<'_> {
203+
// Proc macros can only be compiled for the host, so just completely ignore any configured targets.
204+
// It would be nice to warn about this somehow ...
205+
if self.proc_macro {
206+
return BuildTargets {
207+
default_target: HOST_TARGET,
208+
other_targets: HashSet::default(),
209+
};
210+
}
211+
201212
let default_target = self
202213
.default_target
203214
.as_deref()
204215
// Use the first element of `targets` if `default_target` is unset and `targets` is non-empty
205216
.or_else(|| {
206217
self.targets
207218
.as_ref()
208-
.and_then(|targets| targets.iter().next().map(String::as_str))
219+
.and_then(|targets| targets.first().map(String::as_str))
209220
})
210221
.unwrap_or(HOST_TARGET);
211222

src/docbuilder/rustwide_builder.rs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,11 @@ impl RustwideBuilder {
350350
if res.result.successful {
351351
if let Some(name) = res.cargo_metadata.root().library_name() {
352352
let host_target = build.host_target_dir();
353-
has_docs = host_target.join("doc").join(name).is_dir();
353+
has_docs = if metadata.proc_macro {
354+
host_target.join("doc").join(name).is_dir()
355+
} else {
356+
host_target.join("doc").join(HOST_TARGET).join(name).is_dir()
357+
}
354358
}
355359
}
356360

@@ -656,7 +660,16 @@ impl RustwideBuilder {
656660
if let Some(cpu_limit) = self.config.build_cpu_limit {
657661
cargo_args.push(format!("-j{}", cpu_limit));
658662
}
659-
if target != HOST_TARGET {
663+
// Cargo has a series of frightening bugs around cross-compiling proc-macros:
664+
// - Passing `--target` causes RUSTDOCFLAGS to fail to be passed 🤦
665+
// - Passing `--target` will *create* `target/{target-name}/doc` but will put the docs in `target/doc` anyway
666+
// As a result, it's not possible for us to support cross-compiling proc-macros.
667+
// However, all these caveats unfortunately still apply when `{target-name}` is the host.
668+
// So, only pass `--target` for crates that aren't proc-macros.
669+
//
670+
// Originally, this had a simpler check `target != HOST_TARGET`, but *that* was buggy when `HOST_TARGET` wasn't the same as the default target.
671+
// Rather than trying to keep track of it all, only special case proc-macros, which are what we actually care about.
672+
if !metadata.proc_macro {
660673
cargo_args.push("--target".into());
661674
cargo_args.push(target.into());
662675
};
@@ -935,4 +948,66 @@ mod tests {
935948
Ok(())
936949
})
937950
}
951+
952+
#[test]
953+
#[ignore]
954+
fn test_proc_macro() {
955+
wrapper(|env| {
956+
let crate_ = "thiserror-impl";
957+
let version = "1.0.26";
958+
let mut builder = RustwideBuilder::init(env).unwrap();
959+
assert!(builder.build_package(crate_, version, PackageKind::CratesIo)?);
960+
961+
let storage = env.storage();
962+
963+
// doc archive exists
964+
let doc_archive = rustdoc_archive_path(crate_, version);
965+
assert!(storage.exists(&doc_archive)?);
966+
967+
// source archive exists
968+
let source_archive = source_archive_path(crate_, version);
969+
assert!(storage.exists(&source_archive)?);
970+
971+
Ok(())
972+
});
973+
}
974+
975+
#[test]
976+
#[ignore]
977+
fn test_cross_compile_non_host_default() {
978+
wrapper(|env| {
979+
let crate_ = "xingapi";
980+
let version = "0.3.3";
981+
let mut builder = RustwideBuilder::init(env).unwrap();
982+
assert!(builder.build_package(crate_, version, PackageKind::CratesIo)?);
983+
984+
let storage = env.storage();
985+
986+
// doc archive exists
987+
let doc_archive = rustdoc_archive_path(crate_, version);
988+
assert!(storage.exists(&doc_archive)?);
989+
990+
// source archive exists
991+
let source_archive = source_archive_path(crate_, version);
992+
assert!(storage.exists(&source_archive)?);
993+
994+
let target = "x86_64-unknown-linux-gnu";
995+
let crate_path = crate_.replace("-", "_");
996+
let target_docs_present = storage.exists_in_archive(
997+
&doc_archive,
998+
&format!("{}/{}/index.html", target, crate_path),
999+
)?;
1000+
1001+
let web = env.frontend();
1002+
let target_url = format!(
1003+
"/{}/{}/{}/{}/index.html",
1004+
crate_, version, target, crate_path
1005+
);
1006+
1007+
assert!(target_docs_present);
1008+
assert_success(&target_url, web)?;
1009+
1010+
Ok(())
1011+
});
1012+
}
9381013
}

0 commit comments

Comments
 (0)