Rust in Everything
基于 tauri 2.12.5

does not match the allowlist defined under tauri.conf.json

主线位置:启动主线之前的编译期。应用 crate 的 build script 调 tauri_build::build(),它读完配置之后、收集权限之前,先核对 Cargo.toml 里 tauri 依赖的 feature 和配置是否一致(tauri-build 的「核对 feature」一节讲了这一步在整个 try_build 里的位置)。不一致时构建停在 build script,应用代码一行都没编。

flowchart TB
  conf["tauri.conf.json"] --> expect["期望的 feature"]
  toml["Cargo.toml 里 tauri 的 features 数组"] --> filt["只留 CLI 管的三个"]
  expect --> diffn["两边做差集"]
  filt --> diffn
  diffn -->|"多出来的"| rm["remove the ... feature"]
  diffn -->|"缺的"| add["add the ... feature"]
  diffn -->|"相同"| okn["继续构建"]

本页实验 crate 是 pit1-feat:由模板 base 复制,依次改 Cargo.toml 和 tauri.conf.json 再 cargo build --offline --features tauri/custom-protocol。M2 Max、macOS 27、rustc 1.99.0,tauri =2.12.5、tauri-build =2.7.4。

现象

一:开了 feature,配置里没开

给 tauri 加上 protocol-asset,配置不动:

[dependencies]
tauri = { version = "=2.12.5", features = ["test", "protocol-asset"] }
error: failed to run custom build command for `pit1-feat v0.1.0 (~/exp-tauri/pit1-feat)`

Caused by:
  process didn't exit successfully: `~/exp-tauri/target-pit1/debug/build/pit1-feat-eaa71678969239ea/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-env-changed=TAURI_CONFIG
  cargo:rustc-check-cfg=cfg(desktop)
  cargo:rustc-cfg=desktop
  cargo:rustc-check-cfg=cfg(mobile)
  cargo:rerun-if-changed=~/exp-tauri/pit1-feat/tauri.conf.json
  cargo:rustc-env=TAURI_ANDROID_PACKAGE_NAME_APP_NAME=base
  cargo:rustc-env=TAURI_ANDROID_PACKAGE_NAME_PREFIX=app_rustineverything_exp
  cargo:rustc-check-cfg=cfg(dev)

        The `tauri` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
        Please run `tauri dev` or `tauri build` or remove the `protocol-asset` feature.

错误文字在 --- stdout 段里,不在 --- stderr:build script 用 println! 报错再 exit(1)。

二:配置里开了,feature 没开

去掉 feature,在配置里打开资源协议:

"security": { "assetProtocol": { "enable": true, "scope": [] } }
...
        The `tauri` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
        Please run `tauri dev` or `tauri build` or add the `protocol-asset` feature.

三:feature 其实开了,只是没写在 tauri 依赖上

配置不变(enable: true),tauri 依赖上不写 protocol-asset,改由应用自己的 feature 间接打开,并设为默认:

[dependencies]
tauri = { version = "=2.12.5", features = ["test"] }

[features]
default = ["assets"]
assets = ["tauri/protocol-asset"]
...
        The `tauri` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
        Please run `tauri dev` or `tauri build` or add the `protocol-asset` feature.

这次编出来的 tauri 确实带着 protocol-asset,报错照样要求「add」。反过来,把配置里的 assetProtocol 删掉、保留这段 [features],构建成功:检查也看不到这条间接打开的 feature。

出处

manifest::check 用 cargo_toml 解析应用的 Cargo.toml,对两个依赖各做一次核对:tauri-build(只管 isolation)和 tauri(管 AppConfig::all_features 去掉 tray-icon 之后的 macos-private-api、protocol-asset、isolation)。期望值来自 AppConfig::features,实际值来自 check_features:

fn check_features(dependency: Dependency, metadata: &AllowlistedDependency) -> Result<(), String> {
  let features = match dependency {
    Dependency::Simple(_) => Vec::new(),
    Dependency::Detailed(dep) => dep.features,
    Dependency::Inherited(dep) => dep.features,
  };

  let diff = features_diff(
    &features
      .into_iter()
      .filter(|f| metadata.all_cli_managed_features.contains(&f.as_str()))
      .collect::<Vec<String>>(),
    &metadata.expected_features,
  );

「实际值」就是依赖声明里那个 features 数组的字面内容,不是 cargo 最终解析出的 feature 集合。[features] 里的 "tauri/protocol-asset"、命令行的 --features tauri/protocol-asset、工作区里别的 crate 打开的 feature,这里都看不到,所以情形三被判为缺失。tauri = "2" 这种简写(Dependency::Simple)算作一个 feature 都没开。

配置和 feature 的对应关系:

配置tauri 的 feature另外要求
app.security.assetProtocol.enable: trueprotocol-asset
app.security.pattern 是 isolationisolationtauri-build 也要开 isolation
app.macOSPrivateApi: truemacos-private-api2.12.1 起两者都不再需要(#16166),检查仍在
app.trayIcontray-icon不参与这项检查

提示里的「Please run tauri dev or tauri build」指的是 CLI 会在构建前按配置改写 Cargo.toml 里的这几个 feature,用 CLI 的项目一般碰不到这个错误;只用 cargo 构建的项目要自己维护两边。

修法

两边同时写明:feature 写在 tauri 依赖自己的 features 数组里,配置里打开对应项。

[dependencies]
tauri = { version = "=2.12.5", features = ["test", "protocol-asset"] }
"security": { "assetProtocol": { "enable": true, "scope": [] } }

构建通过,运行:

REPORT greet=hello, rie origin=tauri://localhost

想用自己的 feature 开关某个能力(比如只在某个构建里打开资源协议),检查不允许这样做:它只认依赖声明上的字面值。可行的办法是两套配置加两份 Cargo.toml 的依赖声明,或者用 CLI 构建。

怎么确认没中招

  • 改配置里 assetProtocol、pattern、macOSPrivateApi 时,同一个提交里 Cargo.toml 的 tauri 依赖(以及 tauri-build,对 isolation)跟着改。
  • 构建失败时先看 cargo 输出的 --- stdout 段:「remove the」是 feature 多了,「add the」是 feature 少了(或者写在了别处)。
  • 这个检查不管运行时:情形三去掉配置之后能编过,protocol-asset 照样编进了二进制。资源协议的配置在运行时怎么用见 资源协议。

小结

  • tauri-build 拿配置推出的 feature 和 Cargo.toml 里 tauri 依赖的 features 数组做差集,只看 macos-private-api、protocol-asset、isolation;tauri-build 的 isolation 另算一次。
  • 多了报「remove the ... feature」,少了报「add the ... feature」,错误在 build script 的 stdout 里。
  • 只认依赖声明上的字面值:经自己的 [features]、命令行或别的 crate 打开的 feature 一律当作没开。
  • 修法是两边同时写明;用 CLI 构建时它会替你改写 Cargo.toml。

💬 关联讨论

发起讨论
加载中...