From 321eee62e42049b4f52206e43de7af03659b02b9 Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Fri, 11 Oct 2019 12:25:15 +0000 Subject: [PATCH 1/4] Make sure to use Xargo.toml directory when resolving path This fix #259 --- src/sysroot.rs | 18 ++++++++++-------- src/xargo.rs | 6 +++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/sysroot.rs b/src/sysroot.rs index 4a934f4..b012652 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; use std::io::{self, Write}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::{env, fs}; use rustc_version::VersionMeta; @@ -231,9 +231,11 @@ pub fn update( verbose: bool, ) -> Result<()> { let ctoml = cargo::toml(root)?; - let xtoml = xargo::toml(root)?; + let (xtoml_parent, xtoml) = xargo::toml(root)?; - let blueprint = Blueprint::from(xtoml.as_ref(), cmode.triple(), root, &src)?; + let base_path = xtoml_parent.unwrap_or_else(|| root.path().to_path_buf()); + + let blueprint = Blueprint::from(xtoml.as_ref(), cmode.triple(), &base_path, &src)?; let hash = hash(cmode, &blueprint, rustflags, &ctoml, meta)?; @@ -358,10 +360,10 @@ impl Blueprint { Ok(()) } - fn from(toml: Option<&xargo::Toml>, target: &str, root: &Root, src: &Src) -> Result { + fn from(toml: Option<&xargo::Toml>, target: &str, base_path: &Path, src: &Src) -> Result { fn make_path_absolute( crate_spec: &mut toml::Table, - root: &Root, + base_path: &Path, on_error_path: F, ) -> Result<()> where @@ -376,7 +378,7 @@ impl Blueprint { if !p.is_absolute() { *path = Value::String( - root.path() + base_path .join(&p) .canonicalize() .chain_err(|| format!("couldn't canonicalize {}", p.display()))? @@ -401,7 +403,7 @@ impl Blueprint { for (k2, v) in v.as_table_mut(|| format!("patch.{}", k1))?.iter_mut() { let krate = v.as_table_mut(|| format!("patch.{}.{}", k1, k2))?; - make_path_absolute(krate, root, || format!("patch.{}.{}", k1, k2))?; + make_path_absolute(krate, base_path, || format!("patch.{}.{}", k1, k2))?; } } @@ -481,7 +483,7 @@ impl Blueprint { 0 }; - make_path_absolute(&mut map, root, || format!("dependencies.{}", k))?; + make_path_absolute(&mut map, base_path, || format!("dependencies.{}", k))?; if !map.contains_key("path") && !map.contains_key("git") { // No path and no git given. This might be in the sysroot, but if we don't find it there we assume it comes from crates.io. diff --git a/src/xargo.rs b/src/xargo.rs index 06b21bd..bec0cc8 100644 --- a/src/xargo.rs +++ b/src/xargo.rs @@ -120,11 +120,11 @@ impl Toml { } } -pub fn toml(root: &Root) -> Result> { +pub fn toml(root: &Root) -> Result<(Option, Option)> { if let Some(p) = util::search(root.path(), "Xargo.toml") { - util::parse(&p.join("Xargo.toml")).map(|t| Some(Toml { table: t })) + Ok((Some(p.to_path_buf()), util::parse(&p.join("Xargo.toml")).map(|t| Some(Toml { table: t }))?)) } else { - Ok(None) + Ok((None, None)) } } From b0b9d8a9496b9f2530e9972cdd4a2f06326d9dcb Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Wed, 16 Oct 2019 13:24:55 +0000 Subject: [PATCH 2/4] Avoid PathBuf copies from previous commit --- src/sysroot.rs | 2 +- src/xargo.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sysroot.rs b/src/sysroot.rs index b012652..9a095fc 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -233,7 +233,7 @@ pub fn update( let ctoml = cargo::toml(root)?; let (xtoml_parent, xtoml) = xargo::toml(root)?; - let base_path = xtoml_parent.unwrap_or_else(|| root.path().to_path_buf()); + let base_path: &Path = xtoml_parent.unwrap_or_else(|| root.path()); let blueprint = Blueprint::from(xtoml.as_ref(), cmode.triple(), &base_path, &src)?; diff --git a/src/xargo.rs b/src/xargo.rs index bec0cc8..ad97f9f 100644 --- a/src/xargo.rs +++ b/src/xargo.rs @@ -1,4 +1,4 @@ -use std::path::{Display, PathBuf}; +use std::path::{Display, Path, PathBuf}; use std::process::ExitStatus; use std::{env, mem}; use std::io::{self, Write}; @@ -120,9 +120,9 @@ impl Toml { } } -pub fn toml(root: &Root) -> Result<(Option, Option)> { +pub fn toml(root: &Root) -> Result<(Option<&Path>, Option)> { if let Some(p) = util::search(root.path(), "Xargo.toml") { - Ok((Some(p.to_path_buf()), util::parse(&p.join("Xargo.toml")).map(|t| Some(Toml { table: t }))?)) + Ok((Some(p), util::parse(&p.join("Xargo.toml")).map(|t| Some(Toml { table: t }))?)) } else { Ok((None, None)) From 35585c0ae97c59d8abc485e67df7139b8d5161ec Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Thu, 17 Oct 2019 14:24:29 +0000 Subject: [PATCH 3/4] Add a dependency in target_dependencies for relative path resolution --- tests/smoke.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/tests/smoke.rs b/tests/smoke.rs index b5dbe63..7610869 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -170,6 +170,18 @@ struct Project { td: TempDir, } +/// Create a simple project +fn create_simple_project(project_path: &Path, name: &'static str, library_source: &'static str) -> Result<()> { + xargo()? + .args(&["init", "-q", "--lib", "--vcs", "none", "--name", name]) + .current_dir(project_path) + .run()?; + + write(&project_path.join("src/lib.rs"), false, library_source)?; + + Ok(()) +} + impl Project { /// Creates a new project with given name in a temporary directory. fn new(name: &'static str) -> Result { @@ -194,13 +206,7 @@ impl Project { let td = TempDir::new_in(dir, "xargo").chain_err(|| "couldn't create a temporary directory")?; - xargo()? - .args(&["init", "-q", "--lib", "--vcs", "none", "--name", name]) - .current_dir(td.path()) - .run()?; - - write(&td.path().join("src/lib.rs"), false, "#![no_std]")?; - + create_simple_project(td.path(), name, "#![no_std]")?; write(&td.path().join(format!("{}.json", name)), false, JSON)?; Ok(Project { name: name, td: td }) @@ -363,18 +369,28 @@ fn target_dependencies() { fn run() -> Result<()> { // need this exact target name to get the right gcc flags const TARGET: &'static str = "thumbv7m-none-eabi"; + const STAGE1: &'static str = "stage1"; let td = TempDir::new("xargo").chain_err(|| "couldn't create a temporary directory")?; let project = Project::new_in(td.path().to_path_buf(), TARGET)?; + + let stage1_path = td.path().join(STAGE1); + + mkdir(stage1_path.as_path())?; + create_simple_project(stage1_path.as_path(), STAGE1, "#![no_std]")?; write(&td.path().join("Xargo.toml"), false, r#" [target.thumbv7m-none-eabi.dependencies.alloc] + +[target.thumbv7m-none-eabi.dependencies.stage1] +stage = 1 +path = "stage1" "#, )?; project.build(TARGET)?; assert!(exists("core", TARGET)?); assert!(exists("alloc", TARGET)?); - + assert!(exists("stage1", TARGET)?); Ok(()) } From edddc171a17cb7e4b8eb4557b3d41e1739d179d3 Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Thu, 17 Oct 2019 14:45:58 +0000 Subject: [PATCH 4/4] Document changes for relative paths support in Xargo.toml --- src/sysroot.rs | 4 ++++ src/xargo.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/sysroot.rs b/src/sysroot.rs index 9a095fc..dd60684 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -233,6 +233,10 @@ pub fn update( let ctoml = cargo::toml(root)?; let (xtoml_parent, xtoml) = xargo::toml(root)?; + // As paths in the 'Xargo.toml' can be relative to the directory containing + // the 'Xargo.toml', we need to pass the path containing it to the + // Blueprint. Otherwise, if no 'Xargo.toml' is found, we use the regular + // root path. let base_path: &Path = xtoml_parent.unwrap_or_else(|| root.path()); let blueprint = Blueprint::from(xtoml.as_ref(), cmode.triple(), &base_path, &src)?; diff --git a/src/xargo.rs b/src/xargo.rs index ad97f9f..c56d203 100644 --- a/src/xargo.rs +++ b/src/xargo.rs @@ -120,6 +120,8 @@ impl Toml { } } +/// Returns the closest directory containing a 'Xargo.toml' and the parsed +/// content of this 'Xargo.toml' pub fn toml(root: &Root) -> Result<(Option<&Path>, Option)> { if let Some(p) = util::search(root.path(), "Xargo.toml") { Ok((Some(p), util::parse(&p.join("Xargo.toml")).map(|t| Some(Toml { table: t }))?))