Skip to content
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

RFC First cut support for sandboxing procmacros with wasm #7297

Closed
wants to merge 2 commits into from
Closed
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
23 changes: 21 additions & 2 deletions src/cargo/core/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use crate::util::{profile, Cfg, Config, Rustc};
mod target_info;
pub use self::target_info::{FileFlavor, TargetInfo};

pub const HOST_SANDBOX_TARGET: &str = "wasm32-unknown-unknown";

/// The build context, containing all information about a build task.
///
/// It is intended that this is mostly static information. Stuff that mutates
Expand All @@ -38,10 +40,13 @@ pub struct BuildContext<'a, 'cfg> {
pub rustc: Rustc,
/// Build information for the host arch.
pub host_config: TargetConfig,
/// Build information for the host sandbox arch (wasm).
pub host_sandbox_config: TargetConfig,
/// Build information for the target.
pub target_config: TargetConfig,
pub target_info: TargetInfo,
pub host_info: TargetInfo,
pub host_sandbox_info: TargetInfo,
pub units: &'a UnitInterner<'a>,
}

Expand All @@ -59,18 +64,21 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
let rustc = config.load_global_rustc(Some(ws))?;

let host_config = TargetConfig::new(config, &rustc.host)?;
let host_sandbox_config = TargetConfig::new(config, HOST_SANDBOX_TARGET)?;
let target_config = match build_config.requested_target.as_ref() {
Some(triple) => TargetConfig::new(config, triple)?,
None => host_config.clone(),
};
let (host_info, target_info) = {
let (host_info, host_sandbox_info, target_info) = {
let _p = profile::start("BuildContext::probe_target_info");
debug!("probe_target_info");
let host_info =
TargetInfo::new(config, &build_config.requested_target, &rustc, Kind::Host)?;
let host_sandbox_info =
TargetInfo::new(config, &build_config.requested_target, &rustc, Kind::HostSandbox)?;
let target_info =
TargetInfo::new(config, &build_config.requested_target, &rustc, Kind::Target)?;
(host_info, target_info)
(host_info, host_sandbox_info, target_info)
};

Ok(BuildContext {
Expand All @@ -82,7 +90,9 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
target_config,
target_info,
host_config,
host_sandbox_config,
host_info,
host_sandbox_info,
build_config,
profiles,
extra_compiler_args,
Expand Down Expand Up @@ -111,6 +121,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
};
let (name, info) = match kind {
Kind::Host => (self.host_triple(), &self.host_info),
Kind::HostSandbox => (self.host_sandbox_triple(), &self.host_sandbox_info),
Kind::Target => (self.target_triple(), &self.target_info),
};
platform.matches(name, info.cfg())
Expand All @@ -130,6 +141,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
pub fn cfg(&self, kind: Kind) -> &[Cfg] {
let info = match kind {
Kind::Host => &self.host_info,
Kind::HostSandbox => &self.host_sandbox_info,
Kind::Target => &self.target_info,
};
info.cfg()
Expand All @@ -145,6 +157,10 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
&self.rustc.host
}

pub fn host_sandbox_triple(&self) -> &str {
HOST_SANDBOX_TARGET
}

pub fn target_triple(&self) -> &str {
self.build_config
.requested_target
Expand All @@ -157,6 +173,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
fn target_config(&self, kind: Kind) -> &TargetConfig {
match kind {
Kind::Host => &self.host_config,
Kind::HostSandbox => &self.host_sandbox_config,
Kind::Target => &self.target_config,
}
}
Expand All @@ -181,6 +198,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
fn info(&self, kind: Kind) -> &TargetInfo {
match kind {
Kind::Host => &self.host_info,
Kind::HostSandbox => &self.host_sandbox_info,
Kind::Target => &self.target_info,
}
}
Expand All @@ -196,6 +214,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
pub fn script_override(&self, lib_name: &str, kind: Kind) -> Option<&BuildOutput> {
match kind {
Kind::Host => self.host_config.overrides.get(lib_name),
Kind::HostSandbox => self.host_sandbox_config.overrides.get(lib_name),
Kind::Target => self.target_config.overrides.get(lib_name),
}
}
Expand Down
19 changes: 16 additions & 3 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,22 @@ impl TargetInfo {
let mut pipelining_test = process.clone();
pipelining_test.args(&["--error-format=json", "--json=artifacts"]);
let supports_pipelining = match kind {
Kind::Host => Some(rustc.cached_output(&pipelining_test).is_ok()),
Kind::Host | Kind::HostSandbox => Some(rustc.cached_output(&pipelining_test).is_ok()),
Kind::Target => None,
};

let target_triple = requested_target
.as_ref()
.map(|s| s.as_str())
.unwrap_or(&rustc.host);
if kind == Kind::Target {
process.arg("--target").arg(target_triple);
match kind {
Kind::Host => {}
Kind::HostSandbox => {
process.arg("--target").arg(super::HOST_SANDBOX_TARGET);
}
Kind::Target => {
process.arg("--target").arg(target_triple);
}
}

let crate_type_process = process.clone();
Expand Down Expand Up @@ -161,6 +167,13 @@ impl TargetInfo {
}
rustlib
}
Kind::HostSandbox => {
rustlib.push("lib");
rustlib.push("rustlib");
rustlib.push(super::HOST_SANDBOX_TARGET);
rustlib.push("lib");
rustlib
}
Kind::Target => {
rustlib.push("lib");
rustlib.push("rustlib");
Expand Down
24 changes: 18 additions & 6 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use log::info;

use super::{BuildContext, Context, FileFlavor, Kind, Layout};
use crate::core::compiler::{CompileMode, Unit};
use crate::core::{TargetKind, Workspace};
use crate::core::{LibKind, TargetKind, Workspace};
use crate::util::{self, CargoResult};

/// The `Metadata` is a hash used to make unique file names for each unit in a build.
Expand Down Expand Up @@ -53,6 +53,8 @@ impl fmt::Display for Metadata {
pub struct CompilationFiles<'a, 'cfg> {
/// The target directory layout for the host (and target if it is the same as host).
pub(super) host: Layout,
/// The target directory layout for the host sandbox architecture
pub(super) host_sandbox: Layout,
/// The target directory layout for the target (if different from then host).
pub(super) target: Option<Layout>,
/// Additional directory to include a copy of the outputs.
Expand Down Expand Up @@ -93,6 +95,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
pub(super) fn new(
roots: &[Unit<'a>],
host: Layout,
host_sandbox: Layout,
target: Option<Layout>,
export_dir: Option<PathBuf>,
ws: &'a Workspace<'cfg>,
Expand All @@ -110,6 +113,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
CompilationFiles {
ws,
host,
host_sandbox,
target,
export_dir,
roots: roots.to_vec(),
Expand All @@ -122,6 +126,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
pub fn layout(&self, kind: Kind) -> &Layout {
match kind {
Kind::Host => &self.host,
Kind::HostSandbox => &self.host_sandbox,
Kind::Target => self.target.as_ref().unwrap_or(&self.host),
}
}
Expand Down Expand Up @@ -345,10 +350,10 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {

let out_dir = self.out_dir(unit);
let link_stem = self.link_stem(unit);
let info = if unit.kind == Kind::Host {
&bcx.host_info
} else {
&bcx.target_info
let info = match unit.kind {
Kind::Host => &bcx.host_info,
Kind::HostSandbox => &bcx.host_sandbox_info,
Kind::Target => &bcx.target_info,
};
let file_stem = self.file_stem(unit);

Expand Down Expand Up @@ -405,8 +410,15 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
}
TargetKind::ExampleLib(ref kinds) | TargetKind::Lib(ref kinds) => {
for kind in kinds {
let crate_type =
if kind == &LibKind::ProcMacro && unit.kind == Kind::HostSandbox {
// wasm32-unknown-unknown doesn't support proc-macro, so just use cdylib
"cdylib"
} else {
kind.crate_type()
};
add(
kind.crate_type(),
crate_type,
if kind.linkable() {
FileFlavor::Linkable { rmeta: false }
} else {
Expand Down
6 changes: 6 additions & 0 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
"debug"
};
let host_layout = Layout::new(self.bcx.ws, None, dest)?;
let host_sandbox_layout = Layout::new(self.bcx.ws, Some(super::build_context::HOST_SANDBOX_TARGET), dest)?;
let target_layout = match self.bcx.build_config.requested_target.as_ref() {
Some(target) => Some(Layout::new(self.bcx.ws, Some(target), dest)?),
None => None,
Expand All @@ -309,6 +310,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
let files = CompilationFiles::new(
units,
host_layout,
host_sandbox_layout,
target_layout,
export_dir,
self.bcx.ws,
Expand All @@ -327,6 +329,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
.host
.prepare()
.chain_err(|| internal("couldn't prepare build directories"))?;
self.files_mut()
.host_sandbox
.prepare()
.chain_err(|| internal("couldn't prepare build directories"))?;
if let Some(ref mut target) = self.files.as_mut().unwrap().target {
target
.prepare()
Expand Down
3 changes: 2 additions & 1 deletion src/cargo/core/compiler/context/unit_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ fn compute_deps<'a, 'cfg, 'tmp>(
{
let unit = new_unit(bcx, pkg, lib, dep_unit_for, Kind::Target, mode);
ret.push((unit, dep_unit_for));
let unit = new_unit(bcx, pkg, lib, dep_unit_for, Kind::Host, mode);
let unit = new_unit(bcx, pkg, lib, dep_unit_for, unit.kind.for_target(lib), mode);
ret.push((unit, dep_unit_for));
} else {
let unit = new_unit(bcx, pkg, lib, dep_unit_for, unit.kind.for_target(lib), mode);
Expand All @@ -199,6 +199,7 @@ fn compute_deps<'a, 'cfg, 'tmp>(
// all we need. If this isn't a build script, then it depends on the
// build script if there is one.
if unit.target.is_custom_build() {
assert_eq!(unit.kind, Kind::Host, "unit.target {:?}", unit.target);
return Ok(ret);
}
ret.extend(dep_build_script(unit, bcx));
Expand Down
1 change: 1 addition & 0 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
"TARGET",
&match unit.kind {
Kind::Host => bcx.host_triple(),
Kind::HostSandbox => bcx.host_sandbox_triple(),
Kind::Target => bcx.target_triple(),
},
)
Expand Down
46 changes: 35 additions & 11 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ use crate::util::{internal, join_paths, profile};
/// These will be the same unless cross-compiling.
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord, Serialize)]
pub enum Kind {
/// Actual native host architecture
Host,
/// For host, but in a wasm sandbox
HostSandbox,
/// Target architecture
Target,
}

Expand Down Expand Up @@ -947,16 +951,27 @@ fn build_base_args<'a, 'cfg>(
}
}

if unit.kind == Kind::Target {
opt(
cmd,
"--target",
"",
bcx.build_config
.requested_target
.as_ref()
.map(|s| s.as_ref()),
);
match unit.kind {
Kind::Host => {}
Kind::HostSandbox => {
opt(
cmd,
"--target",
"",
Some(cx.bcx.host_sandbox_triple().as_ref()),
);
}
Kind::Target => {
opt(
cmd,
"--target",
"",
bcx.build_config
.requested_target
.as_ref()
.map(|s| s.as_ref()),
);
}
}

opt(cmd, "-C", "ar=", bcx.ar(unit.kind).map(|s| s.as_ref()));
Expand Down Expand Up @@ -1109,7 +1124,16 @@ impl Kind {
// that needs to be on the host we lift ourselves up to `Host`.
match self {
Kind::Host => Kind::Host,
Kind::Target if target.for_host() => Kind::Host,
Kind::HostSandbox if target.is_custom_build() => Kind::Host,
Kind::HostSandbox => Kind::HostSandbox,
Kind::Target if target.for_host() => {
if target.wasm_sandbox() {
assert!(!target.is_custom_build(), "target {:?}", target);
Kind::HostSandbox
} else {
Kind::Host
}
}
Kind::Target => Kind::Target,
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/cargo/core/compiler/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ impl<'a> UnitInterner<'a> {
kind: Kind,
mode: CompileMode,
) -> Unit<'a> {
// building custom_build implies Host
assert!(!(target.is_custom_build() && mode == CompileMode::Build) || kind == Kind::Host,
"target {:?} kind {:?} mode {:?}", target, kind, mode);
let inner = self.intern_inner(&UnitInner {
pkg,
target,
Expand Down
Loading