From 545f8b98b8f614869e5e836c5a05091dfd5472c6 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Sun, 5 Dec 2021 16:08:59 -0800 Subject: [PATCH] binding_rust: generate bindings during build Bindgen output is platform- and architecture-dependent. Pre-generated bindings may cause issues on the machines different from the one used for generating the code. The recommended way[1] to use bindgen is to invoke it from `build.rs`. [1]: https://rust-lang.github.io/rust-bindgen/library-usage.html --- Cargo.lock | 155 +++++++++++++++++++++++++++++++++++++- lib/Cargo.toml | 1 + lib/binding_rust/build.rs | 24 ++++++ lib/binding_rust/ffi.rs | 2 +- lib/binding_rust/lib.rs | 5 +- 5 files changed, 183 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ed173fdf7..3ab8f52b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,5 +31,7 @@ [dependencies.regex] version = "1" +[build-dependencies.bindgen] +version = "0.59.1" [build-dependencies.cc] version = "^1.0.58" diff --git a/binding_rust/build.rs b/binding_rust/build.rs index 5798cde3..34736b53 100644 --- a/binding_rust/build.rs +++ b/binding_rust/build.rs @@ -1,6 +1,28 @@ use std::path::{Path, PathBuf}; use std::{env, fs}; +fn generate_bindings() { + const HEADER_FILE: &'static str = "include/tree_sitter/api.h"; + + println!("cargo:rerun-if-changed={}", HEADER_FILE); + let bindings = bindgen::Builder::default() + .header(HEADER_FILE) + .layout_tests(false) + .allowlist_type("^TS.*") + .allowlist_function("^ts_.*") + .allowlist_var("^TREE_SITTER.*") + .blocklist_function("ts_tree_print_dot_graph") + .opaque_type("FILE") + .size_t_is_usize(true) + .generate() + .expect("Unable to generate bindings"); + + let output = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(output.join("bindings.rs")) + .expect("Unable to write bindings"); +} + fn main() { println!("cargo:rerun-if-env-changed=TREE_SITTER_STATIC_ANALYSIS"); if env::var("TREE_SITTER_STATIC_ANALYSIS").is_ok() { @@ -17,6 +39,8 @@ fn main() { } } + generate_bindings(); + let src_path = Path::new("src"); for entry in fs::read_dir(&src_path).unwrap() { let entry = entry.unwrap(); diff --git a/binding_rust/ffi.rs b/binding_rust/ffi.rs index 685ed765..5cf93180 100644 --- a/binding_rust/ffi.rs +++ b/binding_rust/ffi.rs @@ -2,7 +2,7 @@ #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] -include!("./bindings.rs"); +include!(concat!(env!("OUT_DIR"),"/bindings.rs")); extern "C" { pub(crate) fn dup(fd: std::os::raw::c_int) -> std::os::raw::c_int; diff --git a/binding_rust/lib.rs b/binding_rust/lib.rs index cf8437b8..35205cee 100644 --- a/binding_rust/lib.rs +++ b/binding_rust/lib.rs @@ -25,11 +25,12 @@ use std::{ /// assigned an ABI version number that corresponds to the current CLI version. /// The Tree-sitter library is generally backwards-compatible with languages /// generated using older CLI versions, but is not forwards-compatible. -pub const LANGUAGE_VERSION: usize = ffi::TREE_SITTER_LANGUAGE_VERSION; +pub const LANGUAGE_VERSION: usize = ffi::TREE_SITTER_LANGUAGE_VERSION as usize; /// The earliest ABI version that is supported by the current version of the /// library. -pub const MIN_COMPATIBLE_LANGUAGE_VERSION: usize = ffi::TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION; +pub const MIN_COMPATIBLE_LANGUAGE_VERSION: usize = + ffi::TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION as usize; pub const PARSER_HEADER: &'static str = include_str!("../include/tree_sitter/parser.h"); -- 2.33.1