[vlc-commits] [Git][videolan/vlc][master] 3 commits: .gitignore: add Rust related ignores

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu Aug 3 09:44:24 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
5c644791 by Loïc Branstett at 2023-08-03T09:15:27+00:00
.gitignore: add Rust related ignores

Cargo.lock: file that contains all (including transitive) the
dependencies. We only want to include one of it and it's yet available.

target*/: Cargo builds by default into the target/ dir, so avoid having
it in the git diff

!build.rs: Cargo has build scripts, that by default are named build.rs

- - - - -
f0f67ecc by Loïc Branstett at 2023-08-03T09:15:27+00:00
rust: add Cargo workspace for abstractions

> A workspace is a collection of one or more packages
https://doc.rust-lang.org/cargo/reference/workspaces.html#workspaces

Rust abstractions of VLC Core will live in src/rust/, while the Rust
modules will live in the respective directories in modules/.

- - - - -
bd1aaaf4 by Loïc Branstett at 2023-08-03T09:15:27+00:00
rust: add binary helper crate for generating raw bindings

This binary crate, called vlcrs-sys-generator, uses the bindgen[1] crate
to automatically generate raw (extern "C"...) bindings, which are then
used by safe abstractions.

The goal is for this program to be used to generate raw bindings that
are which will be used by safe abstractions, each safely wrapping a part
of the VLC core API, generally a header will be a crate. This is done so
that the so that the dependency chain of the Rust modules closely
follows that of the C modules, in particular a demux module should not
need to be rebuild if it doesn't depend on vout.

Since writing and maintaining raw bindings is tedious and error-prone,
the raw bindings (extern "C"...) are generated using a Clang front-end,
bindgen, written in Rust. Updating the bindings should be as simple as
running `cargo run -p vlcrs-sys-generator'.

[1]: https://rust-lang.github.io/rust-bindgen/

- - - - -


4 changed files:

- .gitignore
- + src/rust/Cargo.toml
- + src/rust/vlcrs-sys-generator/Cargo.toml
- + src/rust/vlcrs-sys-generator/src/main.rs


Changes:

=====================================
.gitignore
=====================================
@@ -20,6 +20,7 @@
 .dirstamp
 ABOUT-NLS
 aclocal.m4
+Cargo.lock
 ChangeLog
 compile
 config.status
@@ -50,6 +51,8 @@ patches/*
 
 # Ignore build dirs
 build*/
+target*/
 contrib-*
 install-*
+!build.rs
 !extras/package/apple/build.sh


=====================================
src/rust/Cargo.toml
=====================================
@@ -0,0 +1,4 @@
+[workspace]
+members = [
+    "vlcrs-sys-generator"
+]


=====================================
src/rust/vlcrs-sys-generator/Cargo.toml
=====================================
@@ -0,0 +1,8 @@
+[package]
+name = "vlcrs-sys-generator"
+version = "0.0.0"
+edition = "2021"
+license = "LGPL-2.1-or-later"
+
+[dependencies]
+bindgen = "0.66.1"


=====================================
src/rust/vlcrs-sys-generator/src/main.rs
=====================================
@@ -0,0 +1,88 @@
+//! Helper crate around bindgen for use in VLC
+
+use std::{env, fmt::Write, path::PathBuf};
+
+struct BindingsGenerator {
+    include_path: String,
+}
+
+impl BindingsGenerator {
+    /// Generate the raw bindings for a given list of headers.
+    ///
+    /// # Example
+    ///
+    /// ```rust,no_run
+    /// # let bindings_gen = BindingsGenerator { include_path: ".".to_string() };
+    /// bindings_gen.generate_bindings_for("vlcrs-tick", &["vlc_tick.h"], |builder| {
+    ///     builder
+    ///         .allowlist_function("date_.*")
+    ///         .allowlist_function("vlc_tick_.*")
+    ///         .allowlist_type("date_.*")
+    ///         .allowlist_type("vlc_tick_.*")
+    /// });
+    /// ```
+    fn generate_bindings_for(
+        &self,
+        for_: &str,
+        headers: &[&str],
+        builder: impl FnOnce(bindgen::Builder) -> bindgen::Builder,
+    ) {
+        println!("Generating bindings for {for_}...");
+
+        let mut out_path = PathBuf::from(for_);
+        out_path.push("src");
+        out_path.push("sys.rs");
+
+        // We need to generate the header file at runtime that will be passed to
+        // bindgen to generate the requested bindings.
+        //
+        // We always include vlc_common.h since it's always required. for VLC include.
+        let header_contents = ["vlc_common.h"].iter().chain(headers).fold(
+            String::with_capacity(255),
+            |mut contents, header| {
+                writeln!(contents, "#include <{header}>").unwrap();
+                contents
+            },
+        );
+
+        let bindings = bindgen::Builder::default()
+            // Since we're not integrated into the build system, because
+            // bindgen depends on libclang, we need to pass the include path
+            // manually.
+            .clang_arg("-I")
+            .clang_arg(&self.include_path)
+            // The generated bindings won't respect the recommended Rust
+            // code style, as they use C-style naming and descriptions, and
+            // will therefore trigger warnings. We need to disable them for
+            // these generated files.
+            .raw_line("#![allow(rustdoc::bare_urls)]")
+            .raw_line("#![allow(rustdoc::broken_intra_doc_links)]")
+            .raw_line("#![allow(non_upper_case_globals)]")
+            .raw_line("#![allow(non_camel_case_types)]")
+            .raw_line("#![allow(non_snake_case)]")
+            // Since we are generating the input header content at runtime,
+            // specify wrapper.h as a fake name.
+            .header_contents("wrapper.h", &header_contents);
+
+        // Apply "user" configurations, ie allowlist_function, allowlist_type, ...
+        // So that they can pit-point what they want.
+        let bindings = builder(bindings);
+
+        bindings
+            .generate()
+            .unwrap_or_else(|err| panic!("unable to generate the bindings for {for_}: {err:?}"))
+            .write_to_file(&out_path)
+            .unwrap_or_else(|err| {
+                panic!(
+                    "unable to write the generated the bindings for {for_} to {out_path:?}: {err:?}"
+                )
+            })
+    }
+}
+
+fn main() {
+    #[allow(unused)]
+    let bindings_gen = BindingsGenerator {
+        include_path: env::var("INCLUDE_PATH").unwrap_or_else(|_| "../../include".to_string()),
+    };
+}



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/67481c9ceebb2c7da03b5aec20a736ec58146f3d...bd1aaaf4ed5dc89761b0b65b24a31316341c830c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/67481c9ceebb2c7da03b5aec20a736ec58146f3d...bd1aaaf4ed5dc89761b0b65b24a31316341c830c
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list