Podman容器构建含SQLite的Rust项目时绑定复制权限错误
背景信息
- 在VSCode中使用远程容器开发,将Docker替换为Podman(首次使用Podman,相关知识不足)
- 正在开发一个基于PostgreSQL存储的小型API,已完成配置、迁移工作,运行正常
问题描述
为编写测试,计划使用SQLite内存数据库避免临时数据库的麻烦,执行以下步骤后出现编译错误:
- 在
Cargo.toml的diesel依赖中添加sqlite特性:
diesel = { version = "1.4.8", features = ["postgres", "sqlite", "uuidv07"] }
- 创建使用Diesel SQLite连接的结构体
TestDbConn:
pub struct TestDbConn(diesel::SqliteConnection);
- 执行
cargo build时出现如下错误:
Compiling libsqlite3-sys v0.22.2 error: failed to run custom build command for `libsqlite3-sys v0.22.2` Caused by: process didn't exit successfully: `/workspace/target/debug/build/libsqlite3-sys-55c095f61869bd3c/build-script-build` (exit status: 101) --- stdout cargo:rerun-if-env-changed=SQLITE3_INCLUDE_DIR cargo:rerun-if-env-changed=SQLITE3_LIB_DIR cargo:rerun-if-env-changed=SQLITE3_STATIC cargo:link-target=sqlite3 cargo:rerun-if-env-changed=SQLITE3_NO_PKG_CONFIG cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG cargo:rerun-if-env-changed=PKG_CONFIG cargo:rerun-if-env-changed=SQLITE3_STATIC cargo:rerun-if-env-changed=SQLITE3_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR cargo:rerun-if-env-changed=SYSROOT cargo:rerun-if-env-changed=SQLITE3_STATIC cargo:rerun-if-env-changed=SQLITE3_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC cargo:rustc-link-lib=sqlite3 cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG cargo:rerun-if-env-changed=PKG_CONFIG cargo:rerun-if-env-changed=SQLITE3_STATIC cargo:rerun-if-env-changed=SQLITE3_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR --- stderr thread 'main' panicked at 'Could not copy bindings to output directory: Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }', /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/libsqlite3-sys-0.22.2/build.rs:348:37 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace warning: build failed, waiting for other jobs to finish...
当前排查方向
- Rust的SQLite3依赖
libsqlite3-sys使用bindgen生成C语言绑定 - 绑定生成过程需要将文件写入特定目录
bindgen支持通过OUT_DIR环境变量自定义绑定输出目录- 以拥有
/workspace/目录权限的vscode用户执行OUT_DIR=/workspace/ cargo build,仍出现相同错误 - 怀疑问题源于Podman默认非root运行容器,导致
bindgen尝试写入无权限的系统目录 - 切换回Docker后编译正常
解决方案
方案1:使用libsqlite3-sys的bundled特性(推荐)
在Cargo.toml中为libsqlite3-sys添加bundled特性,该特性会编译依赖自带的SQLite源码,无需调用系统SQLite库,也就跳过了bindgen生成绑定的步骤,从根源避免权限问题:
[dependencies] diesel = { version = "1.4.8", features = ["postgres", "sqlite", "uuidv07"] } libsqlite3-sys = { version = "0.22.2", features = ["bundled"] }
添加后重新执行cargo build即可。
方案2:修改Cargo构建目录到有权限的路径
设置CARGO_TARGET_DIR环境变量,将所有构建产物(包括bindgen生成的绑定文件)写入到你拥有权限的/workspace子目录中:
CARGO_TARGET_DIR=/workspace/target cargo build
可以将这个环境变量配置到VSCode的远程容器环境中,避免每次手动输入。
方案3:调整容器目录权限
如果需要使用系统SQLite库,可临时修改libsqlite3-sys构建脚本的目录权限:
sudo chown -R vscode:vscode /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/libsqlite3-sys-0.22.2/
注意:该目录路径会随依赖版本更新变化,需要根据实际报错路径调整,长期来看不如方案1稳定。
内容的提问来源于stack exchange,提问作者Flashito
相关产品推荐
相关产品推荐

