瀏覽代碼

feat(bundler) bundle all binaries from the project (#726)

Lucas Fernandes Nogueira 5 年之前
父節點
當前提交
055d777a42

+ 6 - 0
.changes/bundler-binaries.md

@@ -0,0 +1,6 @@
+---
+"tauri-bundler": minor
+---
+
+The bundler now bundles all binaries from your project ([[[bin]] target tables](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries)) and [src/bin folder](https://doc.rust-lang.org/cargo/guide/project-layout.html).
+When multiple binaries are used, make sure to use the [default-run](https://doc.rust-lang.org/cargo/reference/manifest.html#the-default-run-field) config field.

+ 4 - 2
cli/tauri-bundler/src/bundle.rs

@@ -15,8 +15,10 @@ mod tauri_config;
 #[cfg(target_os = "windows")]
 mod wix;
 
-pub use self::common::{print_error, print_finished, print_info};
-pub use self::settings::{BuildArtifact, PackageType, Settings};
+#[cfg(target_os = "windows")]
+pub use self::common::print_info;
+pub use self::common::{print_error, print_finished};
+pub use self::settings::{PackageType, Settings};
 
 use std::path::PathBuf;
 

+ 6 - 6
cli/tauri-bundler/src/bundle/appimage_bundle.rs

@@ -42,7 +42,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   };
   let package_base_name = format!(
     "{}_{}_{}",
-    settings.binary_name(),
+    settings.main_binary_name(),
     settings.version_string(),
     arch
   );
@@ -57,17 +57,17 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
     remove_dir_all(&output_path)?;
   }
   std::fs::create_dir_all(output_path.clone())?;
-  let app_dir_path = output_path.join(format!("{}.AppDir", settings.binary_name()));
-  let appimage_path = output_path.join(format!("{}.AppImage", settings.binary_name()));
+  let app_dir_path = output_path.join(format!("{}.AppDir", settings.main_binary_name()));
+  let appimage_path = output_path.join(format!("{}.AppImage", settings.main_binary_name()));
   path_utils::create(app_dir_path.clone(), true)?;
 
-  let upcase = settings.binary_name().to_uppercase();
+  let upcase_app_name = settings.main_binary_name().to_uppercase();
 
   // setup data to insert into shell script
   let mut sh_map = BTreeMap::new();
-  sh_map.insert("app_name", settings.binary_name());
+  sh_map.insert("app_name", settings.main_binary_name());
   sh_map.insert("bundle_name", package_base_name.as_str());
-  sh_map.insert("app_name_uppercase", upcase.as_str());
+  sh_map.insert("app_name_uppercase", upcase_app_name.as_str());
 
   // initialize shell script template.
   let temp = HANDLEBARS.render("appimage", &sh_map)?;

+ 4 - 1
cli/tauri-bundler/src/bundle/common.rs

@@ -57,7 +57,9 @@ fn symlink_file(src: &Path, dst: &Path) -> io::Result<()> {
 /// Copies a regular file from one path to another, creating any parent
 /// directories of the destination path as necessary.  Fails if the source path
 /// is a directory or doesn't exist.
-pub fn copy_file(from: &Path, to: &Path) -> crate::Result<()> {
+pub fn copy_file(from: impl AsRef<Path>, to: impl AsRef<Path>) -> crate::Result<()> {
+  let from = from.as_ref();
+  let to = to.as_ref();
   if !from.exists() {
     return Err(crate::Error::GenericError(format!(
       "{:?} does not exist",
@@ -212,6 +214,7 @@ pub fn print_warning(message: &str) -> crate::Result<()> {
 }
 
 /// Prints a Info message to stderr.
+#[cfg(windows)]
 pub fn print_info(message: &str) -> crate::Result<()> {
   if let Some(mut output) = term::stderr() {
     safe_term_attr(&mut output, term::Attr::Bold)?;

+ 11 - 9
cli/tauri-bundler/src/bundle/deb_bundle.rs

@@ -48,7 +48,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   };
   let package_base_name = format!(
     "{}_{}_{}",
-    settings.binary_name(),
+    settings.main_binary_name(),
     settings.version_string(),
     arch
   );
@@ -93,12 +93,14 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
 pub fn generate_data(settings: &Settings, package_dir: &Path) -> crate::Result<PathBuf> {
   // Generate data files.
   let data_dir = package_dir.join("data");
-  let bin_name = settings.binary_name();
-  let binary_dest = data_dir.join("usr/bin").join(bin_name);
   let bin_dir = data_dir.join("usr/bin");
 
-  common::copy_file(settings.binary_path(), &binary_dest)
-    .with_context(|| "Failed to copy binary file")?;
+  for bin in settings.binaries() {
+    let bin_path = settings.binary_path(bin);
+    common::copy_file(&bin_path, &bin_dir.join(bin.name()))
+      .with_context(|| format!("Failed to copy binary from {:?}", bin_path))?;
+  }
+
   transfer_resource_files(settings, &data_dir).with_context(|| "Failed to copy resource files")?;
 
   settings
@@ -119,7 +121,7 @@ pub fn generate_data(settings: &Settings, package_dir: &Path) -> crate::Result<P
 
 /// Generates the bootstrap script file.
 fn generate_bootstrap_file(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
-  let bin_name = settings.binary_name();
+  let bin_name = settings.main_binary_name();
   let bin_dir = data_dir.join("usr/bin");
 
   let bootstrap_file_name = format!("__{}-bootstrapper", bin_name);
@@ -180,7 +182,7 @@ exit 0",
 
 /// Generate the application desktop file and store it under the `data_dir`.
 fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
-  let bin_name = settings.binary_name();
+  let bin_name = settings.main_binary_name();
   let desktop_file_name = format!("{}.desktop", bin_name);
   let desktop_file_path = data_dir
     .join("usr/share/applications")
@@ -293,7 +295,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 transfer_resource_files(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
-  let resource_dir = data_dir.join("usr/lib").join(settings.binary_name());
+  let resource_dir = data_dir.join("usr/lib").join(settings.main_binary_name());
   settings.copy_resources(&resource_dir)
 }
 
@@ -306,7 +308,7 @@ fn generate_icon_files(settings: &Settings, data_dir: &PathBuf) -> crate::Result
       width,
       height,
       if is_high_density { "@2x" } else { "" },
-      settings.binary_name()
+      settings.main_binary_name()
     ))
   };
   let mut sizes = BTreeSet::new();

+ 8 - 4
cli/tauri-bundler/src/bundle/ios_bundle.rs

@@ -51,9 +51,13 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
     generate_icon_files(&bundle_dir, settings).with_context(|| "Failed to create app icons")?;
   generate_info_plist(&bundle_dir, settings, &icon_filenames)
     .with_context(|| "Failed to create Info.plist")?;
-  let bin_path = bundle_dir.join(&settings.bundle_name());
-  common::copy_file(settings.binary_path(), &bin_path)
-    .with_context(|| format!("Failed to copy binary from {:?}", settings.binary_path()))?;
+
+  for bin in settings.binaries() {
+    let bin_path = settings.binary_path(bin);
+    common::copy_file(&bin_path, &bundle_dir.join(bin.name()))
+      .with_context(|| format!("Failed to copy binary from {:?}", bin_path))?;
+  }
+
   Ok(vec![bundle_dir])
 }
 
@@ -159,7 +163,7 @@ fn generate_info_plist(
   write!(
     file,
     "  <key>CFBundleExecutable</key>\n  <string>{}</string>\n",
-    settings.binary_name()
+    settings.main_binary_name()
   )?;
   write!(
     file,

+ 0 - 1
cli/tauri-bundler/src/bundle/msi_bundle.rs

@@ -1,4 +1,3 @@
-use super::common;
 use super::settings::Settings;
 use super::wix;
 

+ 10 - 9
cli/tauri-bundler/src/bundle/osx_bundle.rs

@@ -73,8 +73,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
     .copy_binaries(&bin_dir)
     .with_context(|| "Failed to copy external binaries")?;
 
-  copy_binary_to_bundle(&bundle_directory, settings)
-    .with_context(|| format!("Failed to copy binary from {:?}", settings.binary_path()))?;
+  copy_binaries_to_bundle(&bundle_directory, settings)?;
 
   let use_bootstrapper = settings.osx_use_bootstrapper();
   if use_bootstrapper {
@@ -84,13 +83,15 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   Ok(vec![app_bundle_path])
 }
 
-// Copies the app's binary to the bundle.
-fn copy_binary_to_bundle(bundle_directory: &Path, settings: &Settings) -> crate::Result<()> {
+// Copies the app's binaries to the bundle.
+fn copy_binaries_to_bundle(bundle_directory: &Path, settings: &Settings) -> crate::Result<()> {
   let dest_dir = bundle_directory.join("MacOS");
-  common::copy_file(
-    settings.binary_path(),
-    &dest_dir.join(settings.binary_name()),
-  )
+  for bin in settings.binaries() {
+    let bin_path = settings.binary_path(bin);
+    common::copy_file(&bin_path, &dest_dir.join(bin.name()))
+      .with_context(|| format!("Failed to copy binary from {:?}", bin_path))?;
+  }
+  Ok(())
 }
 
 // Creates the bootstrap script file.
@@ -179,7 +180,7 @@ fn create_info_plist(
     if use_bootstrapper {
       "__bootstrapper"
     } else {
-      settings.binary_name()
+      settings.main_binary_name()
     }
   )?;
   if let Some(path) = bundle_icon_file {

+ 109 - 76
cli/tauri-bundler/src/bundle/settings.rs

@@ -84,17 +84,6 @@ const ALL_PACKAGE_TYPES: &[PackageType] = &[
   PackageType::AppImage,
 ];
 
-/// The build artifact we're bundling.
-#[derive(Clone, Debug)]
-pub enum BuildArtifact {
-  /// The main application.
-  Main,
-  /// A named binary which is inside of the [bin] section of your Cargo.toml.
-  Bin(String),
-  /// An example app of your crate.
-  Example(String),
-}
-
 /// The bundle settings of the BuildArtifact we're bundling.
 #[derive(Clone, Debug, Deserialize, Default)]
 struct BundleSettings {
@@ -207,6 +196,8 @@ struct PackageSettings {
   authors: Option<Vec<String>>,
   /// the package's metadata.
   metadata: Option<MetadataSettings>,
+  /// the default binary to run.
+  default_run: Option<String>,
 }
 
 /// The `workspace` section of the app configuration (read from Cargo.toml).
@@ -216,6 +207,12 @@ struct WorkspaceSettings {
   members: Option<Vec<String>>,
 }
 
+#[derive(Clone, Debug, Deserialize)]
+struct BinarySettings {
+  name: String,
+  path: Option<String>,
+}
+
 /// The Cargo settings (Cargo.toml root descriptor).
 #[derive(Clone, Debug, Deserialize)]
 struct CargoSettings {
@@ -227,6 +224,43 @@ struct CargoSettings {
   ///
   /// it's present if the read Cargo.toml belongs to a workspace root.
   workspace: Option<WorkspaceSettings>,
+  /// the binary targets configuration.
+  bin: Option<Vec<BinarySettings>>,
+}
+
+#[derive(Clone, Debug)]
+pub struct BundleBinary {
+  name: String,
+  src_path: Option<String>,
+  main: bool,
+}
+
+impl BundleBinary {
+  pub fn new(name: String, main: bool) -> Self {
+    Self {
+      name: if cfg!(windows) {
+        format!("{}.exe", name)
+      } else {
+        name
+      },
+      src_path: None,
+      main,
+    }
+  }
+
+  pub fn set_src_path(mut self, src_path: Option<String>) -> Self {
+    self.src_path = src_path;
+    self
+  }
+
+  pub fn name(&self) -> &String {
+    &self.name
+  }
+
+  #[cfg(windows)]
+  pub fn main(&self) -> bool {
+    self.main
+  }
 }
 
 /// The Settings exposed by the module.
@@ -244,16 +278,12 @@ pub struct Settings {
   features: Option<Vec<String>>,
   /// the directory where the bundles will be placed.
   project_out_directory: PathBuf,
-  /// the type of build artifact we're bundling.
-  build_artifact: BuildArtifact,
   /// whether we should build the app with release mode or not.
   is_release: bool,
-  /// the path to the binary (project_out_directory + bin_name).
-  binary_path: PathBuf,
-  /// the binary name we're bundling.
-  binary_name: String,
   /// the bundle settings.
   bundle_settings: BundleSettings,
+  /// the binaries to bundle.
+  binaries: Vec<BundleBinary>,
 }
 
 impl CargoSettings {
@@ -294,13 +324,6 @@ impl Settings {
       }
       None => None,
     };
-    let build_artifact = if let Some(bin) = matches.value_of("bin") {
-      BuildArtifact::Bin(bin.to_string())
-    } else if let Some(example) = matches.value_of("example") {
-      BuildArtifact::Example(example.to_string())
-    } else {
-      BuildArtifact::Main
-    };
     let is_release = matches.is_present("release");
     let target = match matches.value_of("target") {
       Some(triple) => Some((triple.to_string(), TargetInfo::from_str(triple)?)),
@@ -329,7 +352,7 @@ impl Settings {
       }
     };
     let workspace_dir = Settings::get_workspace_dir(&current_dir);
-    let target_dir = Settings::get_target_dir(&workspace_dir, &target, is_release, &build_artifact);
+    let target_dir = Settings::get_target_dir(&workspace_dir, &target, is_release);
     let bundle_settings = match tauri_config {
       Ok(config) => merge_settings(BundleSettings::default(), config.tauri.bundle),
       Err(e) => {
@@ -353,23 +376,49 @@ impl Settings {
         }
       }
     };
-    let (bundle_settings, binary_name) = match build_artifact {
-      BuildArtifact::Main => (bundle_settings, package.name.clone()),
-      BuildArtifact::Bin(ref name) => (
-        bundle_settings_from_table(&bundle_settings.bin, "bin", name)?,
-        name.clone(),
-      ),
-      BuildArtifact::Example(ref name) => (
-        bundle_settings_from_table(&bundle_settings.example, "example", name)?,
-        name.clone(),
-      ),
-    };
-    let binary_name = if cfg!(windows) {
-      format!("{}.{}", &binary_name, "exe")
-    } else {
-      binary_name
-    };
-    let binary_path = target_dir.join(&binary_name);
+
+    let mut binaries: Vec<BundleBinary> = vec![];
+    if let Some(bin) = cargo_settings.bin {
+      let default_run = package.default_run.clone().unwrap_or("".to_string());
+      for binary in bin {
+        binaries.push(
+          BundleBinary::new(
+            binary.name.clone(),
+            binary.name.as_str() == package.name || binary.name.as_str() == default_run,
+          )
+          .set_src_path(binary.path),
+        )
+      }
+    }
+
+    let mut bins_path = PathBuf::from(current_dir);
+    bins_path.push("src/bin");
+    if let Ok(fs_bins) = std::fs::read_dir(bins_path) {
+      for entry in fs_bins {
+        let path = entry?.path();
+        if let Some(name) = path.file_stem() {
+          if !binaries.iter().any(|bin| {
+            bin.name.as_str() == name
+              || path.ends_with(bin.src_path.as_ref().unwrap_or(&"".to_string()))
+          }) {
+            binaries.push(BundleBinary::new(name.to_string_lossy().to_string(), false))
+          }
+        }
+      }
+    }
+
+    if let Some(default_run) = package.default_run.as_ref() {
+      if !binaries.iter().any(|bin| bin.name.as_str() == default_run) {
+        binaries.push(BundleBinary::new(default_run.to_string(), true));
+      }
+    }
+
+    if binaries.len() == 1 {
+      binaries.get_mut(0).and_then(|bin| {
+        bin.main = true;
+        Some(bin)
+      });
+    }
 
     let bundle_settings = parse_external_bin(bundle_settings)?;
 
@@ -378,11 +427,9 @@ impl Settings {
       package_types,
       target,
       features,
-      build_artifact,
       is_release,
       project_out_directory: target_dir,
-      binary_path,
-      binary_name,
+      binaries,
       bundle_settings,
     })
   }
@@ -393,16 +440,12 @@ impl Settings {
     project_root_dir: &PathBuf,
     target: &Option<(String, TargetInfo)>,
     is_release: bool,
-    build_artifact: &BuildArtifact,
   ) -> PathBuf {
     let mut path = project_root_dir.join("target");
     if let &Some((ref triple, _)) = target {
       path.push(triple);
     }
     path.push(if is_release { "release" } else { "debug" });
-    if let &BuildArtifact::Example(_) = build_artifact {
-      path.push("examples");
-    }
     path
   }
 
@@ -454,13 +497,25 @@ impl Settings {
   }
 
   /// Returns the file name of the binary being bundled.
-  pub fn binary_name(&self) -> &str {
-    &self.binary_name
+  pub fn main_binary_name(&self) -> &str {
+    self
+      .binaries
+      .iter()
+      .find(|bin| bin.main)
+      .expect("failed to find main binary")
+      .name
+      .as_str()
+  }
+
+  /// Returns the path to the specified binary.
+  pub fn binary_path(&self, binary: &BundleBinary) -> PathBuf {
+    let mut path = self.project_out_directory.clone();
+    path.push(binary.name());
+    path
   }
 
-  /// Returns the path to the binary being bundled.
-  pub fn binary_path(&self) -> &Path {
-    &self.binary_path
+  pub fn binaries(&self) -> &Vec<BundleBinary> {
+    &self.binaries
   }
 
   /// If a list of package types was specified by the command-line, returns
@@ -524,11 +579,6 @@ impl Settings {
     self.features.to_owned()
   }
 
-  /// Returns the artifact that is being bundled.
-  pub fn build_artifact(&self) -> &BuildArtifact {
-    &self.build_artifact
-  }
-
   /// Returns true if the bundle is being compiled in release mode, false if
   /// it's being compiled in debug mode.
   pub fn is_release_build(&self) -> bool {
@@ -719,23 +769,6 @@ impl Settings {
   }
 }
 
-/// Gets the bundle settings from a map.
-/// It can be used to get the bundle settings from the [example] or [bin] section of Cargo.toml
-fn bundle_settings_from_table(
-  opt_map: &Option<HashMap<String, BundleSettings>>,
-  map_name: &str,
-  bundle_name: &str,
-) -> crate::Result<BundleSettings> {
-  if let Some(bundle_settings) = opt_map.as_ref().and_then(|map| map.get(bundle_name)) {
-    Ok(bundle_settings.clone())
-  } else {
-    return Err(crate::Error::GenericError(format!(
-      "No 'bundle:{}:{}' keys section in the tauri.conf.json file",
-      map_name, bundle_name
-    )));
-  }
-}
-
 /// Parses the external binaries to bundle, adding the target triple suffix to each of them.
 fn parse_external_bin(bundle_settings: BundleSettings) -> crate::Result<BundleSettings> {
   let target_triple = target_triple()?;

+ 5 - 5
cli/tauri-bundler/src/bundle/templates/main.wxs

@@ -70,9 +70,9 @@
             <Component Id="Path" Guid="{{{path_component_guid}}}" Win64="$(var.Win64)">
                 <File Id="Path" Source="{{{app_exe_source}}}" KeyPath="yes" Checksum="yes"/>
             </Component>
-            {{#each external_binaries as |external_bin| ~}}
-            <Component Id="{{ external_bin.id }}" Guid="{{external_bin.guid}}" Win64="$(var.Win64)">
-                <File Id="Path_{{ external_bin.id }}" Source="{{external_bin.path}}"  KeyPath="yes"/>
+            {{#each binaries as |bin| ~}}
+            <Component Id="{{ bin.id }}" Guid="{{bin.guid}}" Win64="$(var.Win64)">
+                <File Id="Path_{{ bin.id }}" Source="{{bin.path}}"  KeyPath="yes"/>
             </Component>
             {{/each~}}
             {{{resources}}}
@@ -140,8 +140,8 @@
                 Level="1"
                 Absent="allow">
             <ComponentRef Id="Path"/>
-            {{#each external_binaries as |external_bin| ~}}
-            <ComponentRef Id="{{ external_bin.id }}"/>
+            {{#each binaries as |bin| ~}}
+            <ComponentRef Id="{{ bin.id }}"/>
             {{/each~}}
             </Feature>
         </Feature>

+ 48 - 18
cli/tauri-bundler/src/bundle/wix.rs

@@ -57,15 +57,16 @@ lazy_static! {
 /// Mapper between a resource directory name and its ResourceDirectory descriptor.
 type ResourceMap = BTreeMap<String, ResourceDirectory>;
 
-/// An external binary to bundle with WIX.
+/// A binary to bundle with WIX.
+/// External binaries or additional project binaries are represented with this data structure.
 /// This data structure is needed because WIX requires each path to have its own `id` and `guid`.
 #[derive(Serialize)]
-struct ExternalBinary {
+struct Binary {
   /// the GUID to use on the WIX XML.
   guid: String,
   /// the id to use on the WIX XML.
   id: String,
-  /// the external binary path.
+  /// the binary path.
   path: String,
 }
 
@@ -135,8 +136,7 @@ impl ResourceDirectory {
 /// Copies the icons to the binary path, under the `resources` folder,
 /// and returns the path to that directory.
 fn copy_icons(settings: &Settings) -> crate::Result<PathBuf> {
-  let base_dir = settings.binary_path();
-  let base_dir = base_dir.parent().expect("Failed to get dir");
+  let base_dir = settings.project_out_directory();
 
   let resource_dir = base_dir.join("resources");
 
@@ -323,11 +323,20 @@ fn run_candle(
     }
   };
 
+  let main_binary = settings
+    .binaries()
+    .iter()
+    .find(|bin| bin.main())
+    .ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?;
+
   let args = vec![
     "-arch".to_string(),
     arch.to_string(),
     wxs_file_name.to_string(),
-    format!("-dSourceDir={}", settings.binary_path().display()),
+    format!(
+      "-dSourceDir={}",
+      settings.binary_path(main_binary).display()
+    ),
   ];
 
   let candle_exe = wix_toolset_path.join("candle.exe");
@@ -434,7 +443,7 @@ pub fn build_wix_app_installer(
   data.insert("manufacturer", to_json(manufacturer.as_str()));
   let upgrade_code = Uuid::new_v5(
     &Uuid::NAMESPACE_DNS,
-    format!("{}.app.x64", &settings.binary_name()).as_bytes(),
+    format!("{}.app.x64", &settings.main_binary_name()).as_bytes(),
   )
   .to_string();
 
@@ -446,13 +455,13 @@ 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()));
 
-  let app_exe_name = settings.binary_name().to_string();
+  let app_exe_name = settings.main_binary_name().to_string();
   data.insert("app_exe_name", to_json(&app_exe_name));
 
-  let external_binaries = generate_external_binary_data(&settings)?;
+  let binaries = generate_binaries_data(&settings)?;
 
-  let external_binaries_json = to_json(&external_binaries);
-  data.insert("external_binaries", external_binaries_json);
+  let binaries_json = to_json(&binaries);
+  data.insert("binaries", binaries_json);
 
   let resources = generate_resource_data(&settings)?;
   let mut resources_wix_string = String::from("");
@@ -468,7 +477,12 @@ pub fn build_wix_app_installer(
   data.insert("resources", to_json(resources_wix_string));
   data.insert("resource_file_ids", to_json(files_ids));
 
-  let app_exe_source = settings.binary_path().display().to_string();
+  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).display().to_string();
 
   data.insert("app_exe_source", to_json(&app_exe_source));
 
@@ -508,9 +522,9 @@ pub fn build_wix_app_installer(
   Ok(target)
 }
 
-/// Generates the data required for the external binaries bundling.
-fn generate_external_binary_data(settings: &Settings) -> crate::Result<Vec<ExternalBinary>> {
-  let mut external_binaries = Vec::new();
+/// Generates the data required for the external binaries and extra binaries bundling.
+fn generate_binaries_data(settings: &Settings) -> crate::Result<Vec<Binary>> {
+  let mut binaries = Vec::new();
   let regex = Regex::new(r"[^\w\d\.]")?;
   let cwd = std::env::current_dir()?;
   for src in settings.external_binaries() {
@@ -524,8 +538,8 @@ fn generate_external_binary_data(settings: &Settings) -> crate::Result<Vec<Exter
 
     let guid = generate_guid(filename.as_bytes()).to_string();
 
-    external_binaries.push(ExternalBinary {
-      guid: guid,
+    binaries.push(Binary {
+      guid,
       path: cwd
         .join(src)
         .into_os_string()
@@ -535,7 +549,23 @@ fn generate_external_binary_data(settings: &Settings) -> crate::Result<Vec<Exter
     });
   }
 
-  Ok(external_binaries)
+  for bin in settings.binaries() {
+    let filename = bin.name();
+    let guid = generate_guid(filename.as_bytes()).to_string();
+    if !bin.main() {
+      binaries.push(Binary {
+        guid,
+        path: settings
+          .binary_path(bin)
+          .into_os_string()
+          .into_string()
+          .expect("failed to read binary path"),
+        id: regex.replace_all(&filename, "").to_string(),
+      })
+    }
+  }
+
+  Ok(binaries)
 }
 
 /// Generates the data required for the resource bundling on wix

+ 5 - 12
cli/tauri-bundler/src/main.rs

@@ -2,9 +2,9 @@ mod bundle;
 mod error;
 pub use error::{Error, Result};
 
-use crate::bundle::{
-  bundle_project, check_icons, print_info, BuildArtifact, PackageType, Settings,
-};
+#[cfg(windows)]
+use crate::bundle::print_info;
+use crate::bundle::{bundle_project, check_icons, PackageType, Settings};
 
 use clap::{crate_version, App, AppSettings, Arg, SubCommand};
 
@@ -16,18 +16,11 @@ use std::process;
 // Runs `cargo build` to make sure the binary file is up-to-date.
 fn build_project_if_unbuilt(settings: &Settings) -> crate::Result<()> {
   let mut args = vec!["build".to_string()];
+
   if let Some(triple) = settings.target_triple() {
     args.push(format!("--target={}", triple));
   }
-  match settings.build_artifact() {
-    &BuildArtifact::Main => {}
-    &BuildArtifact::Bin(ref name) => {
-      args.push(format!("--bin={}", name));
-    }
-    &BuildArtifact::Example(ref name) => {
-      args.push(format!("--example={}", name));
-    }
-  }
+
   if settings.is_release_build() {
     args.push("--release".to_string());
   }