Skip to content

Commit 7783c0b

Browse files
committed
wip
1 parent ef4bb44 commit 7783c0b

File tree

7 files changed

+155
-9
lines changed

7 files changed

+155
-9
lines changed

src/bin/commands/install.rs

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
use clap::Args;
2+
use cross::{docker, rustc, shell::MessageInfo};
3+
use eyre::Context;
4+
5+
#[derive(Args, Debug)]
6+
pub struct Install {
7+
#[clap(long)]
8+
target: Option<String>,
9+
/// Provide verbose diagnostic output.
10+
#[clap(short, long)]
11+
pub verbose: bool,
12+
/// Do not print
13+
#[clap(short, long)]
14+
pub quiet: bool,
15+
/// Coloring: auto, always, never
16+
#[clap(long)]
17+
pub color: Option<String>,
18+
/// Container engine (such as docker or podman).
19+
#[clap(long)]
20+
pub engine: Option<String>,
21+
/// Path to crate
22+
#[clap(long)]
23+
pub path: Option<String>,
24+
/// Path to Cross.toml
25+
#[clap(long)]
26+
pub config: Option<std::path::PathBuf>,
27+
#[clap(name = "crate")]
28+
krate: String,
29+
}
30+
31+
impl Install {
32+
pub fn verbose(&self) -> bool {
33+
self.verbose
34+
}
35+
36+
pub fn quiet(&self) -> bool {
37+
self.quiet
38+
}
39+
40+
pub fn color(&self) -> Option<&str> {
41+
self.color.as_deref()
42+
}
43+
44+
pub fn run(self, msg_info: &mut MessageInfo) -> cross::Result<std::process::ExitStatus> {
45+
let target_list = rustc::target_list(&mut cross::shell::Verbosity::Quiet.into())?;
46+
47+
let host_version_meta = rustc::version_meta()?;
48+
let mut command = vec!["install".to_owned(), self.krate];
49+
50+
if let Some(target) = self.target {
51+
command.push(format!("--target={target}"));
52+
}
53+
if let Some(engine) = self.engine {
54+
std::env::set_var(docker::CROSS_CONTAINER_ENGINE_VAR, engine);
55+
}
56+
57+
let args = cross::cli::parse(command, &target_list)?;
58+
let Some(cross::CrossSetup {
59+
config,
60+
target,
61+
uses_xargo,
62+
uses_zig,
63+
uses_build_std,
64+
zig_version,
65+
toolchain,
66+
is_remote,
67+
engine,
68+
image,
69+
}) = cross::setup(&host_version_meta, None, &args, target_list, msg_info)? else {
70+
eyre::bail!("couldn't setup context for cross (see warning)")
71+
};
72+
73+
let mut is_nightly = toolchain.channel.contains("nightly");
74+
let mut rustc_version = None;
75+
if let Some((version, channel, _)) = toolchain.rustc_version()? {
76+
is_nightly = channel == rustc_version::Channel::Nightly;
77+
rustc_version = Some(version);
78+
}
79+
80+
let available_targets = cross::rustup::setup_rustup(&toolchain, msg_info)?;
81+
82+
cross::rustup::setup_components(
83+
&target,
84+
uses_xargo,
85+
uses_build_std,
86+
&toolchain,
87+
is_nightly,
88+
available_targets,
89+
&args,
90+
msg_info,
91+
)?;
92+
93+
let filtered_args = cross::get_filtered_args(
94+
zig_version,
95+
&args,
96+
&target,
97+
&config,
98+
is_nightly,
99+
uses_build_std,
100+
);
101+
102+
let cwd = std::env::current_dir()?;
103+
104+
let paths =
105+
docker::DockerPaths::create(&engine, todo!(), cwd, toolchain.clone(), msg_info)?;
106+
let options = docker::DockerOptions::new(
107+
engine,
108+
target.clone(),
109+
config,
110+
image,
111+
cross::CargoVariant::create(uses_zig, uses_xargo)?,
112+
rustc_version,
113+
);
114+
115+
cross::install_interpreter_if_needed(
116+
&args,
117+
host_version_meta,
118+
&target,
119+
&options,
120+
msg_info,
121+
)?;
122+
123+
let status = docker::run(options, paths, &filtered_args, msg_info)
124+
.wrap_err("could not run container")?;
125+
let needs_host = args.subcommand.map_or(false, |sc| sc.needs_host(is_remote));
126+
if !status.success() {
127+
cross::warn_on_failure(&target, &toolchain, msg_info)?;
128+
}
129+
Ok(status)
130+
}
131+
}

src/bin/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
mod clean;
22
mod containers;
33
mod images;
4+
mod install;
45

56
pub use self::clean::*;
67
pub use self::containers::*;
78
pub use self::images::*;
9+
pub use self::install::*;

src/bin/cross-util.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ enum Commands {
3939
Containers(commands::Containers),
4040
/// Clean all cross data in local storage.
4141
Clean(commands::Clean),
42+
/// Install a binary crate
43+
Install(commands::Install),
4244
}
4345

4446
fn is_toolchain(toolchain: &str) -> cross::Result<Toolchain> {
@@ -103,6 +105,14 @@ pub fn main() -> cross::Result<()> {
103105
let engine = get_engine!(args, false, msg_info)?;
104106
args.run(engine, &mut msg_info)?;
105107
}
108+
Commands::Install(args) => {
109+
let mut msg_info = get_msg_info!(args)?;
110+
let status = args.run(&mut msg_info)?;
111+
let code = status
112+
.code()
113+
.ok_or_else(|| eyre::Report::msg("Cargo process terminated by signal"))?;
114+
std::process::exit(code)
115+
}
106116
}
107117

108118
Ok(())

src/bin/cross.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn main() -> cross::Result<()> {
1616
cross::install_termination_hook()?;
1717

1818
let target_list = rustc::target_list(&mut Verbosity::Quiet.into())?;
19-
let args = cli::parse(&target_list)?;
19+
let args = cli::parse(env::args().skip(1), &target_list)?;
2020
let subcommand = args.subcommand;
2121
let mut msg_info = shell::MessageInfo::create(args.verbose, args.quiet, args.color.as_deref())?;
2222
let status = match cross::run(args, target_list, &mut msg_info)? {

src/cli.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn store_target_dir(_: String) -> Result<String> {
157157
Ok("/target".to_owned())
158158
}
159159

160-
pub fn parse(target_list: &TargetList) -> Result<Args> {
160+
pub fn parse(args: impl IntoIterator<Item = String>, target_list: &TargetList) -> Result<Args> {
161161
let mut channel = None;
162162
let mut target = None;
163163
let mut features = Vec::new();
@@ -171,8 +171,9 @@ pub fn parse(target_list: &TargetList) -> Result<Args> {
171171
let mut verbose = 0;
172172
let mut color = None;
173173

174+
let mut args = args.into_iter();
175+
174176
{
175-
let mut args = env::args().skip(1);
176177
while let Some(arg) = args.next() {
177178
if arg.is_empty() {
178179
continue;

src/docker/engine.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use super::{Architecture, ContainerOs};
1111

1212
pub const DOCKER: &str = "docker";
1313
pub const PODMAN: &str = "podman";
14+
pub const CROSS_CONTAINER_ENGINE_VAR: &str = "CROSS_CONTAINER_ENGINE";
1415

1516
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1617
pub enum EngineType {
@@ -260,7 +261,7 @@ fn get_custom_info(
260261
}
261262

262263
pub fn get_container_engine() -> Result<PathBuf, which::Error> {
263-
if let Ok(ce) = env::var("CROSS_CONTAINER_ENGINE") {
264+
if let Ok(ce) = env::var(CROSS_CONTAINER_ENGINE_VAR) {
264265
which::which(ce)
265266
} else {
266267
which::which(DOCKER).or_else(|_| which::which(PODMAN))

src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ impl CargoVariant {
473473
}
474474
}
475475

476-
fn warn_on_failure(
476+
pub fn warn_on_failure(
477477
target: &Target,
478478
toolchain: &QualifiedToolchain,
479479
msg_info: &mut MessageInfo,
@@ -518,6 +518,8 @@ pub fn run(
518518

519519
let cwd = std::env::current_dir()?;
520520
if let Some(metadata) = cargo_metadata_with_args(None, Some(&args), msg_info)? {
521+
let toml = toml(&metadata, msg_info)?;
522+
521523
let Some(CrossSetup {
522524
config,
523525
target,
@@ -529,7 +531,7 @@ pub fn run(
529531
is_remote,
530532
engine,
531533
image,
532-
}) = setup(&host_version_meta, &metadata, &args, target_list, msg_info)? else {
534+
}) = setup(&host_version_meta, toml, &args, target_list, msg_info)? else {
533535
return Ok(None);
534536
};
535537

@@ -587,7 +589,7 @@ pub fn run(
587589
if target.needs_docker() && needs_docker {
588590
let paths = docker::DockerPaths::create(
589591
&engine,
590-
metadata,
592+
todo!(),
591593
cwd,
592594
toolchain.clone(),
593595
msg_info,
@@ -710,13 +712,12 @@ pub fn get_filtered_args(
710712
/// Setup cross configuration
711713
pub fn setup(
712714
host_version_meta: &rustc_version::VersionMeta,
713-
metadata: &CargoMetadata,
715+
toml: Option<CrossToml>,
714716
args: &Args,
715717
target_list: TargetList,
716718
msg_info: &mut MessageInfo,
717719
) -> Result<Option<CrossSetup>, color_eyre::Report> {
718720
let host = host_version_meta.host();
719-
let toml = toml(metadata, msg_info)?;
720721
let config = Config::new(toml);
721722
let target = args
722723
.target

0 commit comments

Comments
 (0)