From b6720b8937e847637b894bbb7008d1c46a852960 Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Fri, 30 Aug 2019 17:30:32 +0200 Subject: [PATCH] Create bindings automatically using rust-bindgen Signed-off-by: Victor Porof --- lmdb-sys/Cargo.toml | 3 +- lmdb-sys/build.rs | 72 +++++++++++++++++++--- lmdb-sys/src/constants.rs | 125 -------------------------------------- lmdb-sys/src/ffi.rs | 118 ----------------------------------- lmdb-sys/src/lib.rs | 6 +- 5 files changed, 67 insertions(+), 257 deletions(-) delete mode 100644 lmdb-sys/src/constants.rs delete mode 100644 lmdb-sys/src/ffi.rs diff --git a/lmdb-sys/Cargo.toml b/lmdb-sys/Cargo.toml index cfd833e..36ca506 100644 --- a/lmdb-sys/Cargo.toml +++ b/lmdb-sys/Cargo.toml @@ -3,7 +3,7 @@ name = "lmdb-rkv-sys" # NB: When modifying, also modify html_root_url in lib.rs version = "0.8.6" -authors = ["Dan Burkert "] +authors = ["Dan Burkert ", "Victor Porof "] license = "Apache-2.0" description = "Rust bindings for liblmdb." @@ -21,6 +21,7 @@ libc = "0.2" [build-dependencies] pkg-config = "0.3.2" cc = "1" +bindgen = "0.50" [features] default = [] diff --git a/lmdb-sys/build.rs b/lmdb-sys/build.rs index 0a115da..2536bc5 100644 --- a/lmdb-sys/build.rs +++ b/lmdb-sys/build.rs @@ -1,6 +1,9 @@ -extern crate pkg_config; +extern crate bindgen; extern crate cc; +extern crate pkg_config; +use bindgen::callbacks::IntKind; +use bindgen::callbacks::ParseCallbacks; use std::env; use std::path::PathBuf; @@ -32,19 +35,72 @@ const MDB_IDL_LOGN: u8 = 15; )))] const MDB_IDL_LOGN: u8 = 16; +#[derive(Debug)] +struct Callbacks; + +impl ParseCallbacks for Callbacks { + fn int_macro(&self, name: &str, _value: i64) -> Option { + match name { + "MDB_SUCCESS" + | "MDB_KEYEXIST" + | "MDB_NOTFOUND" + | "MDB_PAGE_NOTFOUND" + | "MDB_CORRUPTED" + | "MDB_PANIC" + | "MDB_VERSION_MISMATCH" + | "MDB_INVALID" + | "MDB_MAP_FULL" + | "MDB_DBS_FULL" + | "MDB_READERS_FULL" + | "MDB_TLS_FULL" + | "MDB_TXN_FULL" + | "MDB_CURSOR_FULL" + | "MDB_PAGE_FULL" + | "MDB_MAP_RESIZED" + | "MDB_INCOMPATIBLE" + | "MDB_BAD_RSLOT" + | "MDB_BAD_TXN" + | "MDB_BAD_VALSIZE" + | "MDB_BAD_DBI" + | "MDB_LAST_ERRCODE" => Some(IntKind::Int), + _ => Some(IntKind::UInt), + } + } +} + fn main() { - let mut lmdb: PathBuf = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()); + let mut lmdb = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()); lmdb.push("lmdb"); lmdb.push("libraries"); lmdb.push("liblmdb"); if !pkg_config::find_library("liblmdb").is_ok() { cc::Build::new() - .define("MDB_IDL_LOGN", Some(MDB_IDL_LOGN.to_string().as_str())) - .file(lmdb.join("mdb.c")) - .file(lmdb.join("midl.c")) - // https://github.com/LMDB/lmdb/blob/LMDB_0.9.21/libraries/liblmdb/Makefile#L25 - .opt_level(2) - .compile("liblmdb.a") + .define("MDB_IDL_LOGN", Some(MDB_IDL_LOGN.to_string().as_str())) + .file(lmdb.join("mdb.c")) + .file(lmdb.join("midl.c")) + // https://github.com/LMDB/lmdb/blob/LMDB_0.9.21/libraries/liblmdb/Makefile#L25 + .opt_level(2) + .compile("liblmdb.a") } + + let bindings = bindgen::Builder::default() + .header(lmdb.join("lmdb.h").to_string_lossy()) + .whitelist_var("^(MDB|mdb)_.*") + .whitelist_type("^(MDB|mdb)_.*") + .whitelist_function("^(MDB|mdb)_.*") + .ctypes_prefix("::libc") + .blacklist_item("mode_t") + .blacklist_item("^__.*") + .parse_callbacks(Box::new(Callbacks {})) + .layout_tests(false) + .prepend_enum_name(false) + .rustfmt_bindings(true) + .generate() + .expect("Unable to generate 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!"); } diff --git a/lmdb-sys/src/constants.rs b/lmdb-sys/src/constants.rs deleted file mode 100644 index 227c685..0000000 --- a/lmdb-sys/src/constants.rs +++ /dev/null @@ -1,125 +0,0 @@ -use libc::{c_int, c_uint}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//// Environment Flags -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/// mmap at a fixed address (experimental) -pub const MDB_FIXEDMAP: c_uint = 0x01; -/// no environment directory -pub const MDB_NOSUBDIR: c_uint = 0x4000; -/// don't fsync after commit -pub const MDB_NOSYNC: c_uint = 0x10000; -/// read only -pub const MDB_RDONLY: c_uint = 0x20000; -/// don't fsync metapage after commit -pub const MDB_NOMETASYNC: c_uint = 0x40000; -/// use writable mmap -pub const MDB_WRITEMAP: c_uint = 0x80000; -/// use asynchronous msync when #MDB_WRITEMAP is used -pub const MDB_MAPASYNC: c_uint = 0x100000; -/// tie reader locktable slots to #MDB_txn objects instead of to threads -pub const MDB_NOTLS: c_uint = 0x200000; -/// don't do any locking, caller must manage their own locks -pub const MDB_NOLOCK: c_uint = 0x400000; -/// don't do readahead (no effect on Windows) -pub const MDB_NORDAHEAD: c_uint = 0x800000; -/// don't initialize malloc'd memory before writing to datafile -pub const MDB_NOMEMINIT: c_uint = 0x1000000; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//// Database Flags -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/// use reverse string keys -pub const MDB_REVERSEKEY: c_uint = 0x02; -/// use sorted duplicates -pub const MDB_DUPSORT: c_uint = 0x04; -/// numeric keys in native byte order. The keys must all be of the same size. -pub const MDB_INTEGERKEY: c_uint = 0x08; -/// with `MDB_DUPSORT`, sorted dup items have fixed size. -pub const MDB_DUPFIXED: c_uint = 0x10; -/// with `MDB_DUPSORT`, dups are numeric in native byte order. -pub const MDB_INTEGERDUP: c_uint = 0x20; -/// with #MDB_DUPSORT, use reverse string dups. -pub const MDB_REVERSEDUP: c_uint = 0x40; -/// create DB if not already existing. -pub const MDB_CREATE: c_uint = 0x40000; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//// Write Flags -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/// For put: Don't write if the key already exists. -pub const MDB_NOOVERWRITE: c_uint = 0x10; -/// Only for `MDB_DUPSORT`. -/// -/// For put: don't write if the key and data pair already exist. -/// For `mdb_cursor_del`: remove all duplicate data items. -pub const MDB_NODUPDATA: c_uint = 0x20; -/// For `mdb_cursor_put`: overwrite the current key/data pair. -pub const MDB_CURRENT: c_uint = 0x40; -/// For put: Just reserve space for data, don't copy it. Return a pointer to the reserved space. -pub const MDB_RESERVE: c_uint = 0x10000; -/// Data is being appended, don't split full pages. -pub const MDB_APPEND: c_uint = 0x20000; -/// Duplicate data is being appended, don't split full pages. -pub const MDB_APPENDDUP: c_uint = 0x40000; -/// Store multiple data items in one call. Only for #MDB_DUPFIXED. -pub const MDB_MULTIPLE: c_uint = 0x80000; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//// Copy Flags -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/// Compacting copy: Omit free space from copy, and renumber all pages sequentially. -pub const MDB_CP_COMPACT: c_uint = 0x01; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//// Return Codes -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/// Successful result. -pub const MDB_SUCCESS: c_int = 0; -/// key/data pair already exists. -pub const MDB_KEYEXIST: c_int = -30799; -/// key/data pair not found (EOF). -pub const MDB_NOTFOUND: c_int = -30798; -/// Requested page not found - this usually indicates corruption. -pub const MDB_PAGE_NOTFOUND: c_int = -30797; -/// Located page was wrong type. -pub const MDB_CORRUPTED: c_int = -30796; -/// Update of meta page failed or environment had fatal error. -pub const MDB_PANIC: c_int = -30795; -/// Environment version mismatch. -pub const MDB_VERSION_MISMATCH: c_int = -30794; -/// File is not a valid LMDB file. -pub const MDB_INVALID: c_int = -30793; -/// Environment mapsize reached. -pub const MDB_MAP_FULL: c_int = -30792; -/// Environment maxdbs reached. -pub const MDB_DBS_FULL: c_int = -30791; -/// Environment maxreaders reached. -pub const MDB_READERS_FULL: c_int = -30790; -/// Too many TLS keys in use - Windows only. -pub const MDB_TLS_FULL: c_int = -30789; -/// Txn has too many dirty pages. -pub const MDB_TXN_FULL: c_int = -30788; -/// Cursor stack too deep - internal error. -pub const MDB_CURSOR_FULL: c_int = -30787; -/// Page has not enough space - internal error. -pub const MDB_PAGE_FULL: c_int = -30786; -/// Database contents grew beyond environment mapsize. -pub const MDB_MAP_RESIZED: c_int = -30785; -/// MDB_INCOMPATIBLE: Operation and DB incompatible, or DB flags changed. -pub const MDB_INCOMPATIBLE: c_int = -30784; -/// Invalid reuse of reader locktable slot. -pub const MDB_BAD_RSLOT: c_int = -30783; -/// Transaction cannot recover - it must be aborted. -pub const MDB_BAD_TXN: c_int = -30782; -/// Unsupported size of key/DB name/data, or wrong DUPFIXED size. -pub const MDB_BAD_VALSIZE: c_int = -30781; -/// The specified DBI was changed unexpectedly. -pub const MDB_BAD_DBI: c_int = -30780; -/// The last defined error code. -pub const MDB_LAST_ERRCODE: c_int = MDB_BAD_DBI; diff --git a/lmdb-sys/src/ffi.rs b/lmdb-sys/src/ffi.rs deleted file mode 100644 index a998ea2..0000000 --- a/lmdb-sys/src/ffi.rs +++ /dev/null @@ -1,118 +0,0 @@ -/* automatically generated by rust-bindgen and modified by hand */ - -pub enum MDB_env { } -pub enum MDB_txn { } -pub type MDB_dbi = ::libc::c_uint; -pub enum MDB_cursor { } - -#[repr(C)] -pub struct MDB_val { - pub mv_size: ::libc::size_t, - pub mv_data: *mut ::libc::c_void, -} - -pub type MDB_cmp_func = extern "C" fn(a: *const MDB_val, b: *const MDB_val) -> ::libc::c_int; -pub type MDB_rel_func = extern "C" fn (item: *mut MDB_val, oldptr: *mut ::libc::c_void, newptr: *mut ::libc::c_void, relctx: *mut ::libc::c_void) -> (); - -pub const MDB_FIRST: ::libc::c_uint = 0; -pub const MDB_FIRST_DUP: ::libc::c_uint = 1; -pub const MDB_GET_BOTH: ::libc::c_uint = 2; -pub const MDB_GET_BOTH_RANGE: ::libc::c_uint = 3; -pub const MDB_GET_CURRENT: ::libc::c_uint = 4; -pub const MDB_GET_MULTIPLE: ::libc::c_uint = 5; -pub const MDB_LAST: ::libc::c_uint = 6; -pub const MDB_LAST_DUP: ::libc::c_uint = 7; -pub const MDB_NEXT: ::libc::c_uint = 8; -pub const MDB_NEXT_DUP: ::libc::c_uint = 9; -pub const MDB_NEXT_MULTIPLE: ::libc::c_uint = 10; -pub const MDB_NEXT_NODUP: ::libc::c_uint = 11; -pub const MDB_PREV: ::libc::c_uint = 12; -pub const MDB_PREV_DUP: ::libc::c_uint = 13; -pub const MDB_PREV_NODUP: ::libc::c_uint = 14; -pub const MDB_SET: ::libc::c_uint = 15; -pub const MDB_SET_KEY: ::libc::c_uint = 16; -pub const MDB_SET_RANGE: ::libc::c_uint = 17; -pub type MDB_cursor_op = ::libc::c_uint; - -#[repr(C)] -#[derive(Clone, Copy)] -pub struct MDB_stat { - pub ms_psize: ::libc::c_uint, - pub ms_depth: ::libc::c_uint, - pub ms_branch_pages: ::libc::size_t, - pub ms_leaf_pages: ::libc::size_t, - pub ms_overflow_pages: ::libc::size_t, - pub ms_entries: ::libc::size_t, -} - -#[repr(C)] -pub struct MDB_envinfo { - pub me_mapaddr: *mut ::libc::c_void, - pub me_mapsize: ::libc::size_t, - pub me_last_pgno: ::libc::size_t, - pub me_last_txnid: ::libc::size_t, - pub me_maxreaders: ::libc::c_uint, - pub me_numreaders: ::libc::c_uint, -} - -pub type MDB_assert_func = extern "C" fn(env: *mut MDB_env, msg: *const ::libc::c_char) -> (); -pub type MDB_msg_func = extern "C" fn(msg: *const ::libc::c_char, ctx: *mut ::libc::c_void) -> ::libc::c_int; - -extern "C" { - pub fn mdb_version(major: *mut ::libc::c_int, minor: *mut ::libc::c_int, patch: *mut ::libc::c_int) -> *mut ::libc::c_char; - pub fn mdb_strerror(err: ::libc::c_int) -> *mut ::libc::c_char; - pub fn mdb_env_create(env: *mut *mut MDB_env) -> ::libc::c_int; - pub fn mdb_env_open(env: *mut MDB_env, path: *const ::libc::c_char, flags: ::libc::c_uint, mode: super::mode_t) -> ::libc::c_int; - pub fn mdb_env_copy(env: *mut MDB_env, path: *const ::libc::c_char) -> ::libc::c_int; - pub fn mdb_env_copyfd(env: *mut MDB_env, fd: ::libc::c_int) -> ::libc::c_int; - pub fn mdb_env_copy2(env: *mut MDB_env, path: *const ::libc::c_char, flags: ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_env_copyfd2(env: *mut MDB_env, fd: ::libc::c_int, flags: ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_env_stat(env: *mut MDB_env, stat: *mut MDB_stat) -> ::libc::c_int; - pub fn mdb_env_info(env: *mut MDB_env, stat: *mut MDB_envinfo) -> ::libc::c_int; - pub fn mdb_env_sync(env: *mut MDB_env, force: ::libc::c_int) -> ::libc::c_int; - pub fn mdb_env_close(env: *mut MDB_env) -> (); - pub fn mdb_env_set_flags(env: *mut MDB_env, flags: ::libc::c_uint, onoff: ::libc::c_int) -> ::libc::c_int; - pub fn mdb_env_get_flags(env: *mut MDB_env, flags: *mut ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_env_get_path(env: *mut MDB_env, path: *mut *const ::libc::c_char) -> ::libc::c_int; - pub fn mdb_env_get_fd(env: *mut MDB_env, fd: *mut ::libc::c_int) -> ::libc::c_int; - pub fn mdb_env_set_mapsize(env: *mut MDB_env, size: ::libc::size_t) -> ::libc::c_int; - pub fn mdb_env_set_maxreaders(env: *mut MDB_env, readers: ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_env_get_maxreaders(env: *mut MDB_env, readers: *mut ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_env_set_maxdbs(env: *mut MDB_env, dbs: MDB_dbi) -> ::libc::c_int; - pub fn mdb_env_get_maxkeysize(env: *mut MDB_env) -> ::libc::c_int; - pub fn mdb_env_set_userctx(env: *mut MDB_env, ctx: *mut ::libc::c_void) -> ::libc::c_int; - pub fn mdb_env_get_userctx(env: *mut MDB_env) -> *mut ::libc::c_void; - pub fn mdb_env_set_assert(env: *mut MDB_env, func: *mut ::std::option::Option ()>) -> ::libc::c_int; - pub fn mdb_txn_begin(env: *mut MDB_env, parent: *mut MDB_txn, flags: ::libc::c_uint, txn: *mut *mut MDB_txn) -> ::libc::c_int; - pub fn mdb_txn_env(txn: *mut MDB_txn) -> *mut MDB_env; - pub fn mdb_txn_id(txn: *mut MDB_txn) -> ::libc::size_t; - pub fn mdb_txn_commit(txn: *mut MDB_txn) -> ::libc::c_int; - pub fn mdb_txn_abort(txn: *mut MDB_txn) -> (); - pub fn mdb_txn_reset(txn: *mut MDB_txn) -> (); - pub fn mdb_txn_renew(txn: *mut MDB_txn) -> ::libc::c_int; - pub fn mdb_dbi_open(txn: *mut MDB_txn, name: *const ::libc::c_char, flags: ::libc::c_uint, dbi: *mut MDB_dbi) -> ::libc::c_int; - pub fn mdb_stat(txn: *mut MDB_txn, dbi: MDB_dbi, stat: *mut MDB_stat) -> ::libc::c_int; - pub fn mdb_dbi_flags(txn: *mut MDB_txn, dbi: MDB_dbi, flags: *mut ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_dbi_close(env: *mut MDB_env, dbi: MDB_dbi) -> (); - pub fn mdb_drop(txn: *mut MDB_txn, dbi: MDB_dbi, del: ::libc::c_int) -> ::libc::c_int; - pub fn mdb_set_compare(txn: *mut MDB_txn, dbi: MDB_dbi, cmp: *mut MDB_cmp_func) -> ::libc::c_int; - pub fn mdb_set_dupsort(txn: *mut MDB_txn, dbi: MDB_dbi, cmp: *mut MDB_cmp_func) -> ::libc::c_int; - pub fn mdb_set_relfunc(txn: *mut MDB_txn, dbi: MDB_dbi, rel: *mut MDB_rel_func) -> ::libc::c_int; - pub fn mdb_set_relctx(txn: *mut MDB_txn, dbi: MDB_dbi, ctx: *mut ::libc::c_void) -> ::libc::c_int; - pub fn mdb_get(txn: *mut MDB_txn, dbi: MDB_dbi, key: *mut MDB_val, data: *mut MDB_val) -> ::libc::c_int; - pub fn mdb_put(txn: *mut MDB_txn, dbi: MDB_dbi, key: *mut MDB_val, data: *mut MDB_val, flags: ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_del(txn: *mut MDB_txn, dbi: MDB_dbi, key: *mut MDB_val, data: *mut MDB_val) -> ::libc::c_int; - pub fn mdb_cursor_open(txn: *mut MDB_txn, dbi: MDB_dbi, cursor: *mut *mut MDB_cursor) -> ::libc::c_int; - pub fn mdb_cursor_close(cursor: *mut MDB_cursor) -> (); - pub fn mdb_cursor_renew(txn: *mut MDB_txn, cursor: *mut MDB_cursor) -> ::libc::c_int; - pub fn mdb_cursor_txn(cursor: *mut MDB_cursor) -> *mut MDB_txn; - pub fn mdb_cursor_dbi(cursor: *mut MDB_cursor) -> MDB_dbi; - pub fn mdb_cursor_get(cursor: *mut MDB_cursor, key: *mut MDB_val, data: *mut MDB_val, op: MDB_cursor_op) -> ::libc::c_int; - pub fn mdb_cursor_put(cursor: *mut MDB_cursor, key: *mut MDB_val, data: *mut MDB_val, flags: ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_cursor_del(cursor: *mut MDB_cursor, flags: ::libc::c_uint) -> ::libc::c_int; - pub fn mdb_cursor_count(cursor: *mut MDB_cursor, countp: *mut ::libc::size_t) -> ::libc::c_int; - pub fn mdb_cmp(txn: *mut MDB_txn, dbi: MDB_dbi, a: *const MDB_val, b: *const MDB_val) -> ::libc::c_int; - pub fn mdb_dcmp(txn: *mut MDB_txn, dbi: MDB_dbi, a: *const MDB_val, b: *const MDB_val) -> ::libc::c_int; - pub fn mdb_reader_list(env: *mut MDB_env, func: *mut MDB_msg_func, ctx: *mut ::libc::c_void) -> ::libc::c_int; - pub fn mdb_reader_check(env: *mut MDB_env, dead: *mut ::libc::c_int) -> ::libc::c_int; -} diff --git a/lmdb-sys/src/lib.rs b/lmdb-sys/src/lib.rs index aa2252a..8935a81 100644 --- a/lmdb-sys/src/lib.rs +++ b/lmdb-sys/src/lib.rs @@ -11,8 +11,4 @@ pub type mode_t = ::libc::mode_t; #[allow(non_camel_case_types)] pub type mode_t = ::libc::c_int; -pub use constants::*; -pub use ffi::*; - -mod ffi; -mod constants; +include!(concat!(env!("OUT_DIR"), "/bindings.rs"));