为libvmaf开发sys crate时遭遇crates.io上传限制求助
解决libvmaf sys crate体积超限问题的方案
关键说明
crates.io的上传限制针对的是crate包本身,而非构建后的产物。你当前的问题是把libvmaf源码直接嵌入到了crate目录里,导致包体积超标。下面是具体解决办法:
1. 用Git子模块替代直接嵌入源码
不要把libvmaf源码直接放进crate文件夹,改用Git子模块管理:
- 删除crate里的
vmaf/libvmaf目录 - 执行命令:
git submodule add https://github.com/Netflix/vmaf.git vmaf,将libvmaf作为子模块引入 - 在
Cargo.toml里添加exclude = ["vmaf/.git"],避免把Git元数据打包进crate - 确保
.gitmodules文件被包含在crate中(不要加到.gitignore)
2. 优化Meson构建参数缩小静态库
当前build.rs直接调用默认构建,没有启用优化或剥离调试信息,导致静态库体积过大。修改构建步骤,添加以下参数:
// 替换原来的meson_next::build调用 meson_next::build_args( "vmaf/libvmaf", build_dir_str, &["--buildtype=release", "-Db_lto=true", "-Db_strip=true"], );
--buildtype=release:启用release模式编译优化-Db_lto=true:开启链接时优化,大幅压缩静态库体积-Db_strip=true:剥离调试信息,进一步减小体积
3. 仅构建必要的libvmaf组件
libvmaf自带测试代码、命令行工具等冗余组件,通过Meson参数禁用它们:
把以下参数添加到构建参数列表中:
"-Dbuild_tests=false", "-Dbuild_examples=false", "-Dbuild_tools=false", "-Denable_float=false", // 如果不需要浮点精度可禁用,进一步缩小体积
4. 验证crate体积
修改后执行cargo package --list,查看将要打包的文件列表,确认体积符合crates.io限制(当前上限10MB)。如果还有冗余文件,在Cargo.toml的exclude字段中添加排除项。
修改后的build.rs示例
use meson_next; use std::env; use std::fs::canonicalize; use std::path::PathBuf; fn main() { let build_dir = PathBuf::from(env::var("OUT_DIR").unwrap()).join("build"); let lib_dir = build_dir.join("src"); let build_dir_str = build_dir.to_str().unwrap(); let lib_dir_str = lib_dir.to_str().unwrap(); // 带优化参数构建libvmaf meson_next::build_args( "vmaf/libvmaf", build_dir_str, &[ "--buildtype=release", "-Db_lto=true", "-Db_strip=true", "-Dbuild_tests=false", "-Dbuild_examples=false", "-Dbuild_tools=false", ], ); println!("cargo:rustc-link-lib=static=vmaf"); println!("cargo:rustc-link-search=native={lib_dir_str}"); // 处理头文件路径 let headers_dir = PathBuf::from("vmaf/libvmaf/include"); let headers_dir_canonical = canonicalize(headers_dir).unwrap(); let include_path = headers_dir_canonical.to_str().unwrap(); // 生成bindings let bindings = bindgen::Builder::default() .header("vmaf/libvmaf/include/libvmaf/libvmaf.h") .clang_arg(format!("-I{include_path}")) .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate() .expect("Unable to generate bindings"); // 写入bindings文件 let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); }
内容的提问来源于stack exchange,提问作者Brandon Piña
相关产品推荐
相关产品推荐

