diff --git a/Cargo.toml b/Cargo.toml index adbbc9f..e1b442a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "magnum-opus" -version = "0.3.2" +version = "0.3.3" authors = ["Tad Hardesty ", "Sergey Duck "] edition = "2018" description = "Safe Rust bindings for libopus" @@ -13,6 +13,7 @@ categories = ["api-bindings", "encoding", "compression", repository = "https://github.com/DuckerMan/magnum-opus" documentation = "https://docs.rs/magnum-opus" -[dependencies] -opusic-sys = "0.3" -libc = "0.2" +[build-dependencies] +vcpkg = "0.2" +target_build_utils = "0.3" +bindgen = "0.53" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..7cfead7 --- /dev/null +++ b/build.rs @@ -0,0 +1,71 @@ +use std::{ + env, + path::{Path, PathBuf}, +}; + +fn find_package(name: &str) -> vcpkg::Library { + let mut cfg = vcpkg::Config::new(); + cfg.emit_includes(true); + let mut res = cfg.find_package(name); + if res.is_err() { + let target = { + if cfg!(windows) { + ":x64-windows-static" + } else { + "" + } + }; + std::process::Command::new("vcpkg") + .arg("install") + .arg(format!("{}{}", name, target)) + .status() + .unwrap(); + res = cfg.find_package(name); + } + res.unwrap() +} + +fn generate_bindings(ffi_header: &Path, include_paths: &[PathBuf], ffi_rs: &Path) { + #[derive(Debug)] + struct ParseCallbacks; + impl bindgen::callbacks::ParseCallbacks for ParseCallbacks { + fn int_macro(&self, name: &str, _value: i64) -> Option { + if name.starts_with("OPUS") { + Some(bindgen::callbacks::IntKind::Int) + } else { + None + } + } + } + let mut b = bindgen::Builder::default() + .header(ffi_header.to_str().unwrap()) + .parse_callbacks(Box::new(ParseCallbacks)) + .generate_comments(false); + + for dir in include_paths { + b = b.clang_arg(format!("-I{}", dir.display())); + } + + b.generate().unwrap().write_to_file(ffi_rs).unwrap(); +} + +fn gen_opus() { + let includes = find_package("opus").include_paths; + let src_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); + let src_dir = Path::new(&src_dir); + let out_dir = env::var_os("OUT_DIR").unwrap(); + let out_dir = Path::new(&out_dir); + + let ffi_header = src_dir.join("opus_ffi.h"); + println!("rerun-if-changed={}", ffi_header.display()); + for dir in &includes { + println!("rerun-if-changed={}", dir.display()); + } + + let ffi_rs = out_dir.join("opus_ffi.rs"); + generate_bindings(&ffi_header, &includes, &ffi_rs); +} + +fn main() { + gen_opus() +} diff --git a/opus_ffi.h b/opus_ffi.h new file mode 100644 index 0000000..f6d3aba --- /dev/null +++ b/opus_ffi.h @@ -0,0 +1 @@ +#include diff --git a/src/lib.rs b/src/lib.rs index a347bda..9fb2e11 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,8 @@ //! the [libopus documentation](https://opus-codec.org/docs/opus_api-1.1.2/). #![warn(missing_docs)] -extern crate opusic_sys as ffi; +mod opus_ffi; +use opus_ffi as ffi; use std::ffi::CStr; diff --git a/src/opus_ffi.rs b/src/opus_ffi.rs new file mode 100644 index 0000000..0953b53 --- /dev/null +++ b/src/opus_ffi.rs @@ -0,0 +1,6 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +include!(concat!(env!("OUT_DIR"), "/opus_ffi.rs"));