Prechádzať zdrojové kódy

feat(cli): expose `TAURI_TARGET_TRIPLE` to before*Commands, closes #5091 (#5101)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Amr Bashir 2 rokov pred
rodič
commit
a4aec9f0a8

+ 5 - 0
.changes/cli-target-triple-env.md

@@ -0,0 +1,5 @@
+---
+"cli.rs": "patch"
+---
+
+Expose `TAURI_TARGET_TRIPLE` to `beforeDevCommand`, `beforeBuildCommand` and `beforeBundleCommand`

+ 5 - 0
.changes/fix-cli-envs.md

@@ -0,0 +1,5 @@
+---
+"cli.rs": "patch"
+---
+
+Set `TAURI_PLATFORM_TYPE`, `TAURI_FAMILY`, `TAURI_ARCH` and `TAURI_PLATFORM` env vars for hook commands to based on the app not the cli.

+ 3 - 1
tooling/bundler/src/bundle/windows/msi/wix.rs

@@ -283,8 +283,10 @@ pub fn get_and_extract_wix(path: &Path) -> crate::Result<()> {
 
 fn clear_env_for_wix(cmd: &mut Command) {
   cmd.env_clear();
+  let required_vars: Vec<std::ffi::OsString> =
+    vec!["SYSTEMROOT".into(), "TMP".into(), "TEMP".into()];
   for (k, v) in std::env::vars_os() {
-    if ["SYSTEMROOT", "TMP", "TEMP"].contains(k) || k.to_string_lossy().starts_with("TAURI") {
+    if required_vars.contains(&k) || k.to_string_lossy().starts_with("TAURI") {
       cmd.env(k, v);
     }
   }

+ 1 - 1
tooling/cli/src/build.rs

@@ -154,7 +154,7 @@ pub fn command(mut options: Options) -> Result<()> {
     list.extend(config_.build.features.clone().unwrap_or_default());
   }
 
-  let mut interface = AppInterface::new(config_)?;
+  let mut interface = AppInterface::new(config_, options.target.clone())?;
   let app_settings = interface.app_settings();
   let interface_options = options.clone().into();
 

+ 11 - 5
tooling/cli/src/dev.rs

@@ -89,6 +89,11 @@ fn command_internal(mut options: Options) -> Result<()> {
 
   let config = get_config(options.config.as_deref())?;
 
+  let mut interface = AppInterface::new(
+    config.lock().unwrap().as_ref().unwrap(),
+    options.target.clone(),
+  )?;
+
   if let Some(before_dev) = config
     .lock()
     .unwrap()
@@ -108,6 +113,9 @@ fn command_internal(mut options: Options) -> Result<()> {
     let cwd = script_cwd.unwrap_or_else(|| app_dir().clone());
     if let Some(before_dev) = script {
       info!(action = "Running"; "BeforeDevCommand (`{}`)", before_dev);
+      let mut env = command_env(true);
+      env.extend(interface.env());
+
       #[cfg(windows)]
       let mut command = {
         let mut command = Command::new("cmd");
@@ -116,7 +124,7 @@ fn command_internal(mut options: Options) -> Result<()> {
           .arg("/C")
           .arg(&before_dev)
           .current_dir(cwd)
-          .envs(command_env(true));
+          .envs(env);
         command
       };
       #[cfg(not(windows))]
@@ -126,7 +134,7 @@ fn command_internal(mut options: Options) -> Result<()> {
           .arg("-c")
           .arg(&before_dev)
           .current_dir(cwd)
-          .envs(command_env(true));
+          .envs(env);
         command
       };
 
@@ -234,7 +242,7 @@ fn command_internal(mut options: Options) -> Result<()> {
     }
   }
 
-  let config = reload_config(options.config.as_deref())?;
+  reload_config(options.config.as_deref())?;
 
   if std::env::var_os("TAURI_SKIP_DEVSERVER_CHECK") != Some("true".into()) {
     if let AppUrl::Url(WindowUrl::External(dev_server_url)) = dev_path {
@@ -287,8 +295,6 @@ fn command_internal(mut options: Options) -> Result<()> {
     }
   }
 
-  let mut interface = AppInterface::new(config.lock().unwrap().as_ref().unwrap())?;
-
   let exit_on_panic = options.exit_on_panic;
   let no_watch = options.no_watch;
   interface.dev(options.into(), move |status, reason| {

+ 3 - 13
tooling/cli/src/helpers/mod.rs

@@ -14,26 +14,16 @@ use std::{
   path::{Path, PathBuf},
 };
 
-pub fn command_env(debug: bool) -> HashMap<String, String> {
+pub fn command_env(debug: bool) -> HashMap<&'static str, String> {
   let mut map = HashMap::new();
 
-  map.insert("TAURI_PLATFORM".into(), std::env::consts::OS.into());
-  map.insert("TAURI_ARCH".into(), std::env::consts::ARCH.into());
-  map.insert("TAURI_FAMILY".into(), std::env::consts::FAMILY.into());
   map.insert(
-    "TAURI_PLATFORM_VERSION".into(),
+    "TAURI_PLATFORM_VERSION",
     os_info::get().version().to_string(),
   );
 
-  #[cfg(target_os = "linux")]
-  map.insert("TAURI_PLATFORM_TYPE".into(), "Linux".into());
-  #[cfg(target_os = "windows")]
-  map.insert("TAURI_PLATFORM_TYPE".into(), "Windows_NT".into());
-  #[cfg(target_os = "macos")]
-  map.insert("TAURI_PLATFORM_TYPE".into(), "Darwin".into());
-
   if debug {
-    map.insert("TAURI_DEBUG".into(), "true".to_string());
+    map.insert("TAURI_DEBUG", "true".into());
   }
 
   map

+ 3 - 1
tooling/cli/src/interface/mod.rs

@@ -5,6 +5,7 @@
 pub mod rust;
 
 use std::{
+  collections::HashMap,
   path::{Path, PathBuf},
   process::ExitStatus,
 };
@@ -75,8 +76,9 @@ pub enum ExitReason {
 pub trait Interface: Sized {
   type AppSettings: AppSettings;
 
-  fn new(config: &Config) -> crate::Result<Self>;
+  fn new(config: &Config, target: Option<String>) -> crate::Result<Self>;
   fn app_settings(&self) -> &Self::AppSettings;
+  fn env(&self) -> HashMap<&str, String>;
   fn build(&mut self, options: Options) -> crate::Result<()>;
   fn dev<F: Fn(ExitStatus, ExitReason) + Send + Sync + 'static>(
     &mut self,

+ 71 - 9
tooling/cli/src/interface/rust.rs

@@ -3,6 +3,7 @@
 // SPDX-License-Identifier: MIT
 
 use std::{
+  collections::HashMap,
   ffi::OsStr,
   fs::{File, FileType},
   io::{Read, Write},
@@ -123,7 +124,7 @@ pub struct Rust {
 impl Interface for Rust {
   type AppSettings = RustAppSettings;
 
-  fn new(config: &Config) -> crate::Result<Self> {
+  fn new(config: &Config, target: Option<String>) -> crate::Result<Self> {
     let manifest = {
       let (tx, rx) = sync_channel(1);
       let mut watcher = new_debouncer(Duration::from_secs(1), None, move |r| {
@@ -154,7 +155,7 @@ impl Interface for Rust {
     }
 
     Ok(Self {
-      app_settings: RustAppSettings::new(config, manifest)?,
+      app_settings: RustAppSettings::new(config, manifest, target)?,
       config_features: config.build.features.clone().unwrap_or_default(),
       product_name: config.package.product_name.clone(),
       available_targets: None,
@@ -206,6 +207,52 @@ impl Interface for Rust {
       self.run_dev_watcher(child, options, on_exit)
     }
   }
+
+  fn env(&self) -> HashMap<&str, String> {
+    let mut env = HashMap::new();
+    env.insert(
+      "TAURI_TARGET_TRIPLE",
+      self.app_settings.target_triple.clone(),
+    );
+
+    let mut s = self.app_settings.target_triple.split('-');
+    let (arch, _, host) = (s.next().unwrap(), s.next().unwrap(), s.next().unwrap());
+    env.insert(
+      "TAURI_ARCH",
+      match arch {
+        // keeps compatibility with old `std::env::consts::ARCH` implementation
+        "i686" | "i586" => "x86".into(),
+        a => a.into(),
+      },
+    );
+    env.insert(
+      "TAURI_PLATFORM",
+      match host {
+        // keeps compatibility with old `std::env::consts::OS` implementation
+        "darwin" => "macos".into(),
+        "ios-sim" => "ios".into(),
+        "androideabi" => "android".into(),
+        h => h.into(),
+      },
+    );
+
+    env.insert(
+      "TAURI_FAMILY",
+      match host {
+        "windows" => "windows".into(),
+        _ => "unix".into(),
+      },
+    );
+
+    match host {
+      "linux" => env.insert("TAURI_PLATFORM_TYPE", "Linux".into()),
+      "windows" => env.insert("TAURI_PLATFORM_TYPE", "Windows_NT".into()),
+      "darwin" => env.insert("TAURI_PLATFORM_TYPE", "Darwin".into()),
+      _ => None,
+    };
+
+    env
+  }
 }
 
 fn lookup<F: FnMut(FileType, PathBuf)>(dir: &Path, mut f: F) {
@@ -437,6 +484,7 @@ pub struct RustAppSettings {
   cargo_package_settings: CargoPackageSettings,
   package_settings: PackageSettings,
   cargo_config: CargoConfig,
+  target_triple: String,
 }
 
 impl AppSettings for RustAppSettings {
@@ -468,13 +516,8 @@ impl AppSettings for RustAppSettings {
     let out_dir = self
       .out_dir(options.target.clone(), options.debug)
       .with_context(|| "failed to get project out directory")?;
-    let target: String = if let Some(target) = options.target.clone() {
-      target
-    } else {
-      tauri_utils::platform::target_triple()?
-    };
 
-    let binary_extension: String = if target.contains("windows") {
+    let binary_extension: String = if self.target_triple.contains("windows") {
       "exe"
     } else {
       ""
@@ -590,7 +633,7 @@ impl AppSettings for RustAppSettings {
 }
 
 impl RustAppSettings {
-  pub fn new(config: &Config, manifest: Manifest) -> crate::Result<Self> {
+  pub fn new(config: &Config, manifest: Manifest, target: Option<String>) -> crate::Result<Self> {
     let cargo_settings =
       CargoSettings::load(&tauri_dir()).with_context(|| "failed to load cargo settings")?;
     let cargo_package_settings = match &cargo_settings.package {
@@ -626,12 +669,31 @@ impl RustAppSettings {
 
     let cargo_config = CargoConfig::load(&tauri_dir())?;
 
+    let target_triple = target.unwrap_or_else(|| {
+      cargo_config
+        .build()
+        .target()
+        .map(|t| t.to_string())
+        .unwrap_or_else(|| {
+          let output = Command::new("rustc").args(&["-vV"]).output().unwrap();
+          let stdout = String::from_utf8_lossy(&output.stdout);
+          stdout
+            .split('\n')
+            .find(|l| l.starts_with("host:"))
+            .unwrap()
+            .replace("host:", "")
+            .trim()
+            .to_string()
+        })
+    });
+
     Ok(Self {
       manifest,
       cargo_settings,
       cargo_package_settings,
       package_settings,
       cargo_config,
+      target_triple,
     })
   }
 

+ 19 - 5
tooling/cli/src/interface/rust/cargo_config.rs

@@ -50,13 +50,16 @@ impl Config {
   pub fn load(path: &Path) -> Result<Self> {
     let mut config = Self::default();
 
+    let get_config = |path: PathBuf| -> Result<ConfigSchema> {
+      let contents = fs::read_to_string(&path)
+        .with_context(|| format!("failed to read configuration file `{}`", path.display()))?;
+      toml::from_str(&contents)
+        .with_context(|| format!("could not parse TOML configuration in `{}`", path.display()))
+    };
+
     for current in PathAncestors::new(path) {
       if let Some(path) = get_file_path(&current.join(".cargo"), "config", true)? {
-        let contents = fs::read_to_string(&path)
-          .with_context(|| format!("failed to read configuration file `{}`", path.display()))?;
-        let toml: ConfigSchema = toml::from_str(&contents)
-          .with_context(|| format!("could not parse TOML configuration in `{}`", path.display()))?;
-
+        let toml = get_config(path)?;
         if let Some(target) = toml.build.and_then(|b| b.target) {
           config.build.target = Some(target);
           break;
@@ -64,6 +67,17 @@ impl Config {
       }
     }
 
+    if config.build.target.is_none() {
+      if let Ok(cargo_home) = std::env::var("CARGO_HOME") {
+        if let Some(path) = get_file_path(&PathBuf::from(cargo_home), "config", true)? {
+          let toml = get_config(path)?;
+          if let Some(target) = toml.build.and_then(|b| b.target) {
+            config.build.target = Some(target);
+          }
+        }
+      }
+    }
+
     Ok(config)
   }