问题描述

上周笔者在使用 Buck2 构建 youki 项目下的 libcontainer 时出现了以下报错:

error[E0599]: no method named `get_notify_fd` found for struct `ScmpFilterContext` in the current scope
   --> crates/libcontainer/src/seccomp/mod.rs:268:17
    |
268 |             ctx.get_notify_fd()
    |                 ^^^^^^^^^^^^^ method not found in `ScmpFilterContext`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `libcontainer` (lib) due to 1 previous error

经过分析,应该是 libseccomp-rs 这个 crate 在构建过程中发生了错误,查询资料发现这个 crate 依赖系统中的 libseccomp 库,并且其版本不低于 2.5.0。

在 Debian 及其派生系统上,我们可以使用以下命令安装 libseccomp 库:

sudo apt-get install seccomp libseccomp-dev

安装完成后,上述问题顺利解决。

但是,笔者昨天在为团队成员从头打包开发环境的时候再次遇到了以上问题,并且确认系统中已经安装 libseccomp 库。

原因分析

考虑到当前系统中已经安装了 libseccomp 库,因此 libseccomp-rs 应该还有其他依赖没有安装导致编译时刻无法获取系统中的 libseccomp 库。

build.rs 中,libseccomp-rs 使用 pkg-config 来探测系统中是否存在 libseccomp 库并设置条件编译标志 libseccomp_v2_5

// build.rs:25-31
if pkg_config::Config::new()
.atleast_version("2.5.0")
.probe("libseccomp")
.is_ok()
{
    println!("cargo:rustc-cfg=libseccomp_v2_5");
}

其中,pkg-config 是一个在编译时帮助管理库文件的工具,它通过 .pc 文件获取库的编译和链接选项并在编译时自动插入,避免了硬编码编译选项的麻烦。

进一步分析 libseccomp-rs 代码可以发现,其入口文件 lib.rs 只在 #[cfg(any(libseccomp_v2_5, doc))] 条件成立的情况下导入了 notify 模块:

// src/lib.rs:75-78
#[cfg(any(libseccomp_v2_5, doc))]
mod notify;
mod syscall;
mod version;

到这里其实问题已经非常明显了,由于笔者打包环境时使用的时全新安装的 Debian 12,系统中默认没有安装 pkg-config 导致即使已经安装 libseccomp 库也无法在构建 libseccomp-rs 时被探测到。

解决方案

安装 pkg-config 工具之后就可以顺利构建了:

sudo apt-get install pkg-config

参考资料