Skip to content

Don't build libstd as a dylib #7353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,9 @@ impl Manifest {
pub fn targets(&self) -> &[Target] {
&self.targets
}
pub fn targets_mut(&mut self) -> &mut [Target] {
&mut self.targets
}
pub fn version(&self) -> &Version {
self.package_id().version()
}
Expand Down Expand Up @@ -752,6 +755,9 @@ impl Target {
pub fn kind(&self) -> &TargetKind {
&self.kind
}
pub fn kind_mut(&mut self) -> &mut TargetKind {
&mut self.kind
}
pub fn tested(&self) -> bool {
self.tested
}
Expand Down
9 changes: 9 additions & 0 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,15 @@ impl<'cfg> PackageSet<'cfg> {
let other_sources = set.sources.into_inner();
sources.add_source_map(other_sources);
}

/// Get mutable access to an already downloaded package, if it's already
/// downoaded and it's part of this set. Does not actually attempt to
/// download anything if it's not already downloaded.
pub fn lookup_mut(&mut self, id: PackageId) -> Option<&mut Package> {
self.packages
.get_mut(&id)
.and_then(|cell| cell.borrow_mut())
}
}

// When dynamically linked against libcurl, we want to ignore some failures
Expand Down
37 changes: 35 additions & 2 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::core::compiler::{CompileMode, Kind, Unit};
use crate::core::compiler::{DefaultExecutor, Executor, UnitInterner};
use crate::core::profiles::{Profiles, UnitFor};
use crate::core::resolver::{Resolve, ResolveOpts};
use crate::core::{Package, Target};
use crate::core::{LibKind, Package, PackageSet, Target};
use crate::core::{PackageId, PackageIdSpec, TargetKind, Workspace};
use crate::ops;
use crate::util::config::Config;
Expand Down Expand Up @@ -315,7 +315,8 @@ pub fn compile_ws<'a>(
// requested_target to an enum, or some other approach.
failure::bail!("-Zbuild-std requires --target");
}
let (std_package_set, std_resolve) = standard_lib::resolve_std(ws, crates)?;
let (mut std_package_set, std_resolve) = standard_lib::resolve_std(ws, crates)?;
remove_dylib_crate_type(&mut std_package_set)?;
packages.add_set(std_package_set);
Some(std_resolve)
} else {
Expand Down Expand Up @@ -988,3 +989,35 @@ fn filter_targets<'a>(
}
proposals
}

/// When using `-Zbuild-std` we're building the standard library, but a
/// technical detail of the standard library right now is that it builds itself
/// as both an `rlib` and a `dylib`. We don't actually want to really publicize
/// the `dylib` and in general it's a pain to work with, so when building libstd
/// we want to remove the `dylib` crate type.
///
/// Cargo doesn't have a fantastic way of doing that right now, so let's hack
/// around it a bit and (ab)use the fact that we have mutable access to
/// `PackageSet` here to rewrite downloaded packages. We iterate over all `path`
/// packages (which should download immediately and not actually cause blocking
/// here) and edit their manifests to only list one `LibKind` for an `Rlib`.
fn remove_dylib_crate_type(set: &mut PackageSet<'_>) -> CargoResult<()> {
let ids = set
.package_ids()
.filter(|p| p.source_id().is_path())
.collect::<Vec<_>>();
set.get_many(ids.iter().cloned())?;

for id in ids {
let pkg = set.lookup_mut(id).expect("should be downloaded now");

for target in pkg.manifest_mut().targets_mut() {
if let TargetKind::Lib(crate_types) = target.kind_mut() {
crate_types.truncate(0);
crate_types.push(LibKind::Rlib);
}
}
}

Ok(())
}