build.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. use heck::ToSnakeCase;
  5. use once_cell::sync::OnceCell;
  6. use std::{path::Path, sync::Mutex};
  7. static CHECKED_FEATURES: OnceCell<Mutex<Vec<String>>> = OnceCell::new();
  8. // checks if the given Cargo feature is enabled.
  9. fn has_feature(feature: &str) -> bool {
  10. CHECKED_FEATURES
  11. .get_or_init(Default::default)
  12. .lock()
  13. .unwrap()
  14. .push(feature.to_string());
  15. // when a feature is enabled, Cargo sets the `CARGO_FEATURE_<name` env var to 1
  16. // https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
  17. std::env::var(format!(
  18. "CARGO_FEATURE_{}",
  19. feature.to_snake_case().to_uppercase()
  20. ))
  21. .map(|x| x == "1")
  22. .unwrap_or(false)
  23. }
  24. // creates a cfg alias if `has_feature` is true.
  25. // `alias` must be a snake case string.
  26. fn alias(alias: &str, has_feature: bool) {
  27. if has_feature {
  28. println!("cargo:rustc-cfg={}", alias);
  29. }
  30. }
  31. fn main() {
  32. alias("custom_protocol", has_feature("custom-protocol"));
  33. alias("dev", !has_feature("custom-protocol"));
  34. alias("updater", has_feature("updater"));
  35. let api_all = has_feature("api-all");
  36. alias("api_all", api_all);
  37. alias_module(
  38. "fs",
  39. &[
  40. "read-file",
  41. "write-file",
  42. "read-dir",
  43. "copy-file",
  44. "create-dir",
  45. "remove-dir",
  46. "remove-file",
  47. "rename-file",
  48. ],
  49. api_all,
  50. );
  51. alias_module(
  52. "window",
  53. &[
  54. "create",
  55. "center",
  56. "request-user-attention",
  57. "set-resizable",
  58. "set-title",
  59. "maximize",
  60. "unmaximize",
  61. "minimize",
  62. "unminimize",
  63. "show",
  64. "hide",
  65. "close",
  66. "set-decorations",
  67. "set-always-on-top",
  68. "set-size",
  69. "set-min-size",
  70. "set-max-size",
  71. "set-position",
  72. "set-fullscreen",
  73. "set-focus",
  74. "set-icon",
  75. "set-skip-taskbar",
  76. "set-cursor-grab",
  77. "set-cursor-visible",
  78. "set-cursor-icon",
  79. "set-cursor-position",
  80. "start-dragging",
  81. "print",
  82. ],
  83. api_all,
  84. );
  85. alias_module("shell", &["execute", "sidecar", "open"], api_all);
  86. // helper for the command module macro
  87. let shell_script = has_feature("shell-execute") || has_feature("shell-sidecar");
  88. alias("shell_script", shell_script);
  89. alias("shell_scope", has_feature("shell-open-api") || shell_script);
  90. alias_module(
  91. "dialog",
  92. &["open", "save", "message", "ask", "confirm"],
  93. api_all,
  94. );
  95. alias_module("http", &["request"], api_all);
  96. alias("cli", has_feature("cli"));
  97. alias_module("notification", &[], api_all);
  98. alias_module("global-shortcut", &[], api_all);
  99. alias_module("os", &[], api_all);
  100. alias_module("path", &[], api_all);
  101. alias_module("protocol", &["asset"], api_all);
  102. alias_module("process", &["relaunch", "exit"], api_all);
  103. alias_module("clipboard", &["write-text", "read-text"], api_all);
  104. let checked_features_out_path =
  105. Path::new(&std::env::var("OUT_DIR").unwrap()).join("checked_features");
  106. std::fs::write(
  107. &checked_features_out_path,
  108. &CHECKED_FEATURES.get().unwrap().lock().unwrap().join(","),
  109. )
  110. .expect("failed to write checked_features file");
  111. }
  112. // create aliases for the given module with its apis.
  113. // each api is translated into a feature flag in the format of `<module>-<api>`
  114. // and aliased as `<module_snake_case>_<api_snake_case>`.
  115. //
  116. // The `<module>-all` feature is also aliased to `<module>_all`.
  117. //
  118. // If any of the features is enabled, the `<module_snake_case>_any` alias is created.
  119. //
  120. // Note that both `module` and `apis` strings must be written in kebab case.
  121. fn alias_module(module: &str, apis: &[&str], api_all: bool) {
  122. let all_feature_name = format!("{}-all", module);
  123. let all = has_feature(&all_feature_name) || api_all;
  124. alias(&all_feature_name.to_snake_case(), all);
  125. let mut any = all;
  126. for api in apis {
  127. let has = has_feature(&format!("{}-{}", module, api)) || all;
  128. alias(
  129. &format!("{}_{}", module.to_snake_case(), api.to_snake_case()),
  130. has,
  131. );
  132. any = any || has;
  133. }
  134. alias(&format!("{}_any", module.to_snake_case()), any);
  135. }