Skip to content

Commit

Permalink
Try #684:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored Apr 7, 2022
2 parents 416548a + 7860d47 commit 9395c15
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 87 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

- #494 - Parse Cargo's --manifest-path option to determine mounted docker root
- #629 - Update Android NDK version and API version
- #681 - Warn on unknown fields and confusable targets
- #665 - when not using [env.volumes](https://github.com/cross-rs/cross#mounting-volumes-into-the-build-environment), mount project in /project
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ $ QEMU_STRACE=1 cross run --target aarch64-unknown-linux-gnu
- path dependencies (in Cargo.toml) that point outside the Cargo project won't
work because `cross` use docker containers only mounts the Cargo project so
the container doesn't have access to the rest of the filesystem.
However, you may use Cargo's `--manifest-path` option to reference your
target crate, executed from a common root directory from which all your
dependencies are available.

## Minimum Supported Rust Version (MSRV)

Expand Down
15 changes: 15 additions & 0 deletions ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ EOF
popd

rm -rf "${td}"
td=$(mktemp -d)
git clone \
--depth 1 \
--recursive \
https://github.com/cross-rs/test-workspace "${td}"

pushd "${td}"
cross run --target "${TARGET}" -p binary --manifest-path="./workspace/Cargo.toml"
pushd "workspace"
cross run --target "${TARGET}" -p binary
pushd "binary"
cross run --target "${TARGET}"
popd
popd
popd
;;
esac

Expand Down
105 changes: 82 additions & 23 deletions src/cargo.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use serde::Deserialize;
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus};
use std::{env, fs};

use crate::cli::Args;
use crate::errors::*;
use crate::extensions::CommandExt;

Expand Down Expand Up @@ -52,38 +53,96 @@ impl<'a> From<&'a str> for Subcommand {
}
}

#[derive(Debug)]
pub struct Root {
path: PathBuf,
#[derive(Debug, Deserialize)]
pub struct CargoMetadata {
pub workspace_root: PathBuf,
pub target_directory: PathBuf,
pub packages: Vec<Package>,
pub workspace_members: Vec<String>,
}

impl Root {
pub fn path(&self) -> &Path {
&self.path
impl CargoMetadata {
fn non_workspace_members(&self) -> impl Iterator<Item = &Package> {
self.packages
.iter()
.filter(|p| !self.workspace_members.iter().any(|m| m == &p.id))
}
}

/// Cargo project root
pub fn root() -> Result<Option<Root>> {
let cd = env::current_dir().wrap_err("couldn't get current directory")?;
pub fn path_dependencies(&self) -> impl Iterator<Item = &Path> {
// TODO: Also filter out things that are in workspace, but not a workspace member
self.non_workspace_members().filter_map(|p| p.crate_path())
}
}

let mut dir = &*cd;
loop {
let toml = dir.join("Cargo.toml");
#[derive(Debug, Deserialize)]
pub struct Package {
id: String,
manifest_path: PathBuf,
source: Option<String>,
}

if fs::metadata(&toml).is_ok() {
return Ok(Some(Root {
path: dir.to_owned(),
}));
impl Package {
/// Returns the absolute path to the packages manifest "folder"
fn crate_path(&self) -> Option<&Path> {
// when source is none, this package is a path dependency or a workspace member
if self.source.is_none() {
self.manifest_path.parent()
} else {
None
}
}
}

match dir.parent() {
Some(p) => dir = p,
None => break,
/// Cargo metadata with specific invocation
pub fn cargo_metadata_with_args(
cd: Option<&Path>,
args: Option<&Args>,
) -> Result<Option<CargoMetadata>> {
let mut command = std::process::Command::new(
std::env::var("CARGO")
.ok()
.unwrap_or_else(|| "cargo".to_string()),
);
command.arg("metadata").arg("--format-version=1");
if let Some(cd) = cd {
command.current_dir(cd);
}
if let Some(config) = args {
if let Some(ref manifest_path) = config.manifest_path {
command.args(["--manifest-path".as_ref(), manifest_path.as_os_str()]);
}
} else {
command.arg("--no-deps");
}

Ok(None)
if let Some(target) = args.and_then(|a| a.target.as_ref()) {
command.args(["--filter-platform", target.triple()]);
}
let output = command.output()?;
let manifest: Option<CargoMetadata> =
serde_json::from_slice(&output.stdout).wrap_err_with(|| {
format!(
"{command:?} returned nothing. {:?}",
String::from_utf8(output.stderr)
)
})?;
manifest
.map(|m| -> Result<_> {
Ok(CargoMetadata {
target_directory: args
.and_then(|a| a.target_dir.clone())
.map(|p| {
if p.is_relative() {
cd.expect("this is a bug, working directory should be provided here")
.join(p)
} else {
p
}
})
.unwrap_or(m.target_directory),
..m
})
})
.transpose()
}

/// Pass-through mode
Expand Down
19 changes: 18 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ pub struct Args {
pub target: Option<Target>,
pub target_dir: Option<PathBuf>,
pub docker_in_docker: bool,
pub manifest_path: Option<PathBuf>,
}

pub fn parse(target_list: &TargetList) -> Args {
let mut channel = None;
let mut target = None;
let mut manifest_path: Option<PathBuf> = None;
let mut target_dir = None;
let mut sc = None;
let mut all: Vec<String> = Vec::new();
Expand All @@ -28,7 +30,21 @@ pub fn parse(target_list: &TargetList) -> Args {
if arg.is_empty() {
continue;
}
if let ("+", ch) = arg.split_at(1) {
if arg == "--manifest-path" {
all.push(arg);
if let Some(m) = args.next() {
let p = PathBuf::from(&m);
all.push(m);
manifest_path = env::current_dir().ok().map(|cwd| cwd.join(p));
}
} else if arg.starts_with("--manifest-path=") {
manifest_path = arg
.split_once('=')
.map(|x| x.1)
.map(PathBuf::from)
.and_then(|p| env::current_dir().ok().map(|cwd| cwd.join(p)));
all.push(arg);
} else if let ("+", ch) = arg.split_at(1) {
channel = Some(ch.to_string());
} else if arg == "--target" {
all.push(arg);
Expand Down Expand Up @@ -73,5 +89,6 @@ pub fn parse(target_list: &TargetList) -> Args {
target,
target_dir,
docker_in_docker,
manifest_path,
}
}
Loading

0 comments on commit 9395c15

Please sign in to comment.