From ef4bb44f4de7752c088234c1f5bc9680de1db735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Gardstr=C3=B6m?= Date: Wed, 8 Mar 2023 18:33:53 +0100 Subject: [PATCH 1/3] refactor into functions --- src/lib.rs | 373 ++++++++++++++++++++++++++++---------------------- src/rustup.rs | 67 +++++++++ 2 files changed, 275 insertions(+), 165 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 905d5edb8..d7f106cfc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -518,61 +518,24 @@ pub fn run( let cwd = std::env::current_dir()?; if let Some(metadata) = cargo_metadata_with_args(None, Some(&args), msg_info)? { - let host = host_version_meta.host(); - let toml = toml(&metadata, msg_info)?; - let config = Config::new(toml); - let target = args - .target - .or_else(|| config.target(&target_list)) - .unwrap_or_else(|| Target::from(host.triple(), &target_list)); - config.confusable_target(&target, msg_info)?; - - let uses_zig = config.zig(&target).unwrap_or(false); - let zig_version = config.zig_version(&target)?; - // Get the image we're supposed to base all our next actions on. - // The image we actually run in might get changed with - // `target.{{TARGET}}.dockerfile` or `target.{{TARGET}}.pre-build` - let image = match docker::get_image(&config, &target, uses_zig) { - Ok(i) => i, - Err(err) => { - msg_info.warn(err)?; - - return Ok(None); - } + let Some(CrossSetup { + config, + target, + uses_xargo, + uses_zig, + uses_build_std, + zig_version, + toolchain, + is_remote, + engine, + image, + }) = setup(&host_version_meta, &metadata, &args, target_list, msg_info)? else { + return Ok(None); }; - // Grab the current toolchain, this might be the one we mount in the image later - let default_toolchain = QualifiedToolchain::default(&config, msg_info)?; - - // `cross +channel`, where channel can be `+channel[-YYYY-MM-DD]` - let mut toolchain = if let Some(channel) = args.channel { - let picked_toolchain: Toolchain = channel.parse()?; - - if let Some(picked_host) = &picked_toolchain.host { - return Err(eyre::eyre!("the specified toolchain `{picked_toolchain}` can't be used")) - .with_suggestion(|| { - format!( - "try `cross +{}` instead", - picked_toolchain.remove_host() - ) - }).with_section(|| format!( -r#"Overriding the toolchain in cross is only possible in CLI by specifying a channel and optional date: `+channel[-YYYY-MM-DD]`. -To override the toolchain mounted in the image, set `target.{}.image.toolchain = "{picked_host}"`"#, target).header("Note:".bright_cyan())); - } - - default_toolchain.with_picked(picked_toolchain)? - } else { - default_toolchain - }; - - let is_remote = docker::Engine::is_remote(); - let engine = docker::Engine::new(None, Some(is_remote), msg_info)?; - - let image = image.to_definite_with(&engine, msg_info); + config.confusable_target(&target, msg_info)?; - toolchain.replace_host(&image.platform); - let picked_generic_channel = - matches!(toolchain.channel.as_str(), "stable" | "beta" | "nightly"); + let picked_generic_channel = matches!(toolchain.channel.as_str(), "stable" | "beta" | "nightly"); if image.platform.target.is_supported(Some(&target)) { if image.platform.architecture != toolchain.host().architecture { @@ -580,28 +543,7 @@ To override the toolchain mounted in the image, set `target.{}.image.toolchain = "toolchain `{toolchain}` may not run on image `{image}`" ))?; } - // set the sysroot explicitly to the toolchain let mut is_nightly = toolchain.channel.contains("nightly"); - - if !toolchain.is_custom - && !rustup::installed_toolchains(msg_info)? - .into_iter() - .any(|t| t == toolchain.to_string()) - { - rustup::install_toolchain(&toolchain, msg_info)?; - } - let available_targets = if !toolchain.is_custom { - rustup::available_targets(&toolchain.full, msg_info).with_note(|| { - format!("cross would use the toolchain '{toolchain}' for mounting rust") - })? - } else { - rustup::AvailableTargets { - default: String::new(), - installed: vec![], - not_installed: vec![], - } - }; - let mut rustc_version = None; if let Some((version, channel, commit)) = toolchain.rustc_version()? { if picked_generic_channel && toolchain.date.is_none() { @@ -617,103 +559,32 @@ To override the toolchain mounted in the image, set `target.{}.image.toolchain = rustc_version = Some(version); } - let uses_build_std = config.build_std(&target).unwrap_or(false); - let uses_xargo = - !uses_build_std && config.xargo(&target).unwrap_or(!target.is_builtin()); - let cargo_variant = CargoVariant::create(uses_zig, uses_xargo)?; - if !toolchain.is_custom { - // build-std overrides xargo, but only use it if it's a built-in - // tool but not an available target or doesn't have rust-std. - - if !is_nightly && uses_build_std { - eyre::bail!( - "no rust-std component available for {}: must use nightly", - target.triple() - ); - } - - if !uses_xargo - && !uses_build_std - && !available_targets.is_installed(&target) - && available_targets.contains(&target) - { - rustup::install(&target, &toolchain, msg_info)?; - } else if !rustup::component_is_installed("rust-src", &toolchain, msg_info)? { - rustup::install_component("rust-src", &toolchain, msg_info)?; - } - if args.subcommand.map_or(false, |sc| sc == Subcommand::Clippy) - && !rustup::component_is_installed("clippy", &toolchain, msg_info)? - { - rustup::install_component("clippy", &toolchain, msg_info)?; - } - } + let available_targets = rustup::setup_rustup(&toolchain, msg_info)?; + + rustup::setup_components( + &target, + uses_xargo, + uses_build_std, + &toolchain, + is_nightly, + available_targets, + &args, + msg_info, + )?; - let needs_interpreter = args.subcommand.map_or(false, |sc| sc.needs_interpreter()); - - let add_libc = |triple: &str| add_libc_version(triple, zig_version.as_deref()); - let mut filtered_args = if args - .subcommand - .map_or(false, |s| !s.needs_target_in_command()) - { - let mut filtered_args = Vec::new(); - let mut args_iter = args.cargo_args.clone().into_iter(); - while let Some(arg) = args_iter.next() { - if arg == "--target" { - args_iter.next(); - } else if arg.starts_with("--target=") { - // NOOP - } else { - filtered_args.push(arg); - } - } - filtered_args - // Make sure --target is present - } else if !args.cargo_args.iter().any(|a| a.starts_with("--target")) { - let mut args_with_target = args.cargo_args.clone(); - args_with_target.push("--target".to_owned()); - args_with_target.push(add_libc(target.triple())); - args_with_target - } else if zig_version.is_some() { - let mut filtered_args = Vec::new(); - let mut args_iter = args.cargo_args.clone().into_iter(); - while let Some(arg) = args_iter.next() { - if arg == "--target" { - filtered_args.push("--target".to_owned()); - if let Some(triple) = args_iter.next() { - filtered_args.push(add_libc(&triple)); - } - } else if let Some(stripped) = arg.strip_prefix("--target=") { - filtered_args.push(format!("--target={}", add_libc(stripped))); - } else { - filtered_args.push(arg); - } - } - filtered_args - } else { - args.cargo_args.clone() - }; - - let is_test = args.subcommand.map_or(false, |sc| sc == Subcommand::Test); - if is_test && config.doctests().unwrap_or_default() && is_nightly { - filtered_args.push("-Zdoctest-xcompile".to_owned()); - } - if uses_build_std { - filtered_args.push("-Zbuild-std".to_owned()); - } - filtered_args.extend(args.rest_args.iter().cloned()); + let filtered_args = get_filtered_args( + zig_version, + &args, + &target, + &config, + is_nightly, + uses_build_std, + ); let needs_docker = args .subcommand .map_or(false, |sc| sc.needs_docker(is_remote)); if target.needs_docker() && needs_docker { - if host_version_meta.needs_interpreter() - && needs_interpreter - && target.needs_interpreter() - && !interpreter::is_registered(&target)? - { - engine.register_binfmt(&target, msg_info)?; - } - let paths = docker::DockerPaths::create( &engine, metadata, @@ -726,9 +597,18 @@ To override the toolchain mounted in the image, set `target.{}.image.toolchain = target.clone(), config, image, - cargo_variant, + crate::CargoVariant::create(uses_zig, uses_xargo)?, rustc_version, ); + + install_interpreter_if_needed( + &args, + host_version_meta, + &target, + &options, + msg_info, + )?; + let status = docker::run(options, paths, &filtered_args, args.subcommand, msg_info) .wrap_err("could not run container")?; let needs_host = args.subcommand.map_or(false, |sc| sc.needs_host(is_remote)); @@ -744,6 +624,169 @@ To override the toolchain mounted in the image, set `target.{}.image.toolchain = Ok(None) } +/// Check if an interpreter is needed and then install it. +pub fn install_interpreter_if_needed( + args: &Args, + host_version_meta: rustc_version::VersionMeta, + target: &Target, + options: &docker::DockerOptions, + msg_info: &mut MessageInfo, +) -> Result<(), color_eyre::Report> { + let needs_interpreter = args.subcommand.map_or(false, |sc| sc.needs_interpreter()); + + if host_version_meta.needs_interpreter() + && needs_interpreter + && target.needs_interpreter() + && !interpreter::is_registered(target)? + { + options.engine.register_binfmt(target, msg_info)?; + } + Ok(()) +} + +/// Get filtered args to pass to cargo +pub fn get_filtered_args( + zig_version: Option, + args: &Args, + target: &Target, + config: &Config, + is_nightly: bool, + uses_build_std: bool, +) -> Vec { + let add_libc = |triple: &str| add_libc_version(triple, zig_version.as_deref()); + let mut filtered_args = if args + .subcommand + .map_or(false, |s| !s.needs_target_in_command()) + { + let mut filtered_args = Vec::new(); + let mut args_iter = args.cargo_args.clone().into_iter(); + while let Some(arg) = args_iter.next() { + if arg == "--target" { + args_iter.next(); + } else if arg.starts_with("--target=") { + // NOOP + } else { + filtered_args.push(arg); + } + } + filtered_args + // Make sure --target is present + } else if !args.cargo_args.iter().any(|a| a.starts_with("--target")) { + let mut args_with_target = args.cargo_args.clone(); + args_with_target.push("--target".to_owned()); + args_with_target.push(add_libc(target.triple())); + args_with_target + } else if zig_version.is_some() { + let mut filtered_args = Vec::new(); + let mut args_iter = args.cargo_args.clone().into_iter(); + while let Some(arg) = args_iter.next() { + if arg == "--target" { + filtered_args.push("--target".to_owned()); + if let Some(triple) = args_iter.next() { + filtered_args.push(add_libc(&triple)); + } + } else if let Some(stripped) = arg.strip_prefix("--target=") { + filtered_args.push(format!("--target={}", add_libc(stripped))); + } else { + filtered_args.push(arg); + } + } + filtered_args + } else { + args.cargo_args.clone() + }; + + let is_test = args.subcommand.map_or(false, |sc| sc == Subcommand::Test); + if is_test && config.doctests().unwrap_or_default() && is_nightly { + filtered_args.push("-Zdoctest-xcompile".to_owned()); + } + if uses_build_std { + filtered_args.push("-Zbuild-std".to_owned()); + } + filtered_args.extend(args.rest_args.iter().cloned()); + filtered_args +} + +/// Setup cross configuration +pub fn setup( + host_version_meta: &rustc_version::VersionMeta, + metadata: &CargoMetadata, + args: &Args, + target_list: TargetList, + msg_info: &mut MessageInfo, +) -> Result, color_eyre::Report> { + let host = host_version_meta.host(); + let toml = toml(metadata, msg_info)?; + let config = Config::new(toml); + let target = args + .target + .clone() + .or_else(|| config.target(&target_list)) + .unwrap_or_else(|| Target::from(host.triple(), &target_list)); + let uses_build_std = config.build_std(&target).unwrap_or(false); + let uses_xargo = !uses_build_std && config.xargo(&target).unwrap_or(!target.is_builtin()); + let uses_zig = config.zig(&target).unwrap_or(false); + let zig_version = config.zig_version(&target)?; + let image = match docker::get_image(&config, &target, uses_zig) { + Ok(i) => i, + Err(err) => { + msg_info.warn(err)?; + + return Ok(None); + } + }; + let default_toolchain = QualifiedToolchain::default(&config, msg_info)?; + let mut toolchain = if let Some(channel) = &args.channel { + let picked_toolchain: Toolchain = channel.parse()?; + + if let Some(picked_host) = &picked_toolchain.host { + return Err(eyre::eyre!("the specified toolchain `{picked_toolchain}` can't be used")) + .with_suggestion(|| { + format!( + "try `cross +{}` instead", + picked_toolchain.remove_host() + ) + }).with_section(|| format!( + r#"Overriding the toolchain in cross is only possible in CLI by specifying a channel and optional date: `+channel[-YYYY-MM-DD]`. +To override the toolchain mounted in the image, set `target.{target}.image.toolchain = "{picked_host}"`"#).header("Note:".bright_cyan())); + } + + default_toolchain.with_picked(picked_toolchain)? + } else { + default_toolchain + }; + let is_remote = docker::Engine::is_remote(); + let engine = docker::Engine::new(None, Some(is_remote), msg_info)?; + let image = image.to_definite_with(&engine, msg_info); + toolchain.replace_host(&image.platform); + Ok(Some(CrossSetup { + config, + target, + uses_xargo, + uses_zig, + uses_build_std, + zig_version, + toolchain, + is_remote, + engine, + image, + })) +} + +#[derive(Debug)] +pub struct CrossSetup { + pub config: Config, + pub target: Target, + pub uses_xargo: bool, + pub uses_zig: bool, + pub uses_build_std: bool, + pub zig_version: Option, + pub toolchain: QualifiedToolchain, + pub is_remote: bool, + pub engine: docker::Engine, + pub image: docker::Image, +} + #[derive(PartialEq, Eq, Debug)] pub(crate) enum VersionMatch { Same, diff --git a/src/rustup.rs b/src/rustup.rs index 39122b6a3..90b8b4f97 100644 --- a/src/rustup.rs +++ b/src/rustup.rs @@ -28,6 +28,31 @@ impl AvailableTargets { } } +pub fn setup_rustup( + toolchain: &QualifiedToolchain, + msg_info: &mut MessageInfo, +) -> Result { + if !toolchain.is_custom + && !installed_toolchains(msg_info)? + .into_iter() + .any(|t| t == toolchain.to_string()) + { + install_toolchain(toolchain, msg_info)?; + } + let available_targets = if !toolchain.is_custom { + available_targets(&toolchain.full, msg_info).with_note(|| { + format!("cross would use the toolchain '{toolchain}' for mounting rust") + })? + } else { + AvailableTargets { + default: String::new(), + installed: vec![], + not_installed: vec![], + } + }; + Ok(available_targets) +} + fn rustup_command(msg_info: &mut MessageInfo, no_flags: bool) -> Command { let mut cmd = Command::new("rustup"); if no_flags { @@ -241,6 +266,48 @@ pub fn component_is_installed( Ok(check_component(component, toolchain, msg_info)?.is_installed()) } +#[allow(clippy::too_many_arguments)] +pub fn setup_components( + target: &Target, + uses_xargo: bool, + uses_build_std: bool, + toolchain: &QualifiedToolchain, + is_nightly: bool, + available_targets: AvailableTargets, + args: &crate::cli::Args, + msg_info: &mut MessageInfo, +) -> Result<(), color_eyre::Report> { + if !toolchain.is_custom { + // build-std overrides xargo, but only use it if it's a built-in + // tool but not an available target or doesn't have rust-std. + + if !is_nightly && uses_build_std { + eyre::bail!( + "no rust-std component available for {}: must use nightly", + target.triple() + ); + } + + if !uses_xargo + && !uses_build_std + && !available_targets.is_installed(target) + && available_targets.contains(target) + { + install(target, toolchain, msg_info)?; + } else if !component_is_installed("rust-src", toolchain, msg_info)? { + install_component("rust-src", toolchain, msg_info)?; + } + if args + .subcommand + .map_or(false, |sc| sc == crate::Subcommand::Clippy) + && !component_is_installed("clippy", toolchain, msg_info)? + { + install_component("clippy", toolchain, msg_info)?; + } + } + Ok(()) +} + fn rustc_channel(version: &Version) -> Result { match version .pre From 7783c0bdb82ad1325379761c7973c6c578765cd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Gardstr=C3=B6m?= Date: Wed, 8 Mar 2023 20:14:30 +0100 Subject: [PATCH 2/3] wip --- src/bin/commands/install.rs | 131 ++++++++++++++++++++++++++++++++++++ src/bin/commands/mod.rs | 2 + src/bin/cross-util.rs | 10 +++ src/bin/cross.rs | 2 +- src/cli.rs | 5 +- src/docker/engine.rs | 3 +- src/lib.rs | 11 +-- 7 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 src/bin/commands/install.rs diff --git a/src/bin/commands/install.rs b/src/bin/commands/install.rs new file mode 100644 index 000000000..5d6a867f2 --- /dev/null +++ b/src/bin/commands/install.rs @@ -0,0 +1,131 @@ +use clap::Args; +use cross::{docker, rustc, shell::MessageInfo}; +use eyre::Context; + +#[derive(Args, Debug)] +pub struct Install { + #[clap(long)] + target: Option, + /// Provide verbose diagnostic output. + #[clap(short, long)] + pub verbose: bool, + /// Do not print + #[clap(short, long)] + pub quiet: bool, + /// Coloring: auto, always, never + #[clap(long)] + pub color: Option, + /// Container engine (such as docker or podman). + #[clap(long)] + pub engine: Option, + /// Path to crate + #[clap(long)] + pub path: Option, + /// Path to Cross.toml + #[clap(long)] + pub config: Option, + #[clap(name = "crate")] + krate: String, +} + +impl Install { + pub fn verbose(&self) -> bool { + self.verbose + } + + pub fn quiet(&self) -> bool { + self.quiet + } + + pub fn color(&self) -> Option<&str> { + self.color.as_deref() + } + + pub fn run(self, msg_info: &mut MessageInfo) -> cross::Result { + let target_list = rustc::target_list(&mut cross::shell::Verbosity::Quiet.into())?; + + let host_version_meta = rustc::version_meta()?; + let mut command = vec!["install".to_owned(), self.krate]; + + if let Some(target) = self.target { + command.push(format!("--target={target}")); + } + if let Some(engine) = self.engine { + std::env::set_var(docker::CROSS_CONTAINER_ENGINE_VAR, engine); + } + + let args = cross::cli::parse(command, &target_list)?; + let Some(cross::CrossSetup { + config, + target, + uses_xargo, + uses_zig, + uses_build_std, + zig_version, + toolchain, + is_remote, + engine, + image, + }) = cross::setup(&host_version_meta, None, &args, target_list, msg_info)? else { + eyre::bail!("couldn't setup context for cross (see warning)") + }; + + let mut is_nightly = toolchain.channel.contains("nightly"); + let mut rustc_version = None; + if let Some((version, channel, _)) = toolchain.rustc_version()? { + is_nightly = channel == rustc_version::Channel::Nightly; + rustc_version = Some(version); + } + + let available_targets = cross::rustup::setup_rustup(&toolchain, msg_info)?; + + cross::rustup::setup_components( + &target, + uses_xargo, + uses_build_std, + &toolchain, + is_nightly, + available_targets, + &args, + msg_info, + )?; + + let filtered_args = cross::get_filtered_args( + zig_version, + &args, + &target, + &config, + is_nightly, + uses_build_std, + ); + + let cwd = std::env::current_dir()?; + + let paths = + docker::DockerPaths::create(&engine, todo!(), cwd, toolchain.clone(), msg_info)?; + let options = docker::DockerOptions::new( + engine, + target.clone(), + config, + image, + cross::CargoVariant::create(uses_zig, uses_xargo)?, + rustc_version, + ); + + cross::install_interpreter_if_needed( + &args, + host_version_meta, + &target, + &options, + msg_info, + )?; + + let status = docker::run(options, paths, &filtered_args, msg_info) + .wrap_err("could not run container")?; + let needs_host = args.subcommand.map_or(false, |sc| sc.needs_host(is_remote)); + if !status.success() { + cross::warn_on_failure(&target, &toolchain, msg_info)?; + } + Ok(status) + } +} diff --git a/src/bin/commands/mod.rs b/src/bin/commands/mod.rs index 30a1c771a..83ba82c55 100644 --- a/src/bin/commands/mod.rs +++ b/src/bin/commands/mod.rs @@ -1,7 +1,9 @@ mod clean; mod containers; mod images; +mod install; pub use self::clean::*; pub use self::containers::*; pub use self::images::*; +pub use self::install::*; diff --git a/src/bin/cross-util.rs b/src/bin/cross-util.rs index cc90a6824..8f3a9d7db 100644 --- a/src/bin/cross-util.rs +++ b/src/bin/cross-util.rs @@ -39,6 +39,8 @@ enum Commands { Containers(commands::Containers), /// Clean all cross data in local storage. Clean(commands::Clean), + /// Install a binary crate + Install(commands::Install), } fn is_toolchain(toolchain: &str) -> cross::Result { @@ -103,6 +105,14 @@ pub fn main() -> cross::Result<()> { let engine = get_engine!(args, false, msg_info)?; args.run(engine, &mut msg_info)?; } + Commands::Install(args) => { + let mut msg_info = get_msg_info!(args)?; + let status = args.run(&mut msg_info)?; + let code = status + .code() + .ok_or_else(|| eyre::Report::msg("Cargo process terminated by signal"))?; + std::process::exit(code) + } } Ok(()) diff --git a/src/bin/cross.rs b/src/bin/cross.rs index 64536d296..87e1a4483 100644 --- a/src/bin/cross.rs +++ b/src/bin/cross.rs @@ -16,7 +16,7 @@ pub fn main() -> cross::Result<()> { cross::install_termination_hook()?; let target_list = rustc::target_list(&mut Verbosity::Quiet.into())?; - let args = cli::parse(&target_list)?; + let args = cli::parse(env::args().skip(1), &target_list)?; let subcommand = args.subcommand; let mut msg_info = shell::MessageInfo::create(args.verbose, args.quiet, args.color.as_deref())?; let status = match cross::run(args, target_list, &mut msg_info)? { diff --git a/src/cli.rs b/src/cli.rs index 4adbab983..cffd48433 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -157,7 +157,7 @@ fn store_target_dir(_: String) -> Result { Ok("/target".to_owned()) } -pub fn parse(target_list: &TargetList) -> Result { +pub fn parse(args: impl IntoIterator, target_list: &TargetList) -> Result { let mut channel = None; let mut target = None; let mut features = Vec::new(); @@ -171,8 +171,9 @@ pub fn parse(target_list: &TargetList) -> Result { let mut verbose = 0; let mut color = None; + let mut args = args.into_iter(); + { - let mut args = env::args().skip(1); while let Some(arg) = args.next() { if arg.is_empty() { continue; diff --git a/src/docker/engine.rs b/src/docker/engine.rs index 8657e65b6..872e013bb 100644 --- a/src/docker/engine.rs +++ b/src/docker/engine.rs @@ -11,6 +11,7 @@ use super::{Architecture, ContainerOs}; pub const DOCKER: &str = "docker"; pub const PODMAN: &str = "podman"; +pub const CROSS_CONTAINER_ENGINE_VAR: &str = "CROSS_CONTAINER_ENGINE"; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum EngineType { @@ -260,7 +261,7 @@ fn get_custom_info( } pub fn get_container_engine() -> Result { - if let Ok(ce) = env::var("CROSS_CONTAINER_ENGINE") { + if let Ok(ce) = env::var(CROSS_CONTAINER_ENGINE_VAR) { which::which(ce) } else { which::which(DOCKER).or_else(|_| which::which(PODMAN)) diff --git a/src/lib.rs b/src/lib.rs index d7f106cfc..3bfc76bd8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -473,7 +473,7 @@ impl CargoVariant { } } -fn warn_on_failure( +pub fn warn_on_failure( target: &Target, toolchain: &QualifiedToolchain, msg_info: &mut MessageInfo, @@ -518,6 +518,8 @@ pub fn run( let cwd = std::env::current_dir()?; if let Some(metadata) = cargo_metadata_with_args(None, Some(&args), msg_info)? { + let toml = toml(&metadata, msg_info)?; + let Some(CrossSetup { config, target, @@ -529,7 +531,7 @@ pub fn run( is_remote, engine, image, - }) = setup(&host_version_meta, &metadata, &args, target_list, msg_info)? else { + }) = setup(&host_version_meta, toml, &args, target_list, msg_info)? else { return Ok(None); }; @@ -587,7 +589,7 @@ pub fn run( if target.needs_docker() && needs_docker { let paths = docker::DockerPaths::create( &engine, - metadata, + todo!(), cwd, toolchain.clone(), msg_info, @@ -710,13 +712,12 @@ pub fn get_filtered_args( /// Setup cross configuration pub fn setup( host_version_meta: &rustc_version::VersionMeta, - metadata: &CargoMetadata, + toml: Option, args: &Args, target_list: TargetList, msg_info: &mut MessageInfo, ) -> Result, color_eyre::Report> { let host = host_version_meta.host(); - let toml = toml(metadata, msg_info)?; let config = Config::new(toml); let target = args .target From f3fe659ebc9b7b51b832494ca8e354a5c884e4c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Gardstr=C3=B6m?= Date: Wed, 8 Mar 2023 20:36:05 +0100 Subject: [PATCH 3/3] skip target dir --- src/bin/commands/install.rs | 23 +++++++++++++++++++---- src/docker/local.rs | 21 +++++++++++---------- src/docker/shared.rs | 7 ++++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/bin/commands/install.rs b/src/bin/commands/install.rs index 5d6a867f2..9d4419dad 100644 --- a/src/bin/commands/install.rs +++ b/src/bin/commands/install.rs @@ -6,6 +6,8 @@ use eyre::Context; pub struct Install { #[clap(long)] target: Option, + #[clap(long)] + root: String, /// Provide verbose diagnostic output. #[clap(short, long)] pub verbose: bool, @@ -50,6 +52,8 @@ impl Install { if let Some(target) = self.target { command.push(format!("--target={target}")); } + command.push(format!("--root={}", self.root)); + if let Some(engine) = self.engine { std::env::set_var(docker::CROSS_CONTAINER_ENGINE_VAR, engine); } @@ -101,9 +105,19 @@ impl Install { let cwd = std::env::current_dir()?; - let paths = - docker::DockerPaths::create(&engine, todo!(), cwd, toolchain.clone(), msg_info)?; - let options = docker::DockerOptions::new( + let paths = docker::DockerPaths::create( + &engine, + cross::CargoMetadata { + workspace_root: cwd.clone(), + target_directory: cross::file::absolute_path(self.root)?, + packages: vec![], + workspace_members: vec![], + }, + cwd, + toolchain.clone(), + msg_info, + )?; + let mut options = docker::DockerOptions::new( engine, target.clone(), config, @@ -112,6 +126,8 @@ impl Install { rustc_version, ); + options.skip_target_dir = true; + cross::install_interpreter_if_needed( &args, host_version_meta, @@ -122,7 +138,6 @@ impl Install { let status = docker::run(options, paths, &filtered_args, msg_info) .wrap_err("could not run container")?; - let needs_host = args.subcommand.map_or(false, |sc| sc.needs_host(is_remote)); if !status.success() { cross::warn_on_failure(&target, &toolchain, msg_info)?; } diff --git a/src/docker/local.rs b/src/docker/local.rs index 92e9efd72..920167b86 100644 --- a/src/docker/local.rs +++ b/src/docker/local.rs @@ -87,19 +87,20 @@ pub(crate) fn run( package_dirs.mount_root() ), ]); - docker - .args([ - "-v", - &format!( - "{}:{}:z,ro", - toolchain_dirs.get_sysroot().to_utf8()?, - toolchain_dirs.sysroot_mount_path() - ), - ]) - .args([ + docker.args([ + "-v", + &format!( + "{}:{}:z,ro", + toolchain_dirs.get_sysroot().to_utf8()?, + toolchain_dirs.sysroot_mount_path() + ), + ]); + if !options.skip_target_dir { + docker.args([ "-v", &format!("{}:/target:z", package_dirs.target().to_utf8()?), ]); + } docker.add_cwd(&paths)?; // When running inside NixOS or using Nix packaging we need to add the Nix diff --git a/src/docker/shared.rs b/src/docker/shared.rs index 314a0c657..e303e89d2 100644 --- a/src/docker/shared.rs +++ b/src/docker/shared.rs @@ -33,6 +33,7 @@ pub struct DockerOptions { pub target: Target, pub config: Config, pub image: Image, + pub skip_target_dir: bool, pub cargo_variant: CargoVariant, // not all toolchains will provide this pub rustc_version: Option, @@ -52,6 +53,7 @@ impl DockerOptions { target, config, image, + skip_target_dir: false, cargo_variant, rustc_version, } @@ -1039,8 +1041,11 @@ impl DockerCommandExt for Command { "-e", &format!("CROSS_RUST_SYSROOT={}", dirs.sysroot_mount_path()), ]) - .args(["-e", "CARGO_TARGET_DIR=/target"]) .args(["-e", &cross_runner]); + + if !options.skip_target_dir { + self.args(["-e", "CARGO_TARGET_DIR=/target"]); + } if options.cargo_variant.uses_zig() { // otherwise, zig has a permission error trying to create the cache self.args(["-e", "XDG_CACHE_HOME=/target/.zig-cache"]);