mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-11-30 18:46:27 +03:00
feat: add mainBinaryName
option (#10977)
* feat: add `mainBinaryName` option * remove unused imports [skip ci] * enhance error message [skip ci] * migrate `mainBinaryName` * change file * revert bin src_path * add link --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
parent
3ad2427dc0
commit
35bd9dd3dc
5
.changes/changelog-path-deb.md
Normal file
5
.changes/changelog-path-deb.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'tauri-bundler': 'major:breaking'
|
||||
---
|
||||
|
||||
Changed changelog file location in `deb` to `usr/share/doc/<product_name>/changelog.gz` instead of `usr/share/doc/<main_binary_name>/changelog.gz`. For tauri v1 users, the path is unchanged as `product_name` and `main_binary_name` used the same value.
|
8
.changes/main_binary_name.md
Normal file
8
.changes/main_binary_name.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
"tauri": "patch:feat"
|
||||
"tauri-utils": "patch:feat"
|
||||
"tauri-cli": "patch:feat"
|
||||
"tauri-bundler": "patch:feat"
|
||||
---
|
||||
|
||||
Add `mainBinaryName` config option to set the file name for the main binary.
|
5
.changes/resources-path-deb-rpm.md
Normal file
5
.changes/resources-path-deb-rpm.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'tauri-bundler': 'major:breaking'
|
||||
---
|
||||
|
||||
Changed resources directory location in `deb` and `rpm` to `/usr/lib/<product_name>` instead of `/usr/lib/<main_binary_name>`. For tauri v1 users, the path is unchanged as `product_name` and `main_binary_name` used the same value.
|
@ -56,7 +56,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
|
||||
// setup data to insert into shell script
|
||||
let mut sh_map = BTreeMap::new();
|
||||
sh_map.insert("arch", settings.target().split('-').next().unwrap());
|
||||
sh_map.insert("crate_name", settings.main_binary_name());
|
||||
sh_map.insert("product_name", settings.product_name());
|
||||
sh_map.insert("appimage_filename", &appimage_filename);
|
||||
|
||||
let tauri_tools_path = settings
|
||||
|
@ -133,8 +133,8 @@ pub fn generate_data(
|
||||
fn generate_changelog_file(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
|
||||
if let Some(changelog_src_path) = &settings.deb().changelog {
|
||||
let mut src_file = File::open(changelog_src_path)?;
|
||||
let bin_name = settings.main_binary_name();
|
||||
let dest_path = data_dir.join(format!("usr/share/doc/{}/changelog.gz", bin_name));
|
||||
let product_name = settings.product_name();
|
||||
let dest_path = data_dir.join(format!("usr/share/doc/{product_name}/changelog.gz"));
|
||||
|
||||
let changelog_file = common::create_file(&dest_path)?;
|
||||
let mut gzip_encoder = GzEncoder::new(changelog_file, Compression::new(9));
|
||||
@ -306,7 +306,7 @@ fn generate_md5sums(control_dir: &Path, data_dir: &Path) -> crate::Result<()> {
|
||||
/// Copy the bundle's resource files into an appropriate directory under the
|
||||
/// `data_dir`.
|
||||
fn copy_resource_files(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
|
||||
let resource_dir = data_dir.join("usr/lib").join(settings.main_binary_name());
|
||||
let resource_dir = data_dir.join("usr/lib").join(settings.product_name());
|
||||
settings.copy_resources(&resource_dir)
|
||||
}
|
||||
|
||||
|
@ -44,13 +44,14 @@ pub fn list_icon_files(
|
||||
data_dir: &Path,
|
||||
) -> crate::Result<BTreeMap<Icon, PathBuf>> {
|
||||
let base_dir = data_dir.join("usr/share/icons/hicolor");
|
||||
let main_binary_name = settings.main_binary_name()?;
|
||||
let get_dest_path = |width: u32, height: u32, is_high_density: bool| {
|
||||
base_dir.join(format!(
|
||||
"{}x{}{}/apps/{}.png",
|
||||
width,
|
||||
height,
|
||||
if is_high_density { "@2" } else { "" },
|
||||
settings.main_binary_name()
|
||||
main_binary_name
|
||||
))
|
||||
};
|
||||
let mut icons = BTreeMap::new();
|
||||
@ -97,8 +98,9 @@ pub fn generate_desktop_file(
|
||||
custom_template_path: &Option<PathBuf>,
|
||||
data_dir: &Path,
|
||||
) -> crate::Result<(PathBuf, PathBuf)> {
|
||||
let bin_name = settings.main_binary_name();
|
||||
let desktop_file_name = format!("{bin_name}.desktop");
|
||||
let bin_name = settings.main_binary_name()?;
|
||||
let product_name = settings.product_name();
|
||||
let desktop_file_name = format!("{product_name}.desktop");
|
||||
let path = PathBuf::from("usr/share/applications").join(desktop_file_name);
|
||||
let dest_path = PathBuf::from("/").join(&path);
|
||||
let file_path = data_dir.join(&path);
|
||||
|
@ -141,12 +141,12 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
|
||||
|
||||
// Add resources
|
||||
if settings.resource_files().count() > 0 {
|
||||
let resource_dir = Path::new("/usr/lib").join(settings.main_binary_name());
|
||||
let resource_dir = Path::new("/usr/lib").join(settings.product_name());
|
||||
// Create an empty file, needed to add a directory to the RPM package
|
||||
// (cf https://github.com/rpm-rs/rpm/issues/177)
|
||||
let empty_file_path = &package_dir.join("empty");
|
||||
File::create(empty_file_path)?;
|
||||
// Then add the resource directory `/usr/lib/<binary_name>` to the package.
|
||||
// Then add the resource directory `/usr/lib/<product_name>` to the package.
|
||||
builder = builder.with_file(
|
||||
empty_file_path,
|
||||
FileOptions::new(resource_dir.to_string_lossy()).mode(FileMode::Dir { permissions: 0o755 }),
|
||||
|
@ -17,10 +17,10 @@ else
|
||||
linuxdeploy_arch="$ARCH"
|
||||
fi
|
||||
|
||||
mkdir -p "{{crate_name}}.AppDir"
|
||||
cp -r ../appimage_deb/data/usr "{{crate_name}}.AppDir"
|
||||
mkdir -p "{{product_name}}.AppDir"
|
||||
cp -r ../appimage_deb/data/usr "{{product_name}}.AppDir"
|
||||
|
||||
cd "{{crate_name}}.AppDir"
|
||||
cd "{{product_name}}.AppDir"
|
||||
mkdir -p "usr/bin"
|
||||
mkdir -p "usr/lib"
|
||||
|
||||
@ -56,14 +56,14 @@ find -L /usr/lib* -name libwebkit2gtkinjectedbundle.so -exec mkdir -p "$(dirname
|
||||
( cd "{{tauri_tools_path}}" && ( wget -q -4 -N https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-${ARCH} || wget -q -4 -N https://github.com/AppImage/AppImageKit/releases/download/12/AppRun-${ARCH} ) )
|
||||
chmod +x "{{tauri_tools_path}}/AppRun-${ARCH}"
|
||||
|
||||
# We need AppRun to be installed as {{crate_name}}.AppDir/AppRun.
|
||||
# We need AppRun to be installed as {{product_name}}.AppDir/AppRun.
|
||||
# Otherwise the linuxdeploy scripts will default to symlinking our main bin instead and will crash on trying to launch.
|
||||
cp "{{tauri_tools_path}}/AppRun-${ARCH}" AppRun
|
||||
|
||||
cp "{{icon_path}}" .DirIcon
|
||||
ln -sf "{{icon_path}}" "{{crate_name}}.png"
|
||||
ln -sf "{{icon_path}}" "{{product_name}}.png"
|
||||
|
||||
ln -sf "usr/share/applications/{{crate_name}}.desktop" "{{crate_name}}.desktop"
|
||||
ln -sf "usr/share/applications/{{product_name}}.desktop" "{{product_name}}.desktop"
|
||||
|
||||
cd ..
|
||||
|
||||
@ -83,4 +83,4 @@ chmod +x "{{tauri_tools_path}}/linuxdeploy-${linuxdeploy_arch}.AppImage"
|
||||
|
||||
dd if=/dev/zero bs=1 count=3 seek=8 conv=notrunc of="{{tauri_tools_path}}/linuxdeploy-${linuxdeploy_arch}.AppImage"
|
||||
|
||||
OUTPUT="{{appimage_filename}}" "{{tauri_tools_path}}/linuxdeploy-${linuxdeploy_arch}.AppImage" --appimage-extract-and-run --appdir "{{crate_name}}.AppDir" --plugin gtk ${gst_plugin} --output appimage
|
||||
OUTPUT="{{appimage_filename}}" "{{tauri_tools_path}}/linuxdeploy-${linuxdeploy_arch}.AppImage" --appimage-extract-and-run --appdir "{{product_name}}.AppDir" --plugin gtk ${gst_plugin} --output appimage
|
||||
|
@ -200,7 +200,7 @@ fn create_info_plist(
|
||||
plist.insert("CFBundleDisplayName".into(), settings.product_name().into());
|
||||
plist.insert(
|
||||
"CFBundleExecutable".into(),
|
||||
settings.main_binary_name().into(),
|
||||
settings.main_binary_name()?.into(),
|
||||
);
|
||||
if let Some(path) = bundle_icon_file {
|
||||
plist.insert(
|
||||
|
@ -170,7 +170,7 @@ fn generate_info_plist(
|
||||
writeln!(
|
||||
file,
|
||||
" <key>CFBundleExecutable</key>\n <string>{}</string>",
|
||||
settings.main_binary_name()
|
||||
settings.main_binary_name()?
|
||||
)?;
|
||||
writeln!(
|
||||
file,
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
use super::category::AppCategory;
|
||||
use crate::bundle::{common, platform::target_triple};
|
||||
use anyhow::Context;
|
||||
pub use tauri_utils::config::WebviewInstallMode;
|
||||
use tauri_utils::{
|
||||
config::{BundleType, DeepLinkProtocol, FileAssociation, NSISInstallerMode, NsisCompression},
|
||||
@ -617,8 +618,8 @@ pub struct BundleSettings {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BundleBinary {
|
||||
name: String,
|
||||
src_path: Option<String>,
|
||||
main: bool,
|
||||
src_path: Option<String>,
|
||||
}
|
||||
|
||||
impl BundleBinary {
|
||||
@ -626,8 +627,8 @@ impl BundleBinary {
|
||||
pub fn new(name: String, main: bool) -> Self {
|
||||
Self {
|
||||
name,
|
||||
src_path: None,
|
||||
main,
|
||||
src_path: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -640,13 +641,6 @@ impl BundleBinary {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the src path of the binary.
|
||||
#[must_use]
|
||||
pub fn set_src_path(mut self, src_path: Option<String>) -> Self {
|
||||
self.src_path = src_path;
|
||||
self
|
||||
}
|
||||
|
||||
/// Mark the binary as the main executable.
|
||||
pub fn set_main(&mut self, main: bool) {
|
||||
self.main = main;
|
||||
@ -657,9 +651,11 @@ impl BundleBinary {
|
||||
self.name = name;
|
||||
}
|
||||
|
||||
/// Returns the binary name.
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
/// Sets the src path of the binary.
|
||||
#[must_use]
|
||||
pub fn set_src_path(mut self, src_path: Option<String>) -> Self {
|
||||
self.src_path = src_path;
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns the binary `main` flag.
|
||||
@ -667,6 +663,11 @@ impl BundleBinary {
|
||||
self.main
|
||||
}
|
||||
|
||||
/// Returns the binary name.
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// Returns the binary source path.
|
||||
pub fn src_path(&self) -> Option<&String> {
|
||||
self.src_path.as_ref()
|
||||
@ -852,14 +853,24 @@ impl Settings {
|
||||
}
|
||||
|
||||
/// Returns the file name of the binary being bundled.
|
||||
pub fn main_binary_name(&self) -> &str {
|
||||
pub fn main_binary(&self) -> crate::Result<&BundleBinary> {
|
||||
self
|
||||
.binaries
|
||||
.iter()
|
||||
.find(|bin| bin.main)
|
||||
.expect("failed to find main binary")
|
||||
.name
|
||||
.as_str()
|
||||
.context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns the file name of the binary being bundled.
|
||||
pub fn main_binary_name(&self) -> crate::Result<&str> {
|
||||
self
|
||||
.binaries
|
||||
.iter()
|
||||
.find(|bin| bin.main)
|
||||
.context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")
|
||||
.map(|b| b.name.as_str())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns the path to the specified binary.
|
||||
|
@ -304,11 +304,7 @@ fn run_candle(
|
||||
}
|
||||
};
|
||||
|
||||
let main_binary = settings
|
||||
.binaries()
|
||||
.iter()
|
||||
.find(|bin| bin.main())
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?;
|
||||
let main_binary = settings.main_binary()?;
|
||||
|
||||
let mut args = vec![
|
||||
"-arch".to_string(),
|
||||
@ -404,13 +400,6 @@ pub fn build_wix_app_installer(
|
||||
// target only supports x64.
|
||||
log::info!("Target: {}", arch);
|
||||
|
||||
let main_binary = settings
|
||||
.binaries()
|
||||
.iter()
|
||||
.find(|bin| bin.main())
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?;
|
||||
let app_exe_source = settings.binary_path(main_binary);
|
||||
|
||||
let output_path = settings.project_out_directory().join("wix").join(arch);
|
||||
|
||||
if output_path.exists() {
|
||||
@ -546,10 +535,6 @@ pub fn build_wix_app_installer(
|
||||
let shortcut_guid = generate_package_guid(settings).to_string();
|
||||
data.insert("shortcut_guid", to_json(shortcut_guid.as_str()));
|
||||
|
||||
// Note: `main_binary_name` is not used in our template but we keep it as it is potentially useful for custom temples
|
||||
let main_binary_name = settings.main_binary_name().to_string();
|
||||
data.insert("main_binary_name", to_json(&main_binary_name));
|
||||
|
||||
let binaries = generate_binaries_data(settings)?;
|
||||
|
||||
let binaries_json = to_json(binaries);
|
||||
@ -572,7 +557,13 @@ pub fn build_wix_app_installer(
|
||||
let merge_modules = get_merge_modules(settings)?;
|
||||
data.insert("merge_modules", to_json(merge_modules));
|
||||
|
||||
data.insert("app_exe_source", to_json(app_exe_source));
|
||||
// Note: `main_binary_name` is not used in our template but we keep it as it is potentially useful for custom temples
|
||||
let main_binary_name = settings.main_binary_name()?;
|
||||
data.insert("main_binary_name", to_json(main_binary_name));
|
||||
|
||||
let main_binary = settings.main_binary()?;
|
||||
let main_binary_path = settings.binary_path(main_binary);
|
||||
data.insert("main_binary_path", to_json(main_binary_path));
|
||||
|
||||
// copy icon from `settings.windows().icon_path` folder to resource folder near msi
|
||||
let icon_path = copy_icon(settings, "icon.ico", &settings.windows().icon_path)?;
|
||||
|
@ -336,21 +336,9 @@ fn build_nsis_app_installer(
|
||||
}
|
||||
data.insert("language_files", to_json(language_files_paths));
|
||||
|
||||
let main_binary = settings
|
||||
.binaries()
|
||||
.iter()
|
||||
.find(|bin| bin.main())
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?;
|
||||
let main_binary = settings.main_binary()?;
|
||||
let main_binary_path = settings.binary_path(main_binary).with_extension("exe");
|
||||
data.insert(
|
||||
"main_binary_name",
|
||||
to_json(
|
||||
main_binary_path
|
||||
.file_stem()
|
||||
.and_then(|file_name| file_name.to_str())
|
||||
.unwrap_or_else(|| main_binary.name()),
|
||||
),
|
||||
);
|
||||
data.insert("main_binary_name", to_json(main_binary.name()));
|
||||
data.insert("main_binary_path", to_json(&main_binary_path));
|
||||
|
||||
let out_file = "nsis-output.exe";
|
||||
|
@ -139,7 +139,7 @@
|
||||
{{/each~}}
|
||||
</Component>
|
||||
<Component Id="Path" Guid="{{path_component_guid}}" Win64="$(var.Win64)">
|
||||
<File Id="Path" Source="{{app_exe_source}}" KeyPath="yes" Checksum="yes"/>
|
||||
<File Id="Path" Source="{{main_binary_path}}" KeyPath="yes" Checksum="yes"/>
|
||||
{{#each file_associations as |association| ~}}
|
||||
{{#each association.ext as |ext| ~}}
|
||||
<ProgId Id="{{../../product_name}}.{{ext}}" Advertise="yes" Description="{{association.description}}">
|
||||
|
@ -22,6 +22,13 @@
|
||||
],
|
||||
"pattern": "^[^/\\:*?\"<>|]+$"
|
||||
},
|
||||
"mainBinaryName": {
|
||||
"description": "App main binary filename. Defaults to the name of your cargo crate.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"description": "App version. It is a semver version number or a path to a `package.json` file containing the `version` field. If removed the version number from `Cargo.toml` is used.\n\n By default version 1.0 is used on Android.",
|
||||
"type": [
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
app_paths::tauri_dir,
|
||||
config::{get as get_config, ConfigHandle, FrontendDist},
|
||||
},
|
||||
interface::{AppInterface, AppSettings, Interface},
|
||||
interface::{AppInterface, Interface},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
use anyhow::Context;
|
||||
@ -83,10 +83,9 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
|
||||
let app_settings = interface.app_settings();
|
||||
let interface_options = options.clone().into();
|
||||
|
||||
let bin_path = app_settings.app_binary_path(&interface_options)?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
let out_dir = app_settings.out_dir(&interface_options)?;
|
||||
|
||||
interface.build(interface_options)?;
|
||||
let bin_path = interface.build(interface_options)?;
|
||||
|
||||
log::info!(action ="Built"; "application at: {}", tauri_utils::display_path(&bin_path));
|
||||
|
||||
@ -100,7 +99,7 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
|
||||
&interface,
|
||||
&app_settings,
|
||||
config_,
|
||||
out_dir,
|
||||
&out_dir,
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@ -121,8 +121,7 @@ pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
|
||||
let app_settings = interface.app_settings();
|
||||
let interface_options = options.clone().into();
|
||||
|
||||
let bin_path = app_settings.app_binary_path(&interface_options)?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
let out_dir = app_settings.out_dir(&interface_options)?;
|
||||
|
||||
bundle(
|
||||
&options,
|
||||
@ -131,7 +130,7 @@ pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
|
||||
&interface,
|
||||
&app_settings,
|
||||
config_,
|
||||
out_dir,
|
||||
&out_dir,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -55,10 +55,16 @@ pub trait AppSettings {
|
||||
tauri_utils::platform::target_triple()?
|
||||
};
|
||||
|
||||
let mut bins = self.get_binaries(&target)?;
|
||||
if let Some(main_binary_name) = &config.main_binary_name {
|
||||
let main = bins.iter_mut().find(|b| b.main()).context("no main bin?")?;
|
||||
main.set_name(main_binary_name.to_owned());
|
||||
}
|
||||
|
||||
let mut settings_builder = SettingsBuilder::new()
|
||||
.package_settings(self.get_package_settings())
|
||||
.bundle_settings(self.get_bundle_settings(config, &enabled_features)?)
|
||||
.binaries(self.get_binaries(&target)?)
|
||||
.binaries(bins)
|
||||
.project_out_directory(out_dir)
|
||||
.target(target)
|
||||
.package_types(package_types);
|
||||
@ -91,7 +97,7 @@ pub trait Interface: Sized {
|
||||
fn new(config: &Config, target: Option<String>) -> crate::Result<Self>;
|
||||
fn app_settings(&self) -> Arc<Self::AppSettings>;
|
||||
fn env(&self) -> HashMap<&str, String>;
|
||||
fn build(&mut self, options: Options) -> crate::Result<()>;
|
||||
fn build(&mut self, options: Options) -> crate::Result<PathBuf>;
|
||||
fn dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||
&mut self,
|
||||
options: Options,
|
||||
|
@ -115,6 +115,7 @@ pub struct Rust {
|
||||
app_settings: Arc<RustAppSettings>,
|
||||
config_features: Vec<String>,
|
||||
available_targets: Option<Vec<RustupTarget>>,
|
||||
main_binary_name: Option<String>,
|
||||
}
|
||||
|
||||
impl Interface for Rust {
|
||||
@ -160,6 +161,7 @@ impl Interface for Rust {
|
||||
Ok(Self {
|
||||
app_settings: Arc::new(app_settings),
|
||||
config_features: config.build.features.clone().unwrap_or_default(),
|
||||
main_binary_name: config.main_binary_name.clone(),
|
||||
available_targets: None,
|
||||
})
|
||||
}
|
||||
@ -168,14 +170,14 @@ impl Interface for Rust {
|
||||
self.app_settings.clone()
|
||||
}
|
||||
|
||||
fn build(&mut self, options: Options) -> crate::Result<()> {
|
||||
fn build(&mut self, options: Options) -> crate::Result<PathBuf> {
|
||||
desktop::build(
|
||||
options,
|
||||
&self.app_settings,
|
||||
&mut self.available_targets,
|
||||
self.config_features.clone(),
|
||||
)?;
|
||||
Ok(())
|
||||
self.main_binary_name.as_deref(),
|
||||
)
|
||||
}
|
||||
|
||||
fn dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||
@ -498,6 +500,7 @@ impl Rust {
|
||||
&mut self.available_targets,
|
||||
self.config_features.clone(),
|
||||
&self.app_settings,
|
||||
self.main_binary_name.clone(),
|
||||
on_exit,
|
||||
)
|
||||
.map(|c| Box::new(c) as Box<dyn DevProcess + Send>)
|
||||
@ -865,32 +868,30 @@ impl AppSettings for RustAppSettings {
|
||||
let bin_name = binaries
|
||||
.iter()
|
||||
.find(|x| x.main())
|
||||
.expect("failed to find main binary")
|
||||
.context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")?
|
||||
.name();
|
||||
|
||||
let out_dir = self
|
||||
.out_dir(options)
|
||||
.with_context(|| "failed to get project out directory")?;
|
||||
.context("failed to get project out directory")?;
|
||||
|
||||
let binary_extension: String = if self.target_triple.contains("windows") {
|
||||
let ext = if self.target_triple.contains("windows") {
|
||||
"exe"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
.into();
|
||||
};
|
||||
|
||||
Ok(out_dir.join(bin_name).with_extension(binary_extension))
|
||||
Ok(out_dir.join(bin_name).with_extension(ext))
|
||||
}
|
||||
|
||||
fn get_binaries(&self, target: &str) -> crate::Result<Vec<BundleBinary>> {
|
||||
let mut binaries: Vec<BundleBinary> = vec![];
|
||||
|
||||
let binary_extension: String = if target.contains("windows") {
|
||||
let ext = if target.contains("windows") {
|
||||
".exe"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
.into();
|
||||
};
|
||||
|
||||
if let Some(bins) = &self.cargo_settings.bin {
|
||||
let default_run = self
|
||||
@ -899,9 +900,8 @@ impl AppSettings for RustAppSettings {
|
||||
.clone()
|
||||
.unwrap_or_default();
|
||||
for bin in bins {
|
||||
let name = format!("{}{}", bin.name, binary_extension);
|
||||
let is_main =
|
||||
bin.name == self.cargo_package_settings.name || bin.name.as_str() == default_run;
|
||||
let name = format!("{}{}", bin.name, ext);
|
||||
let is_main = bin.name == self.cargo_package_settings.name || bin.name == default_run;
|
||||
binaries.push(BundleBinary::with_path(name, is_main, bin.path.clone()))
|
||||
}
|
||||
}
|
||||
@ -912,12 +912,13 @@ impl AppSettings for RustAppSettings {
|
||||
for entry in fs_bins {
|
||||
let path = entry?.path();
|
||||
if let Some(name) = path.file_stem() {
|
||||
// see https://github.com/tauri-apps/tauri/pull/10977#discussion_r1759742414
|
||||
let bin_exists = binaries.iter().any(|bin| {
|
||||
bin.name() == name || path.ends_with(bin.src_path().unwrap_or(&"".to_string()))
|
||||
});
|
||||
if !bin_exists {
|
||||
binaries.push(BundleBinary::new(
|
||||
format!("{}{}", name.to_string_lossy(), &binary_extension),
|
||||
format!("{}{}", name.to_string_lossy(), ext),
|
||||
false,
|
||||
))
|
||||
}
|
||||
@ -927,16 +928,13 @@ impl AppSettings for RustAppSettings {
|
||||
|
||||
if let Some(default_run) = self.package_settings.default_run.as_ref() {
|
||||
if !binaries.iter_mut().any(|bin| bin.name() == default_run) {
|
||||
binaries.push(BundleBinary::new(
|
||||
format!("{}{}", default_run, binary_extension),
|
||||
true,
|
||||
));
|
||||
binaries.push(BundleBinary::new(format!("{}{}", default_run, ext), true));
|
||||
}
|
||||
}
|
||||
|
||||
match binaries.len() {
|
||||
0 => binaries.push(BundleBinary::new(
|
||||
format!("{}{}", self.cargo_package_settings.name, &binary_extension),
|
||||
format!("{}{}", self.cargo_package_settings.name, ext),
|
||||
true,
|
||||
)),
|
||||
1 => binaries.get_mut(0).unwrap().set_main(true),
|
||||
|
@ -8,7 +8,9 @@ use crate::CommandExt;
|
||||
use anyhow::Context;
|
||||
use shared_child::SharedChild;
|
||||
use std::{
|
||||
fs,
|
||||
io::{BufReader, ErrorKind, Write},
|
||||
path::PathBuf,
|
||||
process::{Command, ExitStatus, Stdio},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
@ -64,6 +66,7 @@ pub fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||
available_targets: &mut Option<Vec<RustupTarget>>,
|
||||
config_features: Vec<String>,
|
||||
app_settings: &RustAppSettings,
|
||||
main_binary_name: Option<String>,
|
||||
on_exit: F,
|
||||
) -> crate::Result<impl DevProcess> {
|
||||
let bin_path = app_settings.app_binary_path(&options)?;
|
||||
@ -79,6 +82,9 @@ pub fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||
config_features,
|
||||
move |status, reason| {
|
||||
if status == Some(0) {
|
||||
let main_binary_name = main_binary_name.as_deref();
|
||||
let bin_path = rename_app(bin_path, main_binary_name).expect("failed to rename app");
|
||||
|
||||
let mut app = Command::new(bin_path);
|
||||
app.stdout(os_pipe::dup_stdout().unwrap());
|
||||
app.stderr(os_pipe::dup_stderr().unwrap());
|
||||
@ -119,18 +125,19 @@ pub fn build(
|
||||
app_settings: &RustAppSettings,
|
||||
available_targets: &mut Option<Vec<RustupTarget>>,
|
||||
config_features: Vec<String>,
|
||||
) -> crate::Result<()> {
|
||||
main_binary_name: Option<&str>,
|
||||
) -> crate::Result<PathBuf> {
|
||||
let out_dir = app_settings.out_dir(&options)?;
|
||||
let bin_path = app_settings.app_binary_path(&options)?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
|
||||
let bin_name = bin_path.file_stem().unwrap();
|
||||
|
||||
if !std::env::var("STATIC_VCRUNTIME").map_or(false, |v| v == "false") {
|
||||
std::env::set_var("STATIC_VCRUNTIME", "true");
|
||||
}
|
||||
|
||||
if options.target == Some("universal-apple-darwin".into()) {
|
||||
std::fs::create_dir_all(out_dir).with_context(|| "failed to create project out directory")?;
|
||||
std::fs::create_dir_all(&out_dir).with_context(|| "failed to create project out directory")?;
|
||||
|
||||
let bin_name = bin_path.file_stem().unwrap();
|
||||
|
||||
let mut lipo_cmd = Command::new("lipo");
|
||||
lipo_cmd
|
||||
@ -162,7 +169,7 @@ pub fn build(
|
||||
.with_context(|| "failed to build app")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
rename_app(bin_path, main_binary_name)
|
||||
}
|
||||
|
||||
fn build_dev_app<F: FnOnce(Option<i32>, ExitReason) + Send + 'static>(
|
||||
@ -363,6 +370,25 @@ fn validate_target(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rename_app(bin_path: PathBuf, main_binary_name: Option<&str>) -> crate::Result<PathBuf> {
|
||||
if let Some(main_binary_name) = main_binary_name {
|
||||
let new_path = bin_path
|
||||
.with_file_name(main_binary_name)
|
||||
.with_extension(bin_path.extension().unwrap_or_default());
|
||||
|
||||
fs::rename(&bin_path, &new_path).with_context(|| {
|
||||
format!(
|
||||
"failed to rename `{}` to `{}`",
|
||||
tauri_utils::display_path(bin_path),
|
||||
tauri_utils::display_path(&new_path),
|
||||
)
|
||||
})?;
|
||||
Ok(new_path)
|
||||
} else {
|
||||
Ok(bin_path)
|
||||
}
|
||||
}
|
||||
|
||||
// taken from https://github.com/rust-lang/cargo/blob/78b10d4e611ab0721fc3aeaf0edd5dd8f4fdc372/src/cargo/core/shell.rs#L514
|
||||
#[cfg(unix)]
|
||||
mod terminal {
|
||||
|
@ -158,7 +158,9 @@ fn process_package_metadata(config: &mut Map<String, Value>) {
|
||||
.map(|v| (v, "product-name"))
|
||||
})
|
||||
{
|
||||
config.insert(key.into(), product_name);
|
||||
config.insert(key.into(), product_name.clone());
|
||||
// keep main binary name unchanged
|
||||
config.insert("mainBinaryName".into(), product_name);
|
||||
}
|
||||
|
||||
if let Some(version) = package_config.remove("version") {
|
||||
@ -872,6 +874,10 @@ mod test {
|
||||
|
||||
// app information
|
||||
assert_eq!(migrated["productName"], original["package"]["productName"]);
|
||||
assert_eq!(
|
||||
migrated["mainBinaryName"],
|
||||
original["package"]["productName"]
|
||||
);
|
||||
assert_eq!(migrated["version"], original["package"]["version"]);
|
||||
assert_eq!(
|
||||
migrated["identifier"],
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
config::{get as get_tauri_config, ConfigHandle},
|
||||
flock,
|
||||
},
|
||||
interface::{AppInterface, AppSettings, Interface, Options as InterfaceOptions},
|
||||
interface::{AppInterface, Interface, Options as InterfaceOptions},
|
||||
mobile::{write_options, CliOptions},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
@ -191,8 +191,7 @@ fn run_build(
|
||||
};
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let bin_path = app_settings.app_binary_path(&interface_options)?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
let out_dir = app_settings.out_dir(&interface_options)?;
|
||||
let _lock = flock::open_rw(out_dir.join("lock").with_extension("android"), "Android")?;
|
||||
|
||||
let cli_options = CliOptions {
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
config::{get as get_tauri_config, ConfigHandle},
|
||||
flock,
|
||||
},
|
||||
interface::{AppInterface, AppSettings, Interface, MobileOptions, Options as InterfaceOptions},
|
||||
interface::{AppInterface, Interface, MobileOptions, Options as InterfaceOptions},
|
||||
mobile::{write_options, CliOptions, DevChild, DevProcess, TargetDevice},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
@ -186,8 +186,7 @@ fn run_dev(
|
||||
};
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let bin_path = app_settings.app_binary_path(&interface_options)?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
let out_dir = app_settings.out_dir(&interface_options)?;
|
||||
let _lock = flock::open_rw(out_dir.join("lock").with_extension("android"), "Android")?;
|
||||
|
||||
configure_cargo(&mut env, config)?;
|
||||
|
@ -271,12 +271,11 @@ fn run_build(
|
||||
crate::build::setup(&interface, &mut build_options, tauri_config.clone(), true)?;
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let bin_path = app_settings.app_binary_path(&InterfaceOptions {
|
||||
let out_dir = app_settings.out_dir(&InterfaceOptions {
|
||||
debug: build_options.debug,
|
||||
target: build_options.target.clone(),
|
||||
..Default::default()
|
||||
})?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
let _lock = flock::open_rw(out_dir.join("lock").with_extension("ios"), "iOS")?;
|
||||
|
||||
let cli_options = CliOptions {
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
config::{get as get_tauri_config, reload as reload_config, ConfigHandle},
|
||||
flock,
|
||||
},
|
||||
interface::{AppInterface, AppSettings, Interface, MobileOptions, Options as InterfaceOptions},
|
||||
interface::{AppInterface, Interface, MobileOptions, Options as InterfaceOptions},
|
||||
mobile::{write_options, CliOptions, DevChild, DevProcess},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
@ -377,12 +377,11 @@ fn run_dev(
|
||||
crate::dev::setup(&interface, &mut dev_options, tauri_config.clone())?;
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let bin_path = app_settings.app_binary_path(&InterfaceOptions {
|
||||
let out_dir = app_settings.out_dir(&InterfaceOptions {
|
||||
debug: !dev_options.release_mode,
|
||||
target: dev_options.target.clone(),
|
||||
..Default::default()
|
||||
})?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
let _lock = flock::open_rw(out_dir.join("lock").with_extension("ios"), "iOS")?;
|
||||
|
||||
let set_host = options.host.is_some();
|
||||
|
@ -5,7 +5,7 @@
|
||||
use super::{ensure_init, env, get_app, get_config, read_options, MobileTarget};
|
||||
use crate::{
|
||||
helpers::config::get as get_tauri_config,
|
||||
interface::{AppInterface, AppSettings, Interface, Options as InterfaceOptions},
|
||||
interface::{AppInterface, Interface, Options as InterfaceOptions},
|
||||
mobile::ios::LIB_OUTPUT_FILE_NAME,
|
||||
Result,
|
||||
};
|
||||
@ -215,14 +215,11 @@ pub fn command(options: Options) -> Result<()> {
|
||||
target_env,
|
||||
)?;
|
||||
|
||||
let bin_path = interface
|
||||
.app_settings()
|
||||
.app_binary_path(&InterfaceOptions {
|
||||
let out_dir = interface.app_settings().out_dir(&InterfaceOptions {
|
||||
debug: matches!(profile, Profile::Debug),
|
||||
target: Some(rust_triple.into()),
|
||||
..Default::default()
|
||||
})?;
|
||||
let out_dir = bin_path.parent().unwrap();
|
||||
|
||||
let lib_path = out_dir.join(format!("lib{}.a", config.app().lib_name()));
|
||||
if !lib_path.exists() {
|
||||
|
@ -282,14 +282,13 @@ pub fn get_app(target: Target, config: &TauriConfig, interface: &AppInterface) -
|
||||
App::from_raw(tauri_dir().to_path_buf(), raw)
|
||||
.unwrap()
|
||||
.with_target_dir_resolver(move |target, profile| {
|
||||
let bin_path = app_settings
|
||||
.app_binary_path(&InterfaceOptions {
|
||||
app_settings
|
||||
.out_dir(&InterfaceOptions {
|
||||
debug: matches!(profile, Profile::Debug),
|
||||
target: Some(target.into()),
|
||||
..Default::default()
|
||||
})
|
||||
.expect("failed to resolve target directory");
|
||||
bin_path.parent().unwrap().to_path_buf()
|
||||
.expect("failed to resolve target directory")
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,13 @@
|
||||
],
|
||||
"pattern": "^[^/\\:*?\"<>|]+$"
|
||||
},
|
||||
"mainBinaryName": {
|
||||
"description": "App main binary filename. Defaults to the name of your cargo crate.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"description": "App version. It is a semver version number or a path to a `package.json` file containing the `version` field. If removed the version number from `Cargo.toml` is used.\n\n By default version 1.0 is used on Android.",
|
||||
"type": [
|
||||
|
@ -2242,6 +2242,9 @@ pub struct Config {
|
||||
#[serde(alias = "product-name")]
|
||||
#[cfg_attr(feature = "schema", validate(regex(pattern = "^[^/\\:*?\"<>|]+$")))]
|
||||
pub product_name: Option<String>,
|
||||
/// App main binary filename. Defaults to the name of your cargo crate.
|
||||
#[serde(alias = "main-binary-name")]
|
||||
pub main_binary_name: Option<String>,
|
||||
/// App version. It is a semver version number or a path to a `package.json` file containing the `version` field. If removed the version number from `Cargo.toml` is used.
|
||||
///
|
||||
/// By default version 1.0 is used on Android.
|
||||
@ -2836,6 +2839,7 @@ mod build {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let schema = quote!(None);
|
||||
let product_name = opt_str_lit(self.product_name.as_ref());
|
||||
let main_binary_name = opt_str_lit(self.main_binary_name.as_ref());
|
||||
let version = opt_str_lit(self.version.as_ref());
|
||||
let identifier = str_lit(&self.identifier);
|
||||
let app = &self.app;
|
||||
@ -2848,6 +2852,7 @@ mod build {
|
||||
::tauri::utils::config::Config,
|
||||
schema,
|
||||
product_name,
|
||||
main_binary_name,
|
||||
version,
|
||||
identifier,
|
||||
app,
|
||||
|
@ -312,7 +312,7 @@ fn resource_dir_from<P: AsRef<std::path::Path>>(
|
||||
res = if curr_dir.ends_with("/data/usr/bin") {
|
||||
// running from the deb bundle dir
|
||||
exe_dir
|
||||
.join(format!("../lib/{}", package_info.crate_name))
|
||||
.join(format!("../lib/{}", package_info.name))
|
||||
.canonicalize()
|
||||
.map_err(Into::into)
|
||||
} else if let Some(appdir) = &env.appdir {
|
||||
@ -320,14 +320,11 @@ fn resource_dir_from<P: AsRef<std::path::Path>>(
|
||||
Ok(PathBuf::from(format!(
|
||||
"{}/usr/lib/{}",
|
||||
appdir.display(),
|
||||
package_info.crate_name
|
||||
package_info.name
|
||||
)))
|
||||
} else {
|
||||
// running bundle
|
||||
Ok(PathBuf::from(format!(
|
||||
"/usr/lib/{}",
|
||||
package_info.crate_name
|
||||
)))
|
||||
Ok(PathBuf::from(format!("/usr/lib/{}", package_info.name)))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,7 @@ pub fn mock_context<R: Runtime, A: Assets<R>>(assets: A) -> crate::Context<R> {
|
||||
config: Config {
|
||||
schema: None,
|
||||
product_name: Default::default(),
|
||||
main_binary_name: Default::default(),
|
||||
version: Default::default(),
|
||||
identifier: Default::default(),
|
||||
app: AppConfig {
|
||||
|
@ -1980,7 +1980,7 @@ tauri::Builder::default()
|
||||
.set_progress_bar(crate::runtime::ProgressBarState {
|
||||
status: progress_state.status,
|
||||
progress: progress_state.progress,
|
||||
desktop_filename: Some(format!("{}.desktop", self.package_info().crate_name)),
|
||||
desktop_filename: Some(format!("{}.desktop", self.package_info().name)),
|
||||
})
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user