verify.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. use crate::{wasm_bindgen::WasmBindgen, BuildRequest, Error, Platform, Result, RustcDetails};
  2. use anyhow::{anyhow, Context};
  3. impl BuildRequest {
  4. /// Check for tooling that might be required for this build.
  5. ///
  6. /// This should generally be only called on the first build since it takes time to verify the tooling
  7. /// is in place, and we don't want to slow down subsequent builds.
  8. pub(crate) async fn verify_tooling(&self) -> Result<()> {
  9. tracing::debug!("Verifying tooling...");
  10. self.status_installing_tooling();
  11. self.krate
  12. .initialize_profiles()
  13. .context("Failed to initialize profiles - dioxus can't build without them. You might need to initialize them yourself.")?;
  14. let rustc = match RustcDetails::from_cli().await {
  15. Ok(out) => out,
  16. Err(err) => {
  17. tracing::error!("Failed to verify tooling: {err}\ndx will proceed, but you might run into errors later.");
  18. return Ok(());
  19. }
  20. };
  21. match self.build.platform() {
  22. Platform::Web => self.verify_web_tooling(rustc).await?,
  23. Platform::Ios => self.verify_ios_tooling(rustc).await?,
  24. Platform::Android => self.verify_android_tooling(rustc).await?,
  25. Platform::Linux => self.verify_linux_tooling(rustc).await?,
  26. Platform::MacOS => {}
  27. Platform::Windows => {}
  28. Platform::Server => {}
  29. Platform::Liveview => {}
  30. }
  31. Ok(())
  32. }
  33. pub(crate) async fn verify_web_tooling(&self, rustc: RustcDetails) -> Result<()> {
  34. // Install target using rustup.
  35. #[cfg(not(feature = "no-downloads"))]
  36. if !rustc.has_wasm32_unknown_unknown() {
  37. tracing::info!(
  38. "Web platform requires wasm32-unknown-unknown to be installed. Installing..."
  39. );
  40. let _ = tokio::process::Command::new("rustup")
  41. .args(["target", "add", "wasm32-unknown-unknown"])
  42. .output()
  43. .await?;
  44. }
  45. // Ensure target is installed.
  46. if !rustc.has_wasm32_unknown_unknown() {
  47. return Err(Error::Other(anyhow!(
  48. "Missing target wasm32-unknown-unknown."
  49. )));
  50. }
  51. // Wasm bindgen
  52. let krate_bindgen_version = self.krate.wasm_bindgen_version().ok_or(anyhow!(
  53. "failed to detect wasm-bindgen version, unable to proceed"
  54. ))?;
  55. WasmBindgen::verify_install(&krate_bindgen_version).await?;
  56. Ok(())
  57. }
  58. /// Currently does nothing, but eventually we need to check that the mobile tooling is installed.
  59. ///
  60. /// For ios, this would be just aarch64-apple-ios + aarch64-apple-ios-sim, as well as xcrun and xcode-select
  61. ///
  62. /// We don't auto-install these yet since we're not doing an architecture check. We assume most users
  63. /// are running on an Apple Silicon Mac, but it would be confusing if we installed these when we actually
  64. /// should be installing the x86 versions.
  65. pub(crate) async fn verify_ios_tooling(&self, _rustc: RustcDetails) -> Result<()> {
  66. // open the simulator
  67. // _ = tokio::process::Command::new("open")
  68. // .arg("/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app")
  69. // .stderr(Stdio::piped())
  70. // .stdout(Stdio::piped())
  71. // .status()
  72. // .await;
  73. // Now xcrun to open the device
  74. // todo: we should try and query the device list and/or parse it rather than hardcode this simulator
  75. // _ = tokio::process::Command::new("xcrun")
  76. // .args(["simctl", "boot", "83AE3067-987F-4F85-AE3D-7079EF48C967"])
  77. // .stderr(Stdio::piped())
  78. // .stdout(Stdio::piped())
  79. // .status()
  80. // .await;
  81. // if !rustup
  82. // .installed_toolchains
  83. // .contains(&"aarch64-apple-ios".to_string())
  84. // {
  85. // tracing::error!("You need to install aarch64-apple-ios to build for ios. Run `rustup target add aarch64-apple-ios` to install it.");
  86. // }
  87. // if !rustup
  88. // .installed_toolchains
  89. // .contains(&"aarch64-apple-ios-sim".to_string())
  90. // {
  91. // tracing::error!("You need to install aarch64-apple-ios to build for ios. Run `rustup target add aarch64-apple-ios` to install it.");
  92. // }
  93. Ok(())
  94. }
  95. /// Check if the android tooling is installed
  96. ///
  97. /// looks for the android sdk + ndk
  98. ///
  99. /// will do its best to fill in the missing bits by exploring the sdk structure
  100. /// IE will attempt to use the Java installed from android studio if possible.
  101. pub(crate) async fn verify_android_tooling(&self, _rustc: RustcDetails) -> Result<()> {
  102. let result = self
  103. .krate
  104. .android_ndk()
  105. .map(|ndk| self.build.target_args.arch().android_linker(&ndk));
  106. if let Some(path) = result {
  107. if path.exists() {
  108. return Ok(());
  109. }
  110. }
  111. Err(anyhow::anyhow!(
  112. "Android linker not found. Please set the `ANDROID_NDK_HOME` environment variable to the root of your NDK installation."
  113. ).into())
  114. }
  115. /// Ensure the right dependencies are installed for linux apps.
  116. /// This varies by distro, so we just do nothing for now.
  117. ///
  118. /// Eventually, we want to check for the prereqs for wry/tao as outlined by tauri:
  119. /// https://tauri.app/start/prerequisites/
  120. pub(crate) async fn verify_linux_tooling(&self, _rustc: RustcDetails) -> Result<()> {
  121. Ok(())
  122. }
  123. }