Skip to content

Commit 70bea01

Browse files
committed
Don't build libstd as a dylib
This commit forcibly prevents Cargo from building the `std` crate as a `dylib`, even though libstd upstream lists a `dylib` crate type. We ideally want a first-class feature for doing this one day, but for now we can just hack around with the manifests to ensure that the `dylib` crate type never shows up. Note that this is only supported for libstd, and it's also all part of the unstable details of building std. Closes rust-lang/wg-cargo-std-aware#35
1 parent 651b1c5 commit 70bea01

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

src/cargo/core/manifest.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ impl Manifest {
463463
pub fn targets(&self) -> &[Target] {
464464
&self.targets
465465
}
466+
pub fn targets_mut(&mut self) -> &mut [Target] {
467+
&mut self.targets
468+
}
466469
pub fn version(&self) -> &Version {
467470
self.package_id().version()
468471
}
@@ -752,6 +755,9 @@ impl Target {
752755
pub fn kind(&self) -> &TargetKind {
753756
&self.kind
754757
}
758+
pub fn kind_mut(&mut self) -> &mut TargetKind {
759+
&mut self.kind
760+
}
755761
pub fn tested(&self) -> bool {
756762
self.tested
757763
}

src/cargo/core/package.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,15 @@ impl<'cfg> PackageSet<'cfg> {
464464
let other_sources = set.sources.into_inner();
465465
sources.add_source_map(other_sources);
466466
}
467+
468+
/// Get mutable access to an already downloaded package, if it's already
469+
/// downoaded and it's part of this set. Does not actually attempt to
470+
/// download anything if it's not already downloaded.
471+
pub fn lookup_mut(&mut self, id: PackageId) -> Option<&mut Package> {
472+
self.packages
473+
.get_mut(&id)
474+
.and_then(|cell| cell.borrow_mut())
475+
}
467476
}
468477

469478
// When dynamically linked against libcurl, we want to ignore some failures

src/cargo/ops/cargo_compile.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::core::compiler::{CompileMode, Kind, Unit};
3535
use crate::core::compiler::{DefaultExecutor, Executor, UnitInterner};
3636
use crate::core::profiles::{Profiles, UnitFor};
3737
use crate::core::resolver::{Resolve, ResolveOpts};
38-
use crate::core::{Package, Target};
38+
use crate::core::{LibKind, Package, PackageSet, Target};
3939
use crate::core::{PackageId, PackageIdSpec, TargetKind, Workspace};
4040
use crate::ops;
4141
use crate::util::config::Config;
@@ -315,7 +315,8 @@ pub fn compile_ws<'a>(
315315
// requested_target to an enum, or some other approach.
316316
failure::bail!("-Zbuild-std requires --target");
317317
}
318-
let (std_package_set, std_resolve) = standard_lib::resolve_std(ws, crates)?;
318+
let (mut std_package_set, std_resolve) = standard_lib::resolve_std(ws, crates)?;
319+
remove_dylib_crate_type(&mut std_package_set)?;
319320
packages.add_set(std_package_set);
320321
Some(std_resolve)
321322
} else {
@@ -988,3 +989,35 @@ fn filter_targets<'a>(
988989
}
989990
proposals
990991
}
992+
993+
/// When using `-Zbuild-std` we're building the standard library, but a
994+
/// technical detail of the standard library right now is that it builds itself
995+
/// as both an `rlib` and a `dylib`. We don't actually want to really publicize
996+
/// the `dylib` and in general it's a pain to work with, so when building libstd
997+
/// we want to remove the `dylib` crate type.
998+
///
999+
/// Cargo doesn't have a fantastic way of doing that right now, so let's hack
1000+
/// around it a bit and (ab)use the fact that we have mutable access to
1001+
/// `PackageSet` here to rewrite downloaded packages. We iterate over all `path`
1002+
/// packages (which should download immediately and not actually cause blocking
1003+
/// here) and edit their manifests to only list one `LibKind` for an `Rlib`.
1004+
fn remove_dylib_crate_type(set: &mut PackageSet<'_>) -> CargoResult<()> {
1005+
let ids = set
1006+
.package_ids()
1007+
.filter(|p| p.source_id().is_path())
1008+
.collect::<Vec<_>>();
1009+
set.get_many(ids.iter().cloned())?;
1010+
1011+
for id in ids {
1012+
let pkg = set.lookup_mut(id).expect("should be downloaded now");
1013+
1014+
for target in pkg.manifest_mut().targets_mut() {
1015+
if let TargetKind::Lib(crate_types) = target.kind_mut() {
1016+
crate_types.truncate(0);
1017+
crate_types.push(LibKind::Rlib);
1018+
}
1019+
}
1020+
}
1021+
1022+
Ok(())
1023+
}

0 commit comments

Comments
 (0)