Skip to content

Commit

Permalink
fix(cli): parse cargo--target-dir flag (#10234)
Browse files Browse the repository at this point in the history
* fix(cli): parse cargo`--target-dir` flag

closes #10190

* clippy
  • Loading branch information
amrbashir authored Jul 10, 2024
1 parent b4e16f3 commit 15e1259
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 31 deletions.
6 changes: 6 additions & 0 deletions .changes/cli-target-dir-cargo-cli-flag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-cli": "patch:bug"
"@tauri-apps/cli": "patch:bug"
---

Fix cli failing to detect the correct cargo target directory when using cargo `--target-dir` flag with `tauri build` or `tauri dev`
161 changes: 134 additions & 27 deletions tooling/cli/src/interface/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ impl AppSettings for RustAppSettings {
let bin_name = self.cargo_package_settings().name.clone();

let out_dir = self
.out_dir(options.target.clone(), get_profile_dir(options).to_string())
.out_dir(options)
.with_context(|| "failed to get project out directory")?;

let binary_extension: String = if self.target_triple.contains("windows") {
Expand Down Expand Up @@ -1081,13 +1081,15 @@ impl RustAppSettings {
&self.cargo_package_settings
}

pub fn out_dir(&self, target: Option<String>, profile: String) -> crate::Result<PathBuf> {
get_target_dir(
target
.as_deref()
.or_else(|| self.cargo_config.build().target()),
profile,
)
fn target<'a>(&'a self, options: &'a Options) -> Option<&'a str> {
options
.target
.as_deref()
.or_else(|| self.cargo_config.build().target())
}

pub fn out_dir(&self, options: &Options) -> crate::Result<PathBuf> {
get_target_dir(self.target(options), options)
}
}

Expand Down Expand Up @@ -1115,20 +1117,39 @@ fn get_cargo_metadata() -> crate::Result<CargoMetadata> {

/// This function determines the 'target' directory and suffixes it with the profile
/// to determine where the compiled binary will be located.
fn get_target_dir(target: Option<&str>, profile: String) -> crate::Result<PathBuf> {
let mut path = get_cargo_metadata()
.with_context(|| "failed to get cargo metadata")?
.target_directory;
fn get_target_dir(triple: Option<&str>, options: &Options) -> crate::Result<PathBuf> {
let mut path = if let Some(target) = get_cargo_option(&options.args, "--target-dir") {
std::env::current_dir()?.join(target)
} else {
let mut path = get_cargo_metadata()
.with_context(|| "failed to get cargo metadata")?
.target_directory;

if let Some(triple) = target {
path.push(triple);
}
if let Some(triple) = triple {
path.push(triple);
}

path
};

path.push(profile);
path.push(get_profile_dir(options));

Ok(path)
}

#[inline]
fn get_cargo_option<'a>(args: &'a [String], option: &'a str) -> Option<&'a str> {
args
.iter()
.position(|a| a.starts_with(option))
.and_then(|i| {
args[i]
.split_once('=')
.map(|(_, p)| Some(p))
.unwrap_or_else(|| args.get(i + 1).map(|s| s.as_str()))
})
}

/// Executes `cargo metadata` to get the workspace directory.
pub fn get_workspace_dir() -> crate::Result<PathBuf> {
Ok(
Expand All @@ -1139,17 +1160,11 @@ pub fn get_workspace_dir() -> crate::Result<PathBuf> {
}

pub fn get_profile(options: &Options) -> &str {
options
.args
.iter()
.position(|a| a.starts_with("--profile"))
.and_then(|i| {
options.args[i]
.split_once('=')
.map(|(_, p)| Some(p))
.unwrap_or_else(|| options.args.get(i + 1).map(|s| s.as_str()))
})
.unwrap_or(if options.debug { "dev" } else { "release" })
get_cargo_option(&options.args, "--profile").unwrap_or(if options.debug {
"dev"
} else {
"release"
})
}

pub fn get_profile_dir(options: &Options) -> &str {
Expand Down Expand Up @@ -1479,6 +1494,25 @@ mod pkgconfig_utils {
mod tests {
use super::*;

#[test]
fn parse_cargo_option() {
let args = vec![
"build".into(),
"--".into(),
"--profile".into(),
"holla".into(),
"--features".into(),
"a".into(),
"b".into(),
"--target-dir".into(),
"path/to/dir".into(),
];

assert_eq!(get_cargo_option(&args, "--profile"), Some("holla"));
assert_eq!(get_cargo_option(&args, "--target-dir"), Some("path/to/dir"));
assert_eq!(get_cargo_option(&args, "--non-existent"), None);
}

#[test]
fn parse_profile_from_opts() {
let options = Options {
Expand Down Expand Up @@ -1539,4 +1573,77 @@ mod tests {
};
assert_eq!(get_profile(&options), "release");
}

#[test]
fn parse_target_dir_from_opts() {
let current_dir = std::env::current_dir().unwrap();

let options = Options {
args: vec![
"build".into(),
"--".into(),
"--target-dir".into(),
"path/to/some/dir".into(),
"--features".into(),
"feat1".into(),
],
debug: false,
..Default::default()
};

assert_eq!(
get_target_dir(None, &options).unwrap(),
current_dir.join("path/to/some/dir/release")
);
assert_eq!(
get_target_dir(Some("x86_64-pc-windows-msvc"), &options).unwrap(),
current_dir.join("path/to/some/dir/release")
);

let options = Options {
args: vec![
"build".into(),
"--".into(),
"--features".into(),
"feat1".into(),
],
debug: false,
..Default::default()
};

#[cfg(windows)]
assert!(get_target_dir(Some("x86_64-pc-windows-msvc"), &options)
.unwrap()
.ends_with("x86_64-pc-windows-msvc\\release"));
#[cfg(not(windows))]
assert!(get_target_dir(Some("x86_64-pc-windows-msvc"), &options)
.unwrap()
.ends_with("x86_64-pc-windows-msvc/release"));

#[cfg(windows)]
{
std::env::set_var("CARGO_TARGET_DIR", "D:\\path\\to\\env\\dir");
assert_eq!(
get_target_dir(None, &options).unwrap(),
PathBuf::from("D:\\path\\to\\env\\dir\\release")
);
assert_eq!(
get_target_dir(Some("x86_64-pc-windows-msvc"), &options).unwrap(),
PathBuf::from("D:\\path\\to\\env\\dir\\x86_64-pc-windows-msvc\\release")
);
}

#[cfg(not(windows))]
{
std::env::set_var("CARGO_TARGET_DIR", "/path/to/env/dir");
assert_eq!(
get_target_dir(None, &options).unwrap(),
PathBuf::from("/path/to/env/dir/release")
);
assert_eq!(
get_target_dir(Some("x86_64-pc-windows-msvc"), &options).unwrap(),
PathBuf::from("/path/to/env/dir/x86_64-pc-windows-msvc/release")
);
}
}
}
6 changes: 2 additions & 4 deletions tooling/cli/src/interface/rust/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use super::{
get_profile_dir, AppSettings, DevProcess, ExitReason, Options, RustAppSettings, RustupTarget,
};
use super::{AppSettings, DevProcess, ExitReason, Options, RustAppSettings, RustupTarget};
use crate::CommandExt;

use anyhow::Context;
Expand Down Expand Up @@ -144,7 +142,7 @@ pub fn build(
options.target.replace(triple.into());

let triple_out_dir = app_settings
.out_dir(Some(triple.into()), get_profile_dir(&options).to_string())
.out_dir(&options)
.with_context(|| format!("failed to get {triple} out dir"))?;

build_production_app(options, available_targets, config_features.clone())
Expand Down

0 comments on commit 15e1259

Please sign in to comment.