Skip to content

Commit 15e1259

Browse files
authored
fix(cli): parse cargo--target-dir flag (#10234)
* fix(cli): parse cargo`--target-dir` flag closes #10190 * clippy
1 parent b4e16f3 commit 15e1259

File tree

3 files changed

+142
-31
lines changed

3 files changed

+142
-31
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri-cli": "patch:bug"
3+
"@tauri-apps/cli": "patch:bug"
4+
---
5+
6+
Fix cli failing to detect the correct cargo target directory when using cargo `--target-dir` flag with `tauri build` or `tauri dev`

tooling/cli/src/interface/rust.rs

Lines changed: 134 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,7 @@ impl AppSettings for RustAppSettings {
858858
let bin_name = self.cargo_package_settings().name.clone();
859859

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

864864
let binary_extension: String = if self.target_triple.contains("windows") {
@@ -1081,13 +1081,15 @@ impl RustAppSettings {
10811081
&self.cargo_package_settings
10821082
}
10831083

1084-
pub fn out_dir(&self, target: Option<String>, profile: String) -> crate::Result<PathBuf> {
1085-
get_target_dir(
1086-
target
1087-
.as_deref()
1088-
.or_else(|| self.cargo_config.build().target()),
1089-
profile,
1090-
)
1084+
fn target<'a>(&'a self, options: &'a Options) -> Option<&'a str> {
1085+
options
1086+
.target
1087+
.as_deref()
1088+
.or_else(|| self.cargo_config.build().target())
1089+
}
1090+
1091+
pub fn out_dir(&self, options: &Options) -> crate::Result<PathBuf> {
1092+
get_target_dir(self.target(options), options)
10911093
}
10921094
}
10931095

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

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

1123-
if let Some(triple) = target {
1124-
path.push(triple);
1125-
}
1128+
if let Some(triple) = triple {
1129+
path.push(triple);
1130+
}
1131+
1132+
path
1133+
};
11261134

1127-
path.push(profile);
1135+
path.push(get_profile_dir(options));
11281136

11291137
Ok(path)
11301138
}
11311139

1140+
#[inline]
1141+
fn get_cargo_option<'a>(args: &'a [String], option: &'a str) -> Option<&'a str> {
1142+
args
1143+
.iter()
1144+
.position(|a| a.starts_with(option))
1145+
.and_then(|i| {
1146+
args[i]
1147+
.split_once('=')
1148+
.map(|(_, p)| Some(p))
1149+
.unwrap_or_else(|| args.get(i + 1).map(|s| s.as_str()))
1150+
})
1151+
}
1152+
11321153
/// Executes `cargo metadata` to get the workspace directory.
11331154
pub fn get_workspace_dir() -> crate::Result<PathBuf> {
11341155
Ok(
@@ -1139,17 +1160,11 @@ pub fn get_workspace_dir() -> crate::Result<PathBuf> {
11391160
}
11401161

11411162
pub fn get_profile(options: &Options) -> &str {
1142-
options
1143-
.args
1144-
.iter()
1145-
.position(|a| a.starts_with("--profile"))
1146-
.and_then(|i| {
1147-
options.args[i]
1148-
.split_once('=')
1149-
.map(|(_, p)| Some(p))
1150-
.unwrap_or_else(|| options.args.get(i + 1).map(|s| s.as_str()))
1151-
})
1152-
.unwrap_or(if options.debug { "dev" } else { "release" })
1163+
get_cargo_option(&options.args, "--profile").unwrap_or(if options.debug {
1164+
"dev"
1165+
} else {
1166+
"release"
1167+
})
11531168
}
11541169

11551170
pub fn get_profile_dir(options: &Options) -> &str {
@@ -1479,6 +1494,25 @@ mod pkgconfig_utils {
14791494
mod tests {
14801495
use super::*;
14811496

1497+
#[test]
1498+
fn parse_cargo_option() {
1499+
let args = vec![
1500+
"build".into(),
1501+
"--".into(),
1502+
"--profile".into(),
1503+
"holla".into(),
1504+
"--features".into(),
1505+
"a".into(),
1506+
"b".into(),
1507+
"--target-dir".into(),
1508+
"path/to/dir".into(),
1509+
];
1510+
1511+
assert_eq!(get_cargo_option(&args, "--profile"), Some("holla"));
1512+
assert_eq!(get_cargo_option(&args, "--target-dir"), Some("path/to/dir"));
1513+
assert_eq!(get_cargo_option(&args, "--non-existent"), None);
1514+
}
1515+
14821516
#[test]
14831517
fn parse_profile_from_opts() {
14841518
let options = Options {
@@ -1539,4 +1573,77 @@ mod tests {
15391573
};
15401574
assert_eq!(get_profile(&options), "release");
15411575
}
1576+
1577+
#[test]
1578+
fn parse_target_dir_from_opts() {
1579+
let current_dir = std::env::current_dir().unwrap();
1580+
1581+
let options = Options {
1582+
args: vec![
1583+
"build".into(),
1584+
"--".into(),
1585+
"--target-dir".into(),
1586+
"path/to/some/dir".into(),
1587+
"--features".into(),
1588+
"feat1".into(),
1589+
],
1590+
debug: false,
1591+
..Default::default()
1592+
};
1593+
1594+
assert_eq!(
1595+
get_target_dir(None, &options).unwrap(),
1596+
current_dir.join("path/to/some/dir/release")
1597+
);
1598+
assert_eq!(
1599+
get_target_dir(Some("x86_64-pc-windows-msvc"), &options).unwrap(),
1600+
current_dir.join("path/to/some/dir/release")
1601+
);
1602+
1603+
let options = Options {
1604+
args: vec![
1605+
"build".into(),
1606+
"--".into(),
1607+
"--features".into(),
1608+
"feat1".into(),
1609+
],
1610+
debug: false,
1611+
..Default::default()
1612+
};
1613+
1614+
#[cfg(windows)]
1615+
assert!(get_target_dir(Some("x86_64-pc-windows-msvc"), &options)
1616+
.unwrap()
1617+
.ends_with("x86_64-pc-windows-msvc\\release"));
1618+
#[cfg(not(windows))]
1619+
assert!(get_target_dir(Some("x86_64-pc-windows-msvc"), &options)
1620+
.unwrap()
1621+
.ends_with("x86_64-pc-windows-msvc/release"));
1622+
1623+
#[cfg(windows)]
1624+
{
1625+
std::env::set_var("CARGO_TARGET_DIR", "D:\\path\\to\\env\\dir");
1626+
assert_eq!(
1627+
get_target_dir(None, &options).unwrap(),
1628+
PathBuf::from("D:\\path\\to\\env\\dir\\release")
1629+
);
1630+
assert_eq!(
1631+
get_target_dir(Some("x86_64-pc-windows-msvc"), &options).unwrap(),
1632+
PathBuf::from("D:\\path\\to\\env\\dir\\x86_64-pc-windows-msvc\\release")
1633+
);
1634+
}
1635+
1636+
#[cfg(not(windows))]
1637+
{
1638+
std::env::set_var("CARGO_TARGET_DIR", "/path/to/env/dir");
1639+
assert_eq!(
1640+
get_target_dir(None, &options).unwrap(),
1641+
PathBuf::from("/path/to/env/dir/release")
1642+
);
1643+
assert_eq!(
1644+
get_target_dir(Some("x86_64-pc-windows-msvc"), &options).unwrap(),
1645+
PathBuf::from("/path/to/env/dir/x86_64-pc-windows-msvc/release")
1646+
);
1647+
}
1648+
}
15421649
}

tooling/cli/src/interface/rust/desktop.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
use super::{
6-
get_profile_dir, AppSettings, DevProcess, ExitReason, Options, RustAppSettings, RustupTarget,
7-
};
5+
use super::{AppSettings, DevProcess, ExitReason, Options, RustAppSettings, RustupTarget};
86
use crate::CommandExt;
97

108
use anyhow::Context;
@@ -144,7 +142,7 @@ pub fn build(
144142
options.target.replace(triple.into());
145143

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

150148
build_production_app(options, available_targets, config_features.clone())

0 commit comments

Comments
 (0)