Skip to content

Commit b52da29

Browse files
fix: main binary name can't contain dots (#13429)
* fix: main binary name can't contain dots * Revert the change in tauri.conf.json * Change file * Use target platform when matching extension
1 parent 574a4d4 commit b52da29

File tree

11 files changed

+121
-79
lines changed

11 files changed

+121
-79
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri-utils": "patch:bug"
3+
"tauri-bundler": "patch:bug"
4+
---
5+
6+
Fix `mainBinaryName` doesn't work when there's `.` in it

crates/tauri-build/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
528528

529529
if let Some(paths) = &config.bundle.external_bin {
530530
copy_binaries(
531-
ResourcePaths::new(external_binaries(paths, &target_triple).as_slice(), true),
531+
ResourcePaths::new(&external_binaries(paths, &target_triple, &target), true),
532532
&target_triple,
533533
target_dir,
534534
manifest.package.as_ref().map(|p| &p.name),

crates/tauri-bundler/src/bundle.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod settings;
1313
mod updater_bundle;
1414
mod windows;
1515

16-
use tauri_utils::display_path;
16+
use tauri_utils::{display_path, platform::Target as TargetPlatform};
1717

1818
pub use self::{
1919
category::AppCategory,
@@ -48,19 +48,14 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<Bundle>> {
4848

4949
package_types.sort_by_key(|a| a.priority());
5050

51-
let target_os = settings
52-
.target()
53-
.split('-')
54-
.nth(2)
55-
.unwrap_or(std::env::consts::OS)
56-
.replace("darwin", "macos");
51+
let target_os = settings.target_platform();
5752

58-
if target_os != std::env::consts::OS {
53+
if *target_os != TargetPlatform::current() {
5954
log::warn!("Cross-platform compilation is experimental and does not support all features. Please use a matching host system for full compatibility.");
6055
}
6156

6257
// Sign windows binaries before the bundling step in case neither wix and nsis bundles are enabled
63-
if target_os == "windows" {
58+
if matches!(target_os, TargetPlatform::Windows) {
6459
if settings.can_sign() {
6560
for bin in settings.binaries() {
6661
let bin_path = settings.binary_path(bin);

crates/tauri-bundler/src/bundle/settings.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use tauri_utils::{
1212
BundleType, DeepLinkProtocol, FileAssociation, NSISInstallerMode, NsisCompression,
1313
RpmCompression,
1414
},
15+
platform::Target as TargetPlatform,
1516
resources::{external_binaries, ResourcePaths},
1617
};
1718

@@ -760,6 +761,8 @@ pub struct Settings {
760761
bundle_settings: BundleSettings,
761762
/// the binaries to bundle.
762763
binaries: Vec<BundleBinary>,
764+
/// The target platform.
765+
target_platform: TargetPlatform,
763766
/// The target triple.
764767
target: String,
765768
}
@@ -855,6 +858,7 @@ impl SettingsBuilder {
855858
} else {
856859
target_triple()?
857860
};
861+
let target_platform = TargetPlatform::from_triple(&target);
858862

859863
Ok(Settings {
860864
log_level: self.log_level.unwrap_or(log::Level::Error),
@@ -872,9 +876,10 @@ impl SettingsBuilder {
872876
.bundle_settings
873877
.external_bin
874878
.as_ref()
875-
.map(|bins| external_binaries(bins, &target)),
879+
.map(|bins| external_binaries(bins, &target, &target_platform)),
876880
..self.bundle_settings
877881
},
882+
target_platform,
878883
target,
879884
})
880885
}
@@ -901,6 +906,11 @@ impl Settings {
901906
&self.target
902907
}
903908

909+
/// Returns the [`TargetPlatform`].
910+
pub fn target_platform(&self) -> &TargetPlatform {
911+
&self.target_platform
912+
}
913+
904914
/// Returns the architecture for the binary being bundled (e.g. "arm", "x86" or "x86_64").
905915
pub fn binary_arch(&self) -> Arch {
906916
if self.target.starts_with("x86_64") {
@@ -955,19 +965,23 @@ impl Settings {
955965

956966
/// Returns the path to the specified binary.
957967
pub fn binary_path(&self, binary: &BundleBinary) -> PathBuf {
958-
let target_os = self
959-
.target()
960-
.split('-')
961-
.nth(2)
962-
.unwrap_or(std::env::consts::OS);
963-
964-
let path = self.project_out_directory.join(binary.name());
968+
let target_os = self.target_platform();
969+
970+
let mut path = self.project_out_directory.join(binary.name());
971+
972+
if matches!(target_os, TargetPlatform::Windows) {
973+
// Append the `.exe` extension without overriding the existing extensions
974+
let extension = if let Some(extension) = path.extension() {
975+
let mut extension = extension.to_os_string();
976+
extension.push(".exe");
977+
extension
978+
} else {
979+
"exe".into()
980+
};
981+
path.set_extension(extension);
982+
};
965983

966-
if target_os == "windows" {
967-
path.with_extension("exe")
968-
} else {
969-
path
970-
}
984+
path
971985
}
972986

973987
/// Returns the list of binaries to bundle.
@@ -985,18 +999,13 @@ impl Settings {
985999
///
9861000
/// Fails if the host/target's native package type is not supported.
9871001
pub fn package_types(&self) -> crate::Result<Vec<PackageType>> {
988-
let target_os = self
989-
.target
990-
.split('-')
991-
.nth(2)
992-
.unwrap_or(std::env::consts::OS)
993-
.replace("darwin", "macos");
994-
995-
let platform_types = match target_os.as_str() {
996-
"macos" => vec![PackageType::MacOsBundle, PackageType::Dmg],
997-
"ios" => vec![PackageType::IosBundle],
998-
"linux" => vec![PackageType::Deb, PackageType::Rpm, PackageType::AppImage],
999-
"windows" => vec![PackageType::WindowsMsi, PackageType::Nsis],
1002+
let target_os = self.target_platform();
1003+
1004+
let platform_types = match target_os {
1005+
TargetPlatform::MacOS => vec![PackageType::MacOsBundle, PackageType::Dmg],
1006+
TargetPlatform::Ios => vec![PackageType::IosBundle],
1007+
TargetPlatform::Linux => vec![PackageType::Deb, PackageType::Rpm, PackageType::AppImage],
1008+
TargetPlatform::Windows => vec![PackageType::WindowsMsi, PackageType::Nsis],
10001009
os => {
10011010
return Err(crate::Error::GenericError(format!(
10021011
"Native {os} bundles not yet supported."

crates/tauri-bundler/src/bundle/updater_bundle.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
utils::fs_utils,
1515
Settings,
1616
};
17-
use tauri_utils::display_path;
17+
use tauri_utils::{display_path, platform::Target as TargetPlatform};
1818

1919
use std::{
2020
fs::{self, File},
@@ -27,14 +27,9 @@ use zip::write::SimpleFileOptions;
2727

2828
// Build update
2929
pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result<Vec<PathBuf>> {
30-
let target_os = settings
31-
.target()
32-
.split('-')
33-
.nth(2)
34-
.unwrap_or(std::env::consts::OS)
35-
.replace("darwin", "macos");
36-
37-
if target_os == "windows" {
30+
let target_os = settings.target_platform();
31+
32+
if matches!(target_os, TargetPlatform::Windows) {
3833
return bundle_update_windows(settings, bundles);
3934
}
4035

crates/tauri-cli/config.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"pattern": "^[^/\\:*?\"<>|]+$"
2525
},
2626
"mainBinaryName": {
27-
"description": "App main binary filename. Defaults to the name of your cargo crate.",
27+
"description": "Overrides app's main binary filename.\n\n By default, Tauri uses the output binary from `cargo`, by setting this, we will rename that binary in `tauri-cli`'s\n `tauri build` command, and target `tauri bundle` to it\n\n If possible, change the [`package name`] or set the [`name field`] instead,\n and if that's not enough and you're using nightly, consider using the [`different-binary-name`] feature instead\n\n Note: this config should not include the binary extension (e.g. `.exe`), we'll add that for you\n\n [`package name`]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field\n [`name field`]: https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-name-field\n [`different-binary-name`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#different-binary-name",
2828
"type": [
2929
"string",
3030
"null"

crates/tauri-cli/src/interface/rust.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::{
3535
},
3636
ConfigValue,
3737
};
38-
use tauri_utils::{display_path, platform::Target};
38+
use tauri_utils::{display_path, platform::Target as TargetPlatform};
3939

4040
mod cargo_config;
4141
mod desktop;
@@ -529,7 +529,7 @@ impl Rust {
529529

530530
if let Some(event_path) = event.paths.first() {
531531
if !ignore_matcher.is_ignore(event_path, event_path.is_dir()) {
532-
if is_configuration_file(self.app_settings.target, event_path) {
532+
if is_configuration_file(self.app_settings.target_platform, event_path) {
533533
if let Ok(config) = reload_config(merge_configs) {
534534
let (manifest, modified) =
535535
rewrite_manifest(config.lock().unwrap().as_ref().unwrap())?;
@@ -643,9 +643,18 @@ struct WorkspacePackageSettings {
643643
#[derive(Clone, Debug, Deserialize)]
644644
struct BinarySettings {
645645
name: String,
646+
/// This is from nightly: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#different-binary-name
647+
filename: Option<String>,
646648
path: Option<String>,
647649
}
648650

651+
impl BinarySettings {
652+
/// The file name without the binary extension (e.g. `.exe`)
653+
pub fn file_name(&self) -> &str {
654+
self.filename.as_ref().unwrap_or(&self.name)
655+
}
656+
}
657+
649658
/// The package settings.
650659
#[derive(Debug, Clone, Deserialize)]
651660
#[serde(rename_all = "kebab-case")]
@@ -699,7 +708,7 @@ pub struct RustAppSettings {
699708
package_settings: PackageSettings,
700709
cargo_config: CargoConfig,
701710
target_triple: String,
702-
target: Target,
711+
target_platform: TargetPlatform,
703712
}
704713

705714
#[derive(Deserialize)]
@@ -866,13 +875,19 @@ impl AppSettings for RustAppSettings {
866875
.out_dir(options)
867876
.context("failed to get project out directory")?;
868877

869-
let ext = if self.target_triple.contains("windows") {
870-
"exe"
871-
} else {
872-
""
878+
let mut path = out_dir.join(bin_name);
879+
if matches!(self.target_platform, TargetPlatform::Windows) {
880+
// Append the `.exe` extension without overriding the existing extensions
881+
let extension = if let Some(extension) = path.extension() {
882+
let mut extension = extension.to_os_string();
883+
extension.push(".exe");
884+
extension
885+
} else {
886+
"exe".into()
887+
};
888+
path.set_extension(extension);
873889
};
874-
875-
Ok(out_dir.join(bin_name).with_extension(ext))
890+
Ok(path)
876891
}
877892

878893
fn get_binaries(&self) -> crate::Result<Vec<BundleBinary>> {
@@ -885,9 +900,10 @@ impl AppSettings for RustAppSettings {
885900
.clone()
886901
.unwrap_or_default();
887902
for bin in bins {
888-
let is_main = bin.name == self.cargo_package_settings.name || bin.name == default_run;
903+
let file_name = bin.file_name();
904+
let is_main = file_name == self.cargo_package_settings.name || file_name == default_run;
889905
binaries.push(BundleBinary::with_path(
890-
bin.name.clone(),
906+
file_name.to_owned(),
891907
is_main,
892908
bin.path.clone(),
893909
))
@@ -1087,7 +1103,7 @@ impl RustAppSettings {
10871103
.to_string()
10881104
})
10891105
});
1090-
let target = Target::from_triple(&target_triple);
1106+
let target = TargetPlatform::from_triple(&target_triple);
10911107

10921108
Ok(Self {
10931109
manifest: Mutex::new(manifest),
@@ -1097,7 +1113,7 @@ impl RustAppSettings {
10971113
package_settings,
10981114
cargo_config,
10991115
target_triple,
1100-
target,
1116+
target_platform: target,
11011117
})
11021118
}
11031119

crates/tauri-cli/src/interface/rust/desktop.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::{
1717
Arc, Mutex,
1818
},
1919
};
20+
use tauri_utils::platform::Target as TargetPlatform;
2021

2122
pub struct DevChild {
2223
manually_killed_app: Arc<AtomicBool>,
@@ -188,16 +189,16 @@ pub fn build(
188189

189190
let lipo_status = lipo_cmd.output_ok()?.status;
190191
if !lipo_status.success() {
191-
return Err(anyhow::anyhow!(format!(
192+
return Err(anyhow::anyhow!(
192193
"Result of `lipo` command was unsuccessful: {lipo_status}. (Is `lipo` installed?)"
193-
)));
194+
));
194195
}
195196
} else {
196197
build_production_app(options, available_targets, config_features)
197198
.with_context(|| "failed to build app")?;
198199
}
199200

200-
rename_app(bin_path, main_binary_name)
201+
rename_app(bin_path, main_binary_name, &app_settings.target_platform)
201202
}
202203

203204
fn build_production_app(
@@ -305,12 +306,18 @@ fn validate_target(
305306
Ok(())
306307
}
307308

308-
fn rename_app(bin_path: PathBuf, main_binary_name: Option<&str>) -> crate::Result<PathBuf> {
309+
fn rename_app(
310+
bin_path: PathBuf,
311+
main_binary_name: Option<&str>,
312+
target_platform: &TargetPlatform,
313+
) -> crate::Result<PathBuf> {
309314
if let Some(main_binary_name) = main_binary_name {
310-
let new_path = bin_path
311-
.with_file_name(main_binary_name)
312-
.with_extension(bin_path.extension().unwrap_or_default());
313-
315+
let extension = if matches!(target_platform, TargetPlatform::Windows) {
316+
".exe"
317+
} else {
318+
""
319+
};
320+
let new_path = bin_path.with_file_name(format!("{main_binary_name}{extension}"));
314321
fs::rename(&bin_path, &new_path).with_context(|| {
315322
format!(
316323
"failed to rename `{}` to `{}`",

crates/tauri-schema-generator/schemas/config.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"pattern": "^[^/\\:*?\"<>|]+$"
2525
},
2626
"mainBinaryName": {
27-
"description": "App main binary filename. Defaults to the name of your cargo crate.",
27+
"description": "Overrides app's main binary filename.\n\n By default, Tauri uses the output binary from `cargo`, by setting this, we will rename that binary in `tauri-cli`'s\n `tauri build` command, and target `tauri bundle` to it\n\n If possible, change the [`package name`] or set the [`name field`] instead,\n and if that's not enough and you're using nightly, consider using the [`different-binary-name`] feature instead\n\n Note: this config should not include the binary extension (e.g. `.exe`), we'll add that for you\n\n [`package name`]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field\n [`name field`]: https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-name-field\n [`different-binary-name`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#different-binary-name",
2828
"type": [
2929
"string",
3030
"null"

crates/tauri-utils/src/config.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2946,7 +2946,19 @@ pub struct Config {
29462946
#[serde(alias = "product-name")]
29472947
#[cfg_attr(feature = "schema", validate(regex(pattern = "^[^/\\:*?\"<>|]+$")))]
29482948
pub product_name: Option<String>,
2949-
/// App main binary filename. Defaults to the name of your cargo crate.
2949+
/// Overrides app's main binary filename.
2950+
///
2951+
/// By default, Tauri uses the output binary from `cargo`, by setting this, we will rename that binary in `tauri-cli`'s
2952+
/// `tauri build` command, and target `tauri bundle` to it
2953+
///
2954+
/// If possible, change the [`package name`] or set the [`name field`] instead,
2955+
/// and if that's not enough and you're using nightly, consider using the [`different-binary-name`] feature instead
2956+
///
2957+
/// Note: this config should not include the binary extension (e.g. `.exe`), we'll add that for you
2958+
///
2959+
/// [`package name`]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field
2960+
/// [`name field`]: https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-name-field
2961+
/// [`different-binary-name`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#different-binary-name
29502962
#[serde(alias = "main-binary-name")]
29512963
pub main_binary_name: Option<String>,
29522964
/// App version. It is a semver version number or a path to a `package.json` file containing the `version` field.

0 commit comments

Comments
 (0)