settings.rs 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. // Copyright 2016-2019 Cargo-Bundle developers <https://github.com/burtonageo/cargo-bundle>
  2. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  3. // SPDX-License-Identifier: Apache-2.0
  4. // SPDX-License-Identifier: MIT
  5. use super::category::AppCategory;
  6. use crate::bundle::{common, platform::target_triple};
  7. use anyhow::Context;
  8. pub use tauri_utils::config::WebviewInstallMode;
  9. use tauri_utils::{
  10. config::{BundleType, DeepLinkProtocol, FileAssociation, NSISInstallerMode, NsisCompression},
  11. resources::{external_binaries, ResourcePaths},
  12. };
  13. use std::{
  14. collections::HashMap,
  15. path::{Path, PathBuf},
  16. };
  17. /// The type of the package we're bundling.
  18. #[derive(Clone, Copy, Debug, Eq, PartialEq)]
  19. #[non_exhaustive]
  20. pub enum PackageType {
  21. /// The macOS application bundle (.app).
  22. MacOsBundle,
  23. /// The iOS app bundle.
  24. IosBundle,
  25. /// The Windows bundle (.msi).
  26. WindowsMsi,
  27. /// The NSIS bundle (.exe).
  28. Nsis,
  29. /// The Linux Debian package bundle (.deb).
  30. Deb,
  31. /// The Linux RPM bundle (.rpm).
  32. Rpm,
  33. /// The Linux AppImage bundle (.AppImage).
  34. AppImage,
  35. /// The macOS DMG bundle (.dmg).
  36. Dmg,
  37. /// The Updater bundle.
  38. Updater,
  39. }
  40. impl From<BundleType> for PackageType {
  41. fn from(bundle: BundleType) -> Self {
  42. match bundle {
  43. BundleType::Deb => Self::Deb,
  44. BundleType::Rpm => Self::Rpm,
  45. BundleType::AppImage => Self::AppImage,
  46. BundleType::Msi => Self::WindowsMsi,
  47. BundleType::Nsis => Self::Nsis,
  48. BundleType::App => Self::MacOsBundle,
  49. BundleType::Dmg => Self::Dmg,
  50. }
  51. }
  52. }
  53. impl PackageType {
  54. /// Maps a short name to a PackageType.
  55. /// Possible values are "deb", "ios", "msi", "app", "rpm", "appimage", "dmg", "updater".
  56. pub fn from_short_name(name: &str) -> Option<PackageType> {
  57. // Other types we may eventually want to support: apk.
  58. match name {
  59. "deb" => Some(PackageType::Deb),
  60. "ios" => Some(PackageType::IosBundle),
  61. "msi" => Some(PackageType::WindowsMsi),
  62. "nsis" => Some(PackageType::Nsis),
  63. "app" => Some(PackageType::MacOsBundle),
  64. "rpm" => Some(PackageType::Rpm),
  65. "appimage" => Some(PackageType::AppImage),
  66. "dmg" => Some(PackageType::Dmg),
  67. "updater" => Some(PackageType::Updater),
  68. _ => None,
  69. }
  70. }
  71. /// Gets the short name of this PackageType.
  72. #[allow(clippy::trivially_copy_pass_by_ref)]
  73. pub fn short_name(&self) -> &'static str {
  74. match *self {
  75. PackageType::Deb => "deb",
  76. PackageType::IosBundle => "ios",
  77. PackageType::WindowsMsi => "msi",
  78. PackageType::Nsis => "nsis",
  79. PackageType::MacOsBundle => "app",
  80. PackageType::Rpm => "rpm",
  81. PackageType::AppImage => "appimage",
  82. PackageType::Dmg => "dmg",
  83. PackageType::Updater => "updater",
  84. }
  85. }
  86. /// Gets the list of the possible package types.
  87. pub fn all() -> &'static [PackageType] {
  88. ALL_PACKAGE_TYPES
  89. }
  90. /// Gets a number representing priority which used to sort package types
  91. /// in an order that guarantees that if a certain package type
  92. /// depends on another (like Dmg depending on MacOsBundle), the dependency
  93. /// will be built first
  94. ///
  95. /// The lower the number, the higher the priority
  96. pub fn priority(&self) -> u32 {
  97. match self {
  98. PackageType::MacOsBundle => 0,
  99. PackageType::IosBundle => 0,
  100. PackageType::WindowsMsi => 0,
  101. PackageType::Nsis => 0,
  102. PackageType::Deb => 0,
  103. PackageType::Rpm => 0,
  104. PackageType::AppImage => 0,
  105. PackageType::Dmg => 1,
  106. PackageType::Updater => 2,
  107. }
  108. }
  109. }
  110. const ALL_PACKAGE_TYPES: &[PackageType] = &[
  111. #[cfg(target_os = "linux")]
  112. PackageType::Deb,
  113. #[cfg(target_os = "macos")]
  114. PackageType::IosBundle,
  115. #[cfg(target_os = "windows")]
  116. PackageType::WindowsMsi,
  117. #[cfg(target_os = "windows")]
  118. PackageType::Nsis,
  119. #[cfg(target_os = "macos")]
  120. PackageType::MacOsBundle,
  121. #[cfg(target_os = "linux")]
  122. PackageType::Rpm,
  123. #[cfg(target_os = "macos")]
  124. PackageType::Dmg,
  125. #[cfg(target_os = "linux")]
  126. PackageType::AppImage,
  127. PackageType::Updater,
  128. ];
  129. /// The package settings.
  130. #[derive(Debug, Clone)]
  131. pub struct PackageSettings {
  132. /// the package's product name.
  133. pub product_name: String,
  134. /// the package's version.
  135. pub version: String,
  136. /// the package's description.
  137. pub description: String,
  138. /// the package's homepage.
  139. pub homepage: Option<String>,
  140. /// the package's authors.
  141. pub authors: Option<Vec<String>>,
  142. /// the default binary to run.
  143. pub default_run: Option<String>,
  144. }
  145. /// The updater settings.
  146. #[derive(Debug, Default, Clone)]
  147. pub struct UpdaterSettings {
  148. /// Should generate v1 compatible zipped updater
  149. pub v1_compatible: bool,
  150. /// Signature public key.
  151. pub pubkey: String,
  152. /// Args to pass to `msiexec.exe` to run the updater on Windows.
  153. pub msiexec_args: &'static [&'static str],
  154. }
  155. /// The Linux debian bundle settings.
  156. #[derive(Clone, Debug, Default)]
  157. pub struct DebianSettings {
  158. // OS-specific settings:
  159. /// the list of debian dependencies.
  160. pub depends: Option<Vec<String>>,
  161. /// the list of dependencies the package provides.
  162. pub provides: Option<Vec<String>>,
  163. /// the list of package conflicts.
  164. pub conflicts: Option<Vec<String>>,
  165. /// the list of package replaces.
  166. pub replaces: Option<Vec<String>>,
  167. /// List of custom files to add to the deb package.
  168. /// Maps the path on the debian package to the path of the file to include (relative to the current working directory).
  169. pub files: HashMap<PathBuf, PathBuf>,
  170. /// Path to a custom desktop file Handlebars template.
  171. ///
  172. /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
  173. ///
  174. /// Default file contents:
  175. /// ```text
  176. #[doc = include_str!("./linux/freedesktop/main.desktop")]
  177. /// ```
  178. pub desktop_template: Option<PathBuf>,
  179. /// Define the section in Debian Control file. See : <https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections>
  180. pub section: Option<String>,
  181. /// Change the priority of the Debian Package. By default, it is set to `optional`.
  182. /// Recognized Priorities as of now are : `required`, `important`, `standard`, `optional`, `extra`
  183. pub priority: Option<String>,
  184. /// Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See
  185. /// <https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes>
  186. pub changelog: Option<PathBuf>,
  187. /// Path to script that will be executed before the package is unpacked. See
  188. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  189. pub pre_install_script: Option<PathBuf>,
  190. /// Path to script that will be executed after the package is unpacked. See
  191. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  192. pub post_install_script: Option<PathBuf>,
  193. /// Path to script that will be executed before the package is removed. See
  194. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  195. pub pre_remove_script: Option<PathBuf>,
  196. /// Path to script that will be executed after the package is removed. See
  197. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  198. pub post_remove_script: Option<PathBuf>,
  199. }
  200. /// The Linux AppImage bundle settings.
  201. #[derive(Clone, Debug, Default)]
  202. pub struct AppImageSettings {
  203. /// The files to include in the Appimage Binary.
  204. pub files: HashMap<PathBuf, PathBuf>,
  205. }
  206. /// The RPM bundle settings.
  207. #[derive(Clone, Debug, Default)]
  208. pub struct RpmSettings {
  209. /// The list of RPM dependencies your application relies on.
  210. pub depends: Option<Vec<String>>,
  211. /// The list of RPM dependencies your application provides.
  212. pub provides: Option<Vec<String>>,
  213. /// The list of RPM dependencies your application conflicts with. They must not be present
  214. /// in order for the package to be installed.
  215. pub conflicts: Option<Vec<String>>,
  216. /// The list of RPM dependencies your application supersedes - if this package is installed,
  217. /// packages listed as “obsoletes” will be automatically removed (if they are present).
  218. pub obsoletes: Option<Vec<String>>,
  219. /// The RPM release tag.
  220. pub release: String,
  221. /// The RPM epoch.
  222. pub epoch: u32,
  223. /// List of custom files to add to the RPM package.
  224. /// Maps the path on the RPM package to the path of the file to include (relative to the current working directory).
  225. pub files: HashMap<PathBuf, PathBuf>,
  226. /// Path to a custom desktop file Handlebars template.
  227. ///
  228. /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
  229. ///
  230. /// Default file contents:
  231. /// ```text
  232. #[doc = include_str!("./linux/freedesktop/main.desktop")]
  233. /// ```
  234. pub desktop_template: Option<PathBuf>,
  235. /// Path to script that will be executed before the package is unpacked. See
  236. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  237. pub pre_install_script: Option<PathBuf>,
  238. /// Path to script that will be executed after the package is unpacked. See
  239. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  240. pub post_install_script: Option<PathBuf>,
  241. /// Path to script that will be executed before the package is removed. See
  242. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  243. pub pre_remove_script: Option<PathBuf>,
  244. /// Path to script that will be executed after the package is removed. See
  245. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  246. pub post_remove_script: Option<PathBuf>,
  247. }
  248. /// Position coordinates struct.
  249. #[derive(Clone, Debug, Default)]
  250. pub struct Position {
  251. /// X coordinate.
  252. pub x: u32,
  253. /// Y coordinate.
  254. pub y: u32,
  255. }
  256. /// Size of the window.
  257. #[derive(Clone, Debug, Default)]
  258. pub struct Size {
  259. /// Width of the window.
  260. pub width: u32,
  261. /// Height of the window.
  262. pub height: u32,
  263. }
  264. /// The DMG bundle settings.
  265. #[derive(Clone, Debug, Default)]
  266. pub struct DmgSettings {
  267. /// Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.
  268. pub background: Option<PathBuf>,
  269. /// Position of volume window on screen.
  270. pub window_position: Option<Position>,
  271. /// Size of volume window.
  272. pub window_size: Size,
  273. /// Position of app file on window.
  274. pub app_position: Position,
  275. /// Position of application folder on window.
  276. pub application_folder_position: Position,
  277. }
  278. /// The macOS bundle settings.
  279. #[derive(Clone, Debug, Default)]
  280. pub struct MacOsSettings {
  281. /// MacOS frameworks that need to be bundled with the app.
  282. ///
  283. /// Each string can either be the name of a framework (without the `.framework` extension, e.g. `"SDL2"`),
  284. /// in which case we will search for that framework in the standard install locations (`~/Library/Frameworks/`, `/Library/Frameworks/`, and `/Network/Library/Frameworks/`),
  285. /// or a path to a specific framework bundle (e.g. `./data/frameworks/SDL2.framework`). Note that this setting just makes tauri-bundler copy the specified frameworks into the OS X app bundle
  286. /// (under `Foobar.app/Contents/Frameworks/`); you are still responsible for:
  287. ///
  288. /// - arranging for the compiled binary to link against those frameworks (e.g. by emitting lines like `cargo:rustc-link-lib=framework=SDL2` from your `build.rs` script)
  289. ///
  290. /// - embedding the correct rpath in your binary (e.g. by running `install_name_tool -add_rpath "@executable_path/../Frameworks" path/to/binary` after compiling)
  291. pub frameworks: Option<Vec<String>>,
  292. /// List of custom files to add to the application bundle.
  293. /// Maps the path in the Contents directory in the app to the path of the file to include (relative to the current working directory).
  294. pub files: HashMap<PathBuf, PathBuf>,
  295. /// A version string indicating the minimum MacOS version that the bundled app supports (e.g. `"10.11"`).
  296. /// If you are using this config field, you may also want have your `build.rs` script emit `cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.11`.
  297. pub minimum_system_version: Option<String>,
  298. /// The exception domain to use on the macOS .app bundle.
  299. ///
  300. /// This allows communication to the outside world e.g. a web server you're shipping.
  301. pub exception_domain: Option<String>,
  302. /// Code signing identity.
  303. pub signing_identity: Option<String>,
  304. /// Preserve the hardened runtime version flag, see <https://developer.apple.com/documentation/security/hardened_runtime>
  305. ///
  306. /// Settings this to `false` is useful when using an ad-hoc signature, making it less strict.
  307. pub hardened_runtime: bool,
  308. /// Provider short name for notarization.
  309. pub provider_short_name: Option<String>,
  310. /// Path to the entitlements.plist file.
  311. pub entitlements: Option<String>,
  312. /// Path to the Info.plist file for the bundle.
  313. pub info_plist_path: Option<PathBuf>,
  314. }
  315. /// Configuration for a target language for the WiX build.
  316. #[derive(Debug, Clone, Default)]
  317. pub struct WixLanguageConfig {
  318. /// The path to a locale (`.wxl`) file. See <https://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/build_a_localized_version.html>.
  319. pub locale_path: Option<PathBuf>,
  320. }
  321. /// The languages to build using WiX.
  322. #[derive(Debug, Clone)]
  323. pub struct WixLanguage(pub Vec<(String, WixLanguageConfig)>);
  324. impl Default for WixLanguage {
  325. fn default() -> Self {
  326. Self(vec![("en-US".into(), Default::default())])
  327. }
  328. }
  329. /// Settings specific to the WiX implementation.
  330. #[derive(Clone, Debug, Default)]
  331. pub struct WixSettings {
  332. /// A GUID upgrade code for MSI installer. This code **_must stay the same across all of your updates_**,
  333. /// otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.
  334. ///
  335. /// By default, tauri generates this code by generating a Uuid v5 using the string `<productName>.exe.app.x64` in the DNS namespace.
  336. /// You can use Tauri's CLI to generate and print this code for you by running `tauri inspect wix-upgrade-code`.
  337. ///
  338. /// It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code
  339. /// whenever you want to change your product name.
  340. pub upgrade_code: Option<uuid::Uuid>,
  341. /// The app languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.
  342. pub language: WixLanguage,
  343. /// By default, the bundler uses an internal template.
  344. /// This option allows you to define your own wix file.
  345. pub template: Option<PathBuf>,
  346. /// A list of paths to .wxs files with WiX fragments to use.
  347. pub fragment_paths: Vec<PathBuf>,
  348. /// The ComponentGroup element ids you want to reference from the fragments.
  349. pub component_group_refs: Vec<String>,
  350. /// The Component element ids you want to reference from the fragments.
  351. pub component_refs: Vec<String>,
  352. /// The FeatureGroup element ids you want to reference from the fragments.
  353. pub feature_group_refs: Vec<String>,
  354. /// The Feature element ids you want to reference from the fragments.
  355. pub feature_refs: Vec<String>,
  356. /// The Merge element ids you want to reference from the fragments.
  357. pub merge_refs: Vec<String>,
  358. /// Create an elevated update task within Windows Task Scheduler.
  359. pub enable_elevated_update_task: bool,
  360. /// Path to a bitmap file to use as the installation user interface banner.
  361. /// This bitmap will appear at the top of all but the first page of the installer.
  362. ///
  363. /// The required dimensions are 493px × 58px.
  364. pub banner_path: Option<PathBuf>,
  365. /// Path to a bitmap file to use on the installation user interface dialogs.
  366. /// It is used on the welcome and completion dialogs.
  367. /// The required dimensions are 493px × 312px.
  368. pub dialog_image_path: Option<PathBuf>,
  369. /// Enables FIPS compliant algorithms.
  370. pub fips_compliant: bool,
  371. }
  372. /// Settings specific to the NSIS implementation.
  373. #[derive(Clone, Debug, Default)]
  374. pub struct NsisSettings {
  375. /// A custom .nsi template to use.
  376. pub template: Option<PathBuf>,
  377. /// The path to a bitmap file to display on the header of installers pages.
  378. ///
  379. /// The recommended dimensions are 150px x 57px.
  380. pub header_image: Option<PathBuf>,
  381. /// The path to a bitmap file for the Welcome page and the Finish page.
  382. ///
  383. /// The recommended dimensions are 164px x 314px.
  384. pub sidebar_image: Option<PathBuf>,
  385. /// The path to an icon file used as the installer icon.
  386. pub installer_icon: Option<PathBuf>,
  387. /// Whether the installation will be for all users or just the current user.
  388. pub install_mode: NSISInstallerMode,
  389. /// A list of installer languages.
  390. /// By default the OS language is used. If the OS language is not in the list of languages, the first language will be used.
  391. /// To allow the user to select the language, set `display_language_selector` to `true`.
  392. ///
  393. /// See <https://github.com/kichik/nsis/tree/9465c08046f00ccb6eda985abbdbf52c275c6c4d/Contrib/Language%20files> for the complete list of languages.
  394. pub languages: Option<Vec<String>>,
  395. /// An key-value pair where the key is the language and the
  396. /// value is the path to a custom `.nsi` file that holds the translated text for tauri's custom messages.
  397. ///
  398. /// See <https://github.com/tauri-apps/tauri/blob/dev/crates/tauri-bundler/src/bundle/windows/nsis/languages/English.nsh> for an example `.nsi` file.
  399. ///
  400. /// **Note**: the key must be a valid NSIS language and it must be added to [`NsisConfig`]languages array,
  401. pub custom_language_files: Option<HashMap<String, PathBuf>>,
  402. /// Whether to display a language selector dialog before the installer and uninstaller windows are rendered or not.
  403. /// By default the OS language is selected, with a fallback to the first language in the `languages` array.
  404. pub display_language_selector: bool,
  405. /// Set compression algorithm used to compress files in the installer.
  406. pub compression: NsisCompression,
  407. /// Set the folder name for the start menu shortcut.
  408. ///
  409. /// Use this option if you have multiple apps and wish to group their shortcuts under one folder
  410. /// or if you generally prefer to set your shortcut inside a folder.
  411. ///
  412. /// Examples:
  413. /// - `AwesomePublisher`, shortcut will be placed in `%AppData%\Microsoft\Windows\Start Menu\Programs\AwesomePublisher\<your-app>.lnk`
  414. /// - If unset, shortcut will be placed in `%AppData%\Microsoft\Windows\Start Menu\Programs\<your-app>.lnk`
  415. pub start_menu_folder: Option<String>,
  416. /// A path to a `.nsh` file that contains special NSIS macros to be hooked into the
  417. /// main installer.nsi script.
  418. ///
  419. /// Supported hooks are:
  420. /// - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.
  421. /// - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.
  422. /// - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.
  423. /// - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.
  424. ///
  425. ///
  426. /// ### Example
  427. ///
  428. /// ```nsh
  429. /// !macro NSIS_HOOK_PREINSTALL
  430. /// MessageBox MB_OK "PreInstall"
  431. /// !macroend
  432. ///
  433. /// !macro NSIS_HOOK_POSTINSTALL
  434. /// MessageBox MB_OK "PostInstall"
  435. /// !macroend
  436. ///
  437. /// !macro NSIS_HOOK_PREUNINSTALL
  438. /// MessageBox MB_OK "PreUnInstall"
  439. /// !macroend
  440. ///
  441. /// !macro NSIS_HOOK_POSTUNINSTALL
  442. /// MessageBox MB_OK "PostUninstall"
  443. /// !macroend
  444. /// ```
  445. pub installer_hooks: Option<PathBuf>,
  446. /// Try to ensure that the WebView2 version is equal to or newer than this version,
  447. /// if the user's WebView2 is older than this version,
  448. /// the installer will try to trigger a WebView2 update.
  449. pub minimum_webview2_version: Option<String>,
  450. }
  451. /// The Custom Signing Command Settings for Windows exe
  452. #[derive(Clone, Debug)]
  453. pub struct CustomSignCommandSettings {
  454. /// The command to run to sign the binary.
  455. pub cmd: String,
  456. /// The arguments to pass to the command.
  457. ///
  458. /// "%1" will be replaced with the path to the binary to be signed.
  459. pub args: Vec<String>,
  460. }
  461. /// The Windows bundle settings.
  462. #[derive(Clone, Debug)]
  463. pub struct WindowsSettings {
  464. /// The file digest algorithm to use for creating file signatures. Required for code signing. SHA-256 is recommended.
  465. pub digest_algorithm: Option<String>,
  466. /// The SHA1 hash of the signing certificate.
  467. pub certificate_thumbprint: Option<String>,
  468. /// Server to use during timestamping.
  469. pub timestamp_url: Option<String>,
  470. /// Whether to use Time-Stamp Protocol (TSP, a.k.a. RFC 3161) for the timestamp server. Your code signing provider may
  471. /// use a TSP timestamp server, like e.g. SSL.com does. If so, enable TSP by setting to true.
  472. pub tsp: bool,
  473. /// WiX configuration.
  474. pub wix: Option<WixSettings>,
  475. /// Nsis configuration.
  476. pub nsis: Option<NsisSettings>,
  477. /// The path to the application icon. Defaults to `./icons/icon.ico`.
  478. pub icon_path: PathBuf,
  479. /// The installation mode for the Webview2 runtime.
  480. pub webview_install_mode: WebviewInstallMode,
  481. /// Validates a second app installation, blocking the user from installing an older version if set to `false`.
  482. ///
  483. /// For instance, if `1.2.1` is installed, the user won't be able to install app version `1.2.0` or `1.1.5`.
  484. ///
  485. /// /// The default value of this flag is `true`.
  486. pub allow_downgrades: bool,
  487. /// Specify a custom command to sign the binaries.
  488. /// This command needs to have a `%1` in it which is just a placeholder for the binary path,
  489. /// which we will detect and replace before calling the command.
  490. ///
  491. /// Example:
  492. /// ```text
  493. /// sign-cli --arg1 --arg2 %1
  494. /// ```
  495. ///
  496. /// By Default we use `signtool.exe` which can be found only on Windows so
  497. /// if you are on another platform and want to cross-compile and sign you will
  498. /// need to use another tool like `osslsigncode`.
  499. pub sign_command: Option<CustomSignCommandSettings>,
  500. }
  501. impl Default for WindowsSettings {
  502. fn default() -> Self {
  503. Self {
  504. digest_algorithm: None,
  505. certificate_thumbprint: None,
  506. timestamp_url: None,
  507. tsp: false,
  508. wix: None,
  509. nsis: None,
  510. icon_path: PathBuf::from("icons/icon.ico"),
  511. webview_install_mode: Default::default(),
  512. allow_downgrades: true,
  513. sign_command: None,
  514. }
  515. }
  516. }
  517. /// The bundle settings of the BuildArtifact we're bundling.
  518. #[derive(Clone, Debug, Default)]
  519. pub struct BundleSettings {
  520. /// the app's identifier.
  521. pub identifier: Option<String>,
  522. /// The app's publisher. Defaults to the second element in the identifier string.
  523. ///
  524. /// Currently maps to the Manufacturer property of the Windows Installer
  525. /// and the Maintainer field of debian packages if the Cargo.toml does not have the authors field.
  526. pub publisher: Option<String>,
  527. /// A url to the home page of your application. If None, will
  528. /// fallback to [PackageSettings::homepage].
  529. ///
  530. /// Supported bundle targets: `deb`, `rpm`, `nsis` and `msi`
  531. pub homepage: Option<String>,
  532. /// the app's icon list.
  533. pub icon: Option<Vec<String>>,
  534. /// the app's resources to bundle.
  535. ///
  536. /// each item can be a path to a file or a path to a folder.
  537. ///
  538. /// supports glob patterns.
  539. pub resources: Option<Vec<String>>,
  540. /// The app's resources to bundle. Takes precedence over `Self::resources` when specified.
  541. ///
  542. /// Maps each resource path to its target directory in the bundle resources directory.
  543. ///
  544. /// Supports glob patterns.
  545. pub resources_map: Option<HashMap<String, String>>,
  546. /// the app's copyright.
  547. pub copyright: Option<String>,
  548. /// The package's license identifier to be included in the appropriate bundles.
  549. /// If not set, defaults to the license from the Cargo.toml file.
  550. pub license: Option<String>,
  551. /// The path to the license file to be included in the appropriate bundles.
  552. pub license_file: Option<PathBuf>,
  553. /// the app's category.
  554. pub category: Option<AppCategory>,
  555. /// the file associations
  556. pub file_associations: Option<Vec<FileAssociation>>,
  557. /// the app's short description.
  558. pub short_description: Option<String>,
  559. /// the app's long description.
  560. pub long_description: Option<String>,
  561. // Bundles for other binaries:
  562. /// Configuration map for the apps to bundle.
  563. pub bin: Option<HashMap<String, BundleSettings>>,
  564. /// External binaries to add to the bundle.
  565. ///
  566. /// Note that each binary name should have the target platform's target triple appended,
  567. /// as well as `.exe` for Windows.
  568. /// For example, if you're bundling a sidecar called `sqlite3`, the bundler expects
  569. /// a binary named `sqlite3-x86_64-unknown-linux-gnu` on linux,
  570. /// and `sqlite3-x86_64-pc-windows-gnu.exe` on windows.
  571. ///
  572. /// Run `tauri build --help` for more info on targets.
  573. ///
  574. /// If you are building a universal binary for MacOS, the bundler expects
  575. /// your external binary to also be universal, and named after the target triple,
  576. /// e.g. `sqlite3-universal-apple-darwin`. See
  577. /// <https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary>
  578. pub external_bin: Option<Vec<String>>,
  579. /// Deep-link protocols.
  580. pub deep_link_protocols: Option<Vec<DeepLinkProtocol>>,
  581. /// Debian-specific settings.
  582. pub deb: DebianSettings,
  583. /// AppImage-specific settings.
  584. pub appimage: AppImageSettings,
  585. /// Rpm-specific settings.
  586. pub rpm: RpmSettings,
  587. /// DMG-specific settings.
  588. pub dmg: DmgSettings,
  589. /// MacOS-specific settings.
  590. pub macos: MacOsSettings,
  591. /// Updater configuration.
  592. pub updater: Option<UpdaterSettings>,
  593. /// Windows-specific settings.
  594. pub windows: WindowsSettings,
  595. }
  596. /// A binary to bundle.
  597. #[derive(Clone, Debug)]
  598. pub struct BundleBinary {
  599. name: String,
  600. main: bool,
  601. src_path: Option<String>,
  602. }
  603. impl BundleBinary {
  604. /// Creates a new bundle binary.
  605. pub fn new(name: String, main: bool) -> Self {
  606. Self {
  607. name,
  608. main,
  609. src_path: None,
  610. }
  611. }
  612. /// Creates a new bundle binary with path.
  613. pub fn with_path(name: String, main: bool, src_path: Option<String>) -> Self {
  614. Self {
  615. name,
  616. src_path,
  617. main,
  618. }
  619. }
  620. /// Mark the binary as the main executable.
  621. pub fn set_main(&mut self, main: bool) {
  622. self.main = main;
  623. }
  624. /// Sets the binary name.
  625. pub fn set_name(&mut self, name: String) {
  626. self.name = name;
  627. }
  628. /// Sets the src path of the binary.
  629. #[must_use]
  630. pub fn set_src_path(mut self, src_path: Option<String>) -> Self {
  631. self.src_path = src_path;
  632. self
  633. }
  634. /// Returns the binary `main` flag.
  635. pub fn main(&self) -> bool {
  636. self.main
  637. }
  638. /// Returns the binary name.
  639. pub fn name(&self) -> &str {
  640. &self.name
  641. }
  642. /// Returns the binary source path.
  643. pub fn src_path(&self) -> Option<&String> {
  644. self.src_path.as_ref()
  645. }
  646. }
  647. /// The Settings exposed by the module.
  648. #[derive(Clone, Debug)]
  649. pub struct Settings {
  650. /// The log level.
  651. log_level: log::Level,
  652. /// the package settings.
  653. package: PackageSettings,
  654. /// the package types we're bundling.
  655. ///
  656. /// if not present, we'll use the PackageType list for the target OS.
  657. package_types: Option<Vec<PackageType>>,
  658. /// the directory where the bundles will be placed.
  659. project_out_directory: PathBuf,
  660. /// the directory to place tools used by the bundler,
  661. /// if `None`, tools are placed in the current user's platform-specific cache directory.
  662. local_tools_directory: Option<PathBuf>,
  663. /// the bundle settings.
  664. bundle_settings: BundleSettings,
  665. /// the binaries to bundle.
  666. binaries: Vec<BundleBinary>,
  667. /// The target triple.
  668. target: String,
  669. }
  670. /// A builder for [`Settings`].
  671. #[derive(Default)]
  672. pub struct SettingsBuilder {
  673. log_level: Option<log::Level>,
  674. project_out_directory: Option<PathBuf>,
  675. package_types: Option<Vec<PackageType>>,
  676. package_settings: Option<PackageSettings>,
  677. bundle_settings: BundleSettings,
  678. binaries: Vec<BundleBinary>,
  679. target: Option<String>,
  680. local_tools_directory: Option<PathBuf>,
  681. }
  682. impl SettingsBuilder {
  683. /// Creates the default settings builder.
  684. pub fn new() -> Self {
  685. Default::default()
  686. }
  687. /// Sets the project output directory. It's used as current working directory.
  688. #[must_use]
  689. pub fn project_out_directory<P: AsRef<Path>>(mut self, path: P) -> Self {
  690. self
  691. .project_out_directory
  692. .replace(path.as_ref().to_path_buf());
  693. self
  694. }
  695. /// Sets the directory to place tools used by the bundler
  696. /// when [`BundleSettings::use_local_tools_dir`] is true.
  697. #[must_use]
  698. pub fn local_tools_directory<P: AsRef<Path>>(mut self, path: P) -> Self {
  699. self
  700. .local_tools_directory
  701. .replace(path.as_ref().to_path_buf());
  702. self
  703. }
  704. /// Sets the package types to create.
  705. #[must_use]
  706. pub fn package_types(mut self, package_types: Vec<PackageType>) -> Self {
  707. self.package_types = Some(package_types);
  708. self
  709. }
  710. /// Sets the package settings.
  711. #[must_use]
  712. pub fn package_settings(mut self, settings: PackageSettings) -> Self {
  713. self.package_settings.replace(settings);
  714. self
  715. }
  716. /// Sets the bundle settings.
  717. #[must_use]
  718. pub fn bundle_settings(mut self, settings: BundleSettings) -> Self {
  719. self.bundle_settings = settings;
  720. self
  721. }
  722. /// Sets the binaries to bundle.
  723. #[must_use]
  724. pub fn binaries(mut self, binaries: Vec<BundleBinary>) -> Self {
  725. self.binaries = binaries;
  726. self
  727. }
  728. /// Sets the target triple.
  729. #[must_use]
  730. pub fn target(mut self, target: String) -> Self {
  731. self.target.replace(target);
  732. self
  733. }
  734. /// Sets the log level for spawned commands. Defaults to [`log::Level::Error`].
  735. #[must_use]
  736. pub fn log_level(mut self, level: log::Level) -> Self {
  737. self.log_level.replace(level);
  738. self
  739. }
  740. /// Builds a Settings from the CLI args.
  741. ///
  742. /// Package settings will be read from Cargo.toml.
  743. ///
  744. /// Bundle settings will be read from $TAURI_DIR/tauri.conf.json if it exists and fallback to Cargo.toml's [package.metadata.bundle].
  745. pub fn build(self) -> crate::Result<Settings> {
  746. let target = if let Some(t) = self.target {
  747. t
  748. } else {
  749. target_triple()?
  750. };
  751. Ok(Settings {
  752. log_level: self.log_level.unwrap_or(log::Level::Error),
  753. package: self
  754. .package_settings
  755. .ok_or_else(|| crate::Error::GenericError("package settings is required".into()))?,
  756. package_types: self.package_types,
  757. project_out_directory: self
  758. .project_out_directory
  759. .ok_or_else(|| crate::Error::GenericError("out directory is required".into()))?,
  760. local_tools_directory: self.local_tools_directory,
  761. binaries: self.binaries,
  762. bundle_settings: BundleSettings {
  763. external_bin: self
  764. .bundle_settings
  765. .external_bin
  766. .as_ref()
  767. .map(|bins| external_binaries(bins, &target)),
  768. ..self.bundle_settings
  769. },
  770. target,
  771. })
  772. }
  773. }
  774. impl Settings {
  775. /// Sets the log level for spawned commands.
  776. pub fn set_log_level(&mut self, level: log::Level) {
  777. self.log_level = level;
  778. }
  779. /// Returns the log level for spawned commands.
  780. pub fn log_level(&self) -> log::Level {
  781. self.log_level
  782. }
  783. /// Returns the directory where the bundle should be placed.
  784. pub fn project_out_directory(&self) -> &Path {
  785. &self.project_out_directory
  786. }
  787. /// Returns the target triple.
  788. pub fn target(&self) -> &str {
  789. &self.target
  790. }
  791. /// Returns the architecture for the binary being bundled (e.g. "arm", "x86" or "x86_64").
  792. pub fn binary_arch(&self) -> &str {
  793. if self.target.starts_with("x86_64") {
  794. "x86_64"
  795. } else if self.target.starts_with('i') {
  796. "x86"
  797. } else if self.target.starts_with("arm") {
  798. "arm"
  799. } else if self.target.starts_with("aarch64") {
  800. "aarch64"
  801. } else if self.target.starts_with("universal") {
  802. "universal"
  803. } else {
  804. panic!("Unexpected target triple {}", self.target)
  805. }
  806. }
  807. /// Returns the file name of the binary being bundled.
  808. pub fn main_binary(&self) -> crate::Result<&BundleBinary> {
  809. self
  810. .binaries
  811. .iter()
  812. .find(|bin| bin.main)
  813. .context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")
  814. .map_err(Into::into)
  815. }
  816. /// Returns the file name of the binary being bundled.
  817. pub fn main_binary_name(&self) -> crate::Result<&str> {
  818. self
  819. .binaries
  820. .iter()
  821. .find(|bin| bin.main)
  822. .context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")
  823. .map(|b| b.name())
  824. .map_err(Into::into)
  825. }
  826. /// Returns the path to the specified binary.
  827. pub fn binary_path(&self, binary: &BundleBinary) -> PathBuf {
  828. let target_os = self
  829. .target()
  830. .split('-')
  831. .nth(2)
  832. .unwrap_or(std::env::consts::OS);
  833. let path = self.project_out_directory.join(binary.name());
  834. if target_os == "windows" {
  835. path.with_extension("exe")
  836. } else {
  837. path
  838. }
  839. }
  840. /// Returns the list of binaries to bundle.
  841. pub fn binaries(&self) -> &Vec<BundleBinary> {
  842. &self.binaries
  843. }
  844. /// If a list of package types was specified by the command-line, returns
  845. /// that list filtered by the current target OS available targets.
  846. ///
  847. /// If a target triple was specified by the
  848. /// command-line, returns the native package type(s) for that target.
  849. ///
  850. /// Otherwise returns the native package type(s) for the host platform.
  851. ///
  852. /// Fails if the host/target's native package type is not supported.
  853. pub fn package_types(&self) -> crate::Result<Vec<PackageType>> {
  854. let target_os = self
  855. .target
  856. .split('-')
  857. .nth(2)
  858. .unwrap_or(std::env::consts::OS)
  859. .replace("darwin", "macos");
  860. let platform_types = match target_os.as_str() {
  861. "macos" => vec![PackageType::MacOsBundle, PackageType::Dmg],
  862. "ios" => vec![PackageType::IosBundle],
  863. "linux" => vec![PackageType::Deb, PackageType::Rpm, PackageType::AppImage],
  864. "windows" => vec![PackageType::WindowsMsi, PackageType::Nsis],
  865. os => {
  866. return Err(crate::Error::GenericError(format!(
  867. "Native {os} bundles not yet supported."
  868. )))
  869. }
  870. };
  871. if let Some(package_types) = &self.package_types {
  872. let mut types = vec![];
  873. for package_type in package_types {
  874. let package_type = *package_type;
  875. if platform_types
  876. .clone()
  877. .into_iter()
  878. .any(|t| t == package_type)
  879. {
  880. types.push(package_type);
  881. }
  882. }
  883. Ok(types)
  884. } else {
  885. Ok(platform_types)
  886. }
  887. }
  888. /// Returns the product name.
  889. pub fn product_name(&self) -> &str {
  890. &self.package.product_name
  891. }
  892. /// Returns the bundle's identifier
  893. pub fn bundle_identifier(&self) -> &str {
  894. self.bundle_settings.identifier.as_deref().unwrap_or("")
  895. }
  896. /// Returns the bundle's publisher
  897. pub fn publisher(&self) -> Option<&str> {
  898. self.bundle_settings.publisher.as_deref()
  899. }
  900. /// Returns an iterator over the icon files to be used for this bundle.
  901. pub fn icon_files(&self) -> ResourcePaths<'_> {
  902. match self.bundle_settings.icon {
  903. Some(ref paths) => ResourcePaths::new(paths.as_slice(), false),
  904. None => ResourcePaths::new(&[], false),
  905. }
  906. }
  907. /// Returns an iterator over the resource files to be included in this
  908. /// bundle.
  909. pub fn resource_files(&self) -> ResourcePaths<'_> {
  910. match (
  911. &self.bundle_settings.resources,
  912. &self.bundle_settings.resources_map,
  913. ) {
  914. (Some(paths), None) => ResourcePaths::new(paths.as_slice(), true),
  915. (None, Some(map)) => ResourcePaths::from_map(map, true),
  916. (Some(_), Some(_)) => panic!("cannot use both `resources` and `resources_map`"),
  917. (None, None) => ResourcePaths::new(&[], true),
  918. }
  919. }
  920. /// Returns an iterator over the external binaries to be included in this
  921. /// bundle.
  922. pub fn external_binaries(&self) -> ResourcePaths<'_> {
  923. match self.bundle_settings.external_bin {
  924. Some(ref paths) => ResourcePaths::new(paths.as_slice(), true),
  925. None => ResourcePaths::new(&[], true),
  926. }
  927. }
  928. /// Copies external binaries to a path.
  929. ///
  930. /// Returns the list of destination paths.
  931. pub fn copy_binaries(&self, path: &Path) -> crate::Result<Vec<PathBuf>> {
  932. let mut paths = Vec::new();
  933. for src in self.external_binaries() {
  934. let src = src?;
  935. let dest = path.join(
  936. src
  937. .file_name()
  938. .expect("failed to extract external binary filename")
  939. .to_string_lossy()
  940. .replace(&format!("-{}", self.target), ""),
  941. );
  942. common::copy_file(&src, &dest)?;
  943. paths.push(dest);
  944. }
  945. Ok(paths)
  946. }
  947. /// Copies resources to a path.
  948. pub fn copy_resources(&self, path: &Path) -> crate::Result<()> {
  949. for resource in self.resource_files().iter() {
  950. let resource = resource?;
  951. let dest = path.join(resource.target());
  952. common::copy_file(resource.path(), dest)?;
  953. }
  954. Ok(())
  955. }
  956. /// Returns the version string of the bundle.
  957. pub fn version_string(&self) -> &str {
  958. &self.package.version
  959. }
  960. /// Returns the copyright text.
  961. pub fn copyright_string(&self) -> Option<&str> {
  962. self.bundle_settings.copyright.as_deref()
  963. }
  964. /// Returns the list of authors name.
  965. pub fn author_names(&self) -> &[String] {
  966. match self.package.authors {
  967. Some(ref names) => names.as_slice(),
  968. None => &[],
  969. }
  970. }
  971. /// Returns the authors as a comma-separated string.
  972. pub fn authors_comma_separated(&self) -> Option<String> {
  973. let names = self.author_names();
  974. if names.is_empty() {
  975. None
  976. } else {
  977. Some(names.join(", "))
  978. }
  979. }
  980. /// Returns the bundle license.
  981. pub fn license(&self) -> Option<String> {
  982. self.bundle_settings.license.clone()
  983. }
  984. /// Returns the bundle license file.
  985. pub fn license_file(&self) -> Option<PathBuf> {
  986. self.bundle_settings.license_file.clone()
  987. }
  988. /// Returns the package's homepage URL, defaulting to "" if not defined.
  989. pub fn homepage_url(&self) -> Option<&str> {
  990. self
  991. .bundle_settings
  992. .homepage
  993. .as_deref()
  994. .or(self.package.homepage.as_deref())
  995. }
  996. /// Returns the app's category.
  997. pub fn app_category(&self) -> Option<AppCategory> {
  998. self.bundle_settings.category
  999. }
  1000. /// Return file associations.
  1001. pub fn file_associations(&self) -> Option<&Vec<FileAssociation>> {
  1002. self.bundle_settings.file_associations.as_ref()
  1003. }
  1004. /// Return the list of deep link protocols to be registered for
  1005. /// this bundle.
  1006. pub fn deep_link_protocols(&self) -> Option<&Vec<DeepLinkProtocol>> {
  1007. self.bundle_settings.deep_link_protocols.as_ref()
  1008. }
  1009. /// Returns the app's short description.
  1010. pub fn short_description(&self) -> &str {
  1011. self
  1012. .bundle_settings
  1013. .short_description
  1014. .as_ref()
  1015. .unwrap_or(&self.package.description)
  1016. }
  1017. /// Returns the app's long description.
  1018. pub fn long_description(&self) -> Option<&str> {
  1019. self.bundle_settings.long_description.as_deref()
  1020. }
  1021. /// Returns the directory for local tools path.
  1022. pub fn local_tools_directory(&self) -> Option<&Path> {
  1023. self.local_tools_directory.as_deref()
  1024. }
  1025. /// Returns the debian settings.
  1026. pub fn deb(&self) -> &DebianSettings {
  1027. &self.bundle_settings.deb
  1028. }
  1029. /// Returns the appimage settings.
  1030. pub fn appimage(&self) -> &AppImageSettings {
  1031. &self.bundle_settings.appimage
  1032. }
  1033. /// Returns the RPM settings.
  1034. pub fn rpm(&self) -> &RpmSettings {
  1035. &self.bundle_settings.rpm
  1036. }
  1037. /// Returns the DMG settings.
  1038. pub fn dmg(&self) -> &DmgSettings {
  1039. &self.bundle_settings.dmg
  1040. }
  1041. /// Returns the MacOS settings.
  1042. pub fn macos(&self) -> &MacOsSettings {
  1043. &self.bundle_settings.macos
  1044. }
  1045. /// Returns the Windows settings.
  1046. pub fn windows(&self) -> &WindowsSettings {
  1047. &self.bundle_settings.windows
  1048. }
  1049. /// Returns the Updater settings.
  1050. pub fn updater(&self) -> Option<&UpdaterSettings> {
  1051. self.bundle_settings.updater.as_ref()
  1052. }
  1053. }