Rust Bindgen 在构建时导致“不是有效的 Ident”错误

Ign*_*dio 4 clang rust bindgen

有谁知道如何开始调试这个 Rust bindgen 缩进问题?

stderr thread 'main' panicked at '"vpx_codec_ctx_union_(unnamed_at_/usr/include/vpx/_/vpx_codec_h_206_3)" is not a valid Ident', /home/ignis/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-1.0.59/src/fallback.rs:811:9

这是引用 libvpx 标头的这一部分:

/*!\brief Codec context structure
 *
 * All codecs \ref MUST support this context structure fully. In general,
 * this data should be considered private to the codec algorithm, and
 * not be manipulated or examined by the calling application. Applications
 * may reference the 'name' member to get a printable description of the
 * algorithm.
 */
typedef struct vpx_codec_ctx {
  const char *name;             /**< Printable interface name */
  vpx_codec_iface_t *iface;     /**< Interface pointers */
  vpx_codec_err_t err;          /**< Last returned error */
  const char *err_detail;       /**< Detailed info, if available */
  vpx_codec_flags_t init_flags; /**< Flags passed at init time */
  union {
    /**< Decoder Configuration Pointer */
    const struct vpx_codec_dec_cfg *dec;
    /**< Encoder Configuration Pointer */
    const struct vpx_codec_enc_cfg *enc;
    const void *raw;
  } config;               /**< Configuration pointer aliasing union */
  vpx_codec_priv_t *priv; /**< Algorithm private storage */
} vpx_codec_ctx_t;
Run Code Online (Sandbox Code Playgroud)

我在网上看到很多关于将这些类型列入黑名单的答案,但我无法将其列入黑名单,因为需要上下文类型。看来联合类型引起了麻烦......

更新:找到 vpx-sys 文档的相关部分:https://docs.rs/env-libvpx-sys/5.1.2/vpx_sys

似乎库作者能够生成绑定......

Ign*_*dio 6

这是令人恐慌的代码:

pub(crate) fn is_ident_start(c: char) -> bool {
    c == '_' || unicode_ident::is_xid_start(c)
}

pub(crate) fn is_ident_continue(c: char) -> bool {
    unicode_ident::is_xid_continue(c)
}

fn validate_ident(string: &str, raw: bool) {
    if string.is_empty() {
        panic!("Ident is not allowed to be empty; use Option<Ident>");
    }

    if string.bytes().all(|digit| digit >= b'0' && digit <= b'9') {
        panic!("Ident cannot be a number; use Literal instead");
    }

    fn ident_ok(string: &str) -> bool {
        let mut chars = string.chars();
        let first = chars.next().unwrap();
        if !is_ident_start(first) {
            return false;
        }
        for ch in chars {
            if !is_ident_continue(ch) {
                return false;
            }
        }
        true
    }

    if !ident_ok(string) {
        panic!("{:?} is not a valid Ident", string);
    }

    if raw {
        match string {
            "_" | "super" | "self" | "Self" | "crate" => {
                panic!("`r#{}` cannot be a raw identifier", string);
            }
            _ => {}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这只是检查标识符中是否包含有效字符。在这种情况下,((我怀疑/)是无效字符。

那么为什么会发生这种情况呢?看一下错误信息:"vpx_codec_ctx_union_(unnamed_at_/usr/include/vpx/_/vpx_codec_h_206_3)" is not a valid Ident

这部分的一切(unamed...)不应该发展到这个阶段。通过搜索,我们发现了 rust-bindgen 问题,引用了导致更改的 libclang 提交

具体来说,该提交是针对 Clang 16 的。因此,要么将 Clang 降级到 16 之前的版本,要么将您的 bindgen crate 更新到 v0.62.0 或更高版本(这是应用修复的时候)。