1

I'm trying to publish a sys crate for libvmaf. Unfortunately I can not simply dynamically link to libvmaf because it's not distributed anywhere and I need to build it from source and include it in my library. Unfortunately libvmaf is absolutely huge and my .rlib file is ending up at 1.4 megabytes which is over the upload limit for crates.io. Am I boned here?

Here's my build.rs file

use meson_next;
use std::env;
use std::fs::canonicalize;
use std::path::PathBuf;

fn main() {
    //env::set_var("RUST_BACKTRACE", "1");
    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();

    meson_next::build("vmaf/libvmaf", build_dir_str);

    println!("cargo:rustc-link-lib=static=vmaf");
    println!("cargo:rustc-link-search=native={lib_dir_str}");

    // Path to vendor header files
    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();

    // Generate bindings to libvmaf using rust-bindgen
    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");

    // Write bindings to build directory
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

Brandon Piña
  • 614
  • 1
  • 6
  • 20

1 Answers1

0

In general you should not be including compiled libraries in your package. Include the source code, and have your build script perform the build.

This will usually result in a smaller package, and also means that your package works on any target architecture (that is supported by the library).

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
  • That is what I'm doing. I probably should have explained better in my question but I'm importing vmaf as a git submodule and then using the meson crate compiling the library, linking to it then generating library bindings – Brandon Piña Nov 24 '22 at 21:38
  • 1
    @BrandonPiña If you're including source only, then no `.rlib` file should be ending up in your package. – Kevin Reid Nov 24 '22 at 22:23
  • Clearly something large is somehow getting included in my crate. Could you refer me to what actually gets included in a crate as it's uploaded to crates.io so I can track it down? – Brandon Piña Nov 24 '22 at 22:40
  • 1
    @BrandonPiña `cargo package --list` should list what's actually being included. To alter it, use [the `exclude` and `include` manifest fields](https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields). – Kevin Reid Nov 25 '22 at 01:16