diff --git a/.changes/target-dir-nightly-out-dir.md b/.changes/target-dir-nightly-out-dir.md new file mode 100644 index 000000000000..7eade8ec1b13 --- /dev/null +++ b/.changes/target-dir-nightly-out-dir.md @@ -0,0 +1,5 @@ +--- +'tauri-build': 'patch:bug' +--- + +Resolve the target directory by walking up from `OUT_DIR` to the `build` directory instead of assuming it is exactly three levels up. Recent nightly toolchains add another level to `OUT_DIR`, which made sidecars and resources land in `target/debug/build` instead of `target/debug`. diff --git a/crates/tauri-build/src/lib.rs b/crates/tauri-build/src/lib.rs index 9c3a8d29172c..c5e4a5ddd4e1 100644 --- a/crates/tauri-build/src/lib.rs +++ b/crates/tauri-build/src/lib.rs @@ -21,7 +21,9 @@ use tauri_utils::{ use std::{ collections::HashMap, - env, fs, + env, + ffi::OsStr, + fs, path::{Path, PathBuf}, }; @@ -205,6 +207,17 @@ fn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> { Ok(()) } +// TODO: far from ideal, but there's no other way to get the target dir, see +// resolves the target dir from `OUT_DIR`, which is `/build/-/out` on stable +// and `/build///out` on recent nightlies, so we walk up to the `build` dir +// and take its parent instead of assuming a fixed depth. +fn target_dir_from_out_dir(out_dir: &Path) -> Option<&Path> { + out_dir + .ancestors() + .find(|path| path.file_name() == Some(OsStr::new("build"))) + .and_then(|build_dir| build_dir.parent()) +} + // creates a cfg alias if `has_feature` is true. // `alias` must be a snake case string. fn cfg_alias(alias: &str, has_feature: bool) { @@ -573,14 +586,8 @@ pub fn try_build(attributes: Attributes) -> Result<()> { // when running codegen in this build script, we need to access the env var directly env::set_var("TAURI_ENV_TARGET_TRIPLE", &target_triple); - // TODO: far from ideal, but there's no other way to get the target dir, see - let target_dir = out_dir - .parent() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap(); + let target_dir = target_dir_from_out_dir(&out_dir) + .with_context(|| format!("failed to resolve the target directory from {out_dir:?}"))?; if let Some(paths) = &config.bundle.external_bin { copy_binaries( @@ -785,6 +792,38 @@ fn should_static_link_vc_runtime(config: &Config, attributes: &Attributes) -> bo #[cfg(test)] mod tests { use semver::Version; + use std::path::Path; + + #[test] + fn target_dir_from_stable_out_dir() { + let out_dir = Path::new("/app/target/debug/build/app-63ba68eead531e35/out"); + + assert_eq!( + crate::target_dir_from_out_dir(out_dir), + Some(Path::new("/app/target/debug")) + ); + } + + #[test] + fn target_dir_from_nightly_out_dir() { + let out_dir = Path::new("/app/target/debug/build/app/63ba68eead531e35/out"); + + assert_eq!( + crate::target_dir_from_out_dir(out_dir), + Some(Path::new("/app/target/debug")) + ); + } + + #[test] + fn target_dir_from_out_dir_with_triple() { + let out_dir = + Path::new("/app/target/aarch64-apple-darwin/release/build/app/63ba68eead531e35/out"); + + assert_eq!( + crate::target_dir_from_out_dir(out_dir), + Some(Path::new("/app/target/aarch64-apple-darwin/release")) + ); + } #[test] fn version_uses_numeric_build_metadata() {