build.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2019-2023 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. use heck::AsShoutySnakeCase;
  5. use once_cell::sync::OnceCell;
  6. use std::env::var_os;
  7. use std::fs::read_dir;
  8. use std::fs::read_to_string;
  9. use std::fs::write;
  10. use std::{
  11. env::var,
  12. path::{Path, PathBuf},
  13. sync::Mutex,
  14. };
  15. static CHECKED_FEATURES: OnceCell<Mutex<Vec<String>>> = OnceCell::new();
  16. // checks if the given Cargo feature is enabled.
  17. fn has_feature(feature: &str) -> bool {
  18. CHECKED_FEATURES
  19. .get_or_init(Default::default)
  20. .lock()
  21. .unwrap()
  22. .push(feature.to_string());
  23. // when a feature is enabled, Cargo sets the `CARGO_FEATURE_<name>` env var to 1
  24. // https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
  25. std::env::var(format!("CARGO_FEATURE_{}", AsShoutySnakeCase(feature)))
  26. .map(|x| x == "1")
  27. .unwrap_or(false)
  28. }
  29. // creates a cfg alias if `has_feature` is true.
  30. // `alias` must be a snake case string.
  31. fn alias(alias: &str, has_feature: bool) {
  32. if has_feature {
  33. println!("cargo:rustc-cfg={alias}");
  34. }
  35. }
  36. fn main() {
  37. alias("custom_protocol", has_feature("custom-protocol"));
  38. alias("dev", !has_feature("custom-protocol"));
  39. let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
  40. let mobile = target_os == "ios" || target_os == "android";
  41. alias("desktop", !mobile);
  42. alias("mobile", mobile);
  43. let checked_features_out_path = Path::new(&var("OUT_DIR").unwrap()).join("checked_features");
  44. std::fs::write(
  45. checked_features_out_path,
  46. CHECKED_FEATURES.get().unwrap().lock().unwrap().join(","),
  47. )
  48. .expect("failed to write checked_features file");
  49. if target_os == "android" {
  50. if let Ok(kotlin_out_dir) = std::env::var("WRY_ANDROID_KOTLIN_FILES_OUT_DIR") {
  51. fn env_var(var: &str) -> String {
  52. std::env::var(var).unwrap_or_else(|_| {
  53. panic!(
  54. "`{}` is not set, which is needed to generate the kotlin files for android.",
  55. var
  56. )
  57. })
  58. }
  59. let package = env_var("WRY_ANDROID_PACKAGE");
  60. let library = env_var("WRY_ANDROID_LIBRARY");
  61. let kotlin_out_dir = PathBuf::from(&kotlin_out_dir)
  62. .canonicalize()
  63. .unwrap_or_else(move |_| {
  64. panic!("Failed to canonicalize `WRY_ANDROID_KOTLIN_FILES_OUT_DIR` path {kotlin_out_dir}")
  65. });
  66. let kotlin_files_path =
  67. PathBuf::from(env_var("CARGO_MANIFEST_DIR")).join("mobile/android-codegen");
  68. println!("cargo:rerun-if-changed={}", kotlin_files_path.display());
  69. let kotlin_files =
  70. read_dir(kotlin_files_path).expect("failed to read Android codegen directory");
  71. for file in kotlin_files {
  72. let file = file.unwrap();
  73. let content = read_to_string(file.path())
  74. .expect("failed to read kotlin file as string")
  75. .replace("{{package}}", &package)
  76. .replace("{{library}}", &library);
  77. let out_path = kotlin_out_dir.join(file.file_name());
  78. write(&out_path, content).expect("Failed to write kotlin file");
  79. println!("cargo:rerun-if-changed={}", out_path.display());
  80. }
  81. }
  82. if let Some(project_dir) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
  83. let tauri_proguard = include_str!("./mobile/proguard-tauri.pro").replace(
  84. "$PACKAGE",
  85. &var("WRY_ANDROID_PACKAGE").expect("missing `WRY_ANDROID_PACKAGE` environment variable"),
  86. );
  87. std::fs::write(
  88. project_dir.join("app").join("proguard-tauri.pro"),
  89. tauri_proguard,
  90. )
  91. .expect("failed to write proguard-tauri.pro");
  92. }
  93. let lib_path =
  94. PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("mobile/android");
  95. println!("cargo:android_library_path={}", lib_path.display());
  96. }
  97. #[cfg(target_os = "macos")]
  98. {
  99. if target_os == "ios" {
  100. let lib_path =
  101. PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("mobile/ios-api");
  102. tauri_build::mobile::link_swift_library("Tauri", &lib_path);
  103. println!("cargo:ios_library_path={}", lib_path.display());
  104. }
  105. }
  106. }