Skip to contentSkip to conversation

libgpiod: Add Rust bindings

PATCH Superseded Viresh Kumar 1 participant 5 messages Dec 20, 2021 GPIO

v3 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v3 cover libgpiod: Add Rust bindings

Here is another version of rust bindings for libgpiod v2.0, based of the next/libgpiod-2.0.

I will be adding testing infrastructure later on, once other bindings are converted to use gpiosim.

All the examples, including gpiomon, are tested now and work just fine.

V2->V3:
- Remove naming redundancy, users just need to do this now
use libgpiod:{Chip, Direction, LineConfig} now (Bartosz);
- Fix lifetime issues between event-buffer and edge-event modules, the event buffer is released after the last edge-event reference is dropped (Bartosz).
- Allow edge-event to be copied, and freed later (Bartosz).
- Add two separate rust crates, sys and wrapper (Gerard).
- Null-terminate the strings passed to libgpiod (Wedson).
- Drop unnecessary checks to validate string returned from chip:name/label/path.
- Fix SAFETY comments (Wedson).
- Drop unnecessary clone() instances (Bartosz).

V1->V2:
- Added examples (I tested everything except gpiomon.rs, didn't have right hardware/mock device to test).
- Build rust bindings as part of Make, update documentation.

Thanks.

--
Viresh

Viresh Kumar (4):
libgpiod: Add libgpiod-sys rust crate
libgpiod: Add rust wrapper crate
libgpiod: Add rust examples
libgpiod: Integrate building of rust bindings with make

 .gitignore                            |   5 +
 README                                |   8 +-
 TODO                                  |   8 -
 bindings/Makefile.am                  |   6 +
 bindings/rust/Cargo.toml              |  11 +
 bindings/rust/Makefile.am             |  27 ++
 bindings/rust/examples/gpiodetect.rs  |  37 +++
 bindings/rust/examples/gpiofind.rs    |  42 +++
 bindings/rust/examples/gpioget.rs     |  42 +++
 bindings/rust/examples/gpioinfo.rs    |  89 ++++++
 bindings/rust/examples/gpiomon.rs     |  68 +++++
 bindings/rust/examples/gpioset.rs     |  52 ++++
 bindings/rust/libgpiod-sys/Cargo.toml |  12 +
 bindings/rust/libgpiod-sys/build.rs   |  60 ++++
 bindings/rust/libgpiod-sys/src/lib.rs |  16 ++
 bindings/rust/libgpiod-sys/wrapper.h  |   2 +
 bindings/rust/src/chip.rs             | 183 ++++++++++++
 bindings/rust/src/edge_event.rs       | 103 +++++++
 bindings/rust/src/event_buffer.rs     |  87 ++++++
 bindings/rust/src/info_event.rs       |  68 +++++
 bindings/rust/src/lib.rs              | 280 ++++++++++++++++++
 bindings/rust/src/line_config.rs      | 391 ++++++++++++++++++++++++++
 bindings/rust/src/line_info.rs        | 182 ++++++++++++
 bindings/rust/src/line_request.rs     | 214 ++++++++++++++
 bindings/rust/src/request_config.rs   | 119 ++++++++
 configure.ac                          |  16 ++
 26 files changed, 2117 insertions(+), 11 deletions(-)
 create mode 100644 bindings/rust/Cargo.toml
 create mode 100644 bindings/rust/Makefile.am
 create mode 100644 bindings/rust/examples/gpiodetect.rs
 create mode 100644 bindings/rust/examples/gpiofind.rs
 create mode 100644 bindings/rust/examples/gpioget.rs
 create mode 100644 bindings/rust/examples/gpioinfo.rs
 create mode 100644 bindings/rust/examples/gpiomon.rs
 create mode 100644 bindings/rust/examples/gpioset.rs
 create mode 100644 bindings/rust/libgpiod-sys/Cargo.toml
 create mode 100644 bindings/rust/libgpiod-sys/build.rs
 create mode 100644 bindings/rust/libgpiod-sys/src/lib.rs
 create mode 100644 bindings/rust/libgpiod-sys/wrapper.h
 create mode 100644 bindings/rust/src/chip.rs
 create mode 100644 bindings/rust/src/edge_event.rs
 create mode 100644 bindings/rust/src/event_buffer.rs
 create mode 100644 bindings/rust/src/info_event.rs
 create mode 100644 bindings/rust/src/lib.rs
 create mode 100644 bindings/rust/src/line_config.rs
 create mode 100644 bindings/rust/src/line_info.rs
 create mode 100644 bindings/rust/src/line_request.rs
 create mode 100644 bindings/rust/src/request_config.rs
Signature · 1 line
2.31.1.272.g89b43f80a514
#1 lore raw

PATCH v3 1/4 libgpiod: Add libgpiod-sys rust crate

This adds libgpiod-sys rust crate, which provides FFI (foreign function interface) bindings for libgpiod APIs.

---
 .gitignore                            |  5 +++
 bindings/rust/libgpiod-sys/Cargo.toml | 12 ++++++
 bindings/rust/libgpiod-sys/build.rs   | 60 +++++++++++++++++++++++++++
 bindings/rust/libgpiod-sys/src/lib.rs | 16 +++++++
 bindings/rust/libgpiod-sys/wrapper.h  |  2 +
 5 files changed, 95 insertions(+)
 create mode 100644 bindings/rust/libgpiod-sys/Cargo.toml
 create mode 100644 bindings/rust/libgpiod-sys/build.rs
 create mode 100644 bindings/rust/libgpiod-sys/src/lib.rs
 create mode 100644 bindings/rust/libgpiod-sys/wrapper.h
.gitignore +5 -0
index 2d7cc7fc0758..3a80a65c087e 100644
@@ -29,3 +29,8 @@ libtool
 *-libtool
 m4/
 stamp-h1
+
+# Added by cargo
+
+target
+Cargo.lock
bindings/rust/libgpiod-sys/Cargo.toml new file +12 -0
new file mode 100644
index 000000000000..a9c7b01365b2
@@ -0,0 +1,12 @@
+[package]
+name = "libgpiod-sys"
+version = "0.1.0"
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+
+[build-dependencies]
+bindgen = "0.59.1"
+cc = "1.0.46"
bindings/rust/libgpiod-sys/build.rs new file +60 -0

60 lines not on this page · raw message

bindings/rust/libgpiod-sys/src/lib.rs new file +16 -0
new file mode 100644
index 000000000000..7d6caa7d9c11
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#[allow(
+    clippy::all,
+    deref_nullptr,
+    dead_code,
+    non_camel_case_types,
+    non_upper_case_globals,
+    non_snake_case,
+    improper_ctypes
+)]
+
+mod bindings_raw {
+    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+}
+pub use bindings_raw::*;
bindings/rust/libgpiod-sys/wrapper.h new file +2 -0
new file mode 100644
index 000000000000..7bc1158b7d90
@@ -0,0 +1,2 @@
+#include <string.h>
+#include "../../../include/gpiod.h"
Signature · 1 line
2.31.1.272.g89b43f80a514
#2 lore raw

PATCH v3 2/4 libgpiod: Add rust wrapper crate

In reply to Viresh Kumar

Add rust wrapper crate, around the libpiod-sys crate added earlier, to provide a convenient interface for the users.

---
 bindings/rust/Cargo.toml            |  11 +
 bindings/rust/src/chip.rs           | 183 +++++++++++++
 bindings/rust/src/edge_event.rs     | 103 ++++++++
 bindings/rust/src/event_buffer.rs   |  87 +++++++
 bindings/rust/src/info_event.rs     |  68 +++++
 bindings/rust/src/lib.rs            | 280 ++++++++++++++++++++
 bindings/rust/src/line_config.rs    | 391 ++++++++++++++++++++++++++++
 bindings/rust/src/line_info.rs      | 182 +++++++++++++
 bindings/rust/src/line_request.rs   | 214 +++++++++++++++
 bindings/rust/src/request_config.rs | 119 +++++++++
 10 files changed, 1638 insertions(+)
 create mode 100644 bindings/rust/Cargo.toml
 create mode 100644 bindings/rust/src/chip.rs
 create mode 100644 bindings/rust/src/edge_event.rs
 create mode 100644 bindings/rust/src/event_buffer.rs
 create mode 100644 bindings/rust/src/info_event.rs
 create mode 100644 bindings/rust/src/lib.rs
 create mode 100644 bindings/rust/src/line_config.rs
 create mode 100644 bindings/rust/src/line_info.rs
 create mode 100644 bindings/rust/src/line_request.rs
 create mode 100644 bindings/rust/src/request_config.rs
bindings/rust/Cargo.toml new file +11 -0
new file mode 100644
index 000000000000..948037258b82
@@ -0,0 +1,11 @@
+[package]
+name = "libgpiod"
+version = "0.1.0"
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+libgpiod-sys = { path = "libgpiod-sys" }
+thiserror = "1.0"
+vmm-sys-util = "=0.9.0"
bindings/rust/src/chip.rs new file +183 -0

183 lines not on this page · raw message

bindings/rust/src/edge_event.rs new file +103 -0

103 lines not on this page · raw message

bindings/rust/src/event_buffer.rs new file +87 -0

87 lines not on this page · raw message

bindings/rust/src/info_event.rs new file +68 -0

68 lines not on this page · raw message

bindings/rust/src/lib.rs new file +280 -0

280 lines not on this page · raw message

bindings/rust/src/line_config.rs new file +391 -0

391 lines not on this page · raw message

bindings/rust/src/line_info.rs new file +182 -0

182 lines not on this page · raw message

bindings/rust/src/line_request.rs new file +214 -0

214 lines not on this page · raw message

bindings/rust/src/request_config.rs new file +119 -0

119 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#3 lore raw

PATCH v3 3/4 libgpiod: Add rust examples

In reply to Viresh Kumar

Add examples for the usage of the rust bindings, quite similar to the ones in cxx bindings.

---
 bindings/rust/examples/gpiodetect.rs | 37 ++++++++++++
 bindings/rust/examples/gpiofind.rs   | 42 +++++++++++++
 bindings/rust/examples/gpioget.rs    | 42 +++++++++++++
 bindings/rust/examples/gpioinfo.rs   | 89 ++++++++++++++++++++++++++++
 bindings/rust/examples/gpiomon.rs    | 68 +++++++++++++++++++++
 bindings/rust/examples/gpioset.rs    | 52 ++++++++++++++++
 6 files changed, 330 insertions(+)
 create mode 100644 bindings/rust/examples/gpiodetect.rs
 create mode 100644 bindings/rust/examples/gpiofind.rs
 create mode 100644 bindings/rust/examples/gpioget.rs
 create mode 100644 bindings/rust/examples/gpioinfo.rs
 create mode 100644 bindings/rust/examples/gpiomon.rs
 create mode 100644 bindings/rust/examples/gpioset.rs
bindings/rust/examples/gpiodetect.rs new file +37 -0
new file mode 100644
index 000000000000..505ad1e3420d
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
+//
+// Copyright 2021 Linaro Ltd. All Rights Reserved.
+//     Viresh Kumar <[email protected]>
+//
+// Simplified Rust implementation of gpiodetect tool.
+
+use std::env;
+use std::fs;
+use std::path::Path;
+
+use libgpiod::{gpiod_is_gpiochip_device, Chip};
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 {
+        println!("Usage: {}", args[0]);
+        return;
+    }
+
+    for entry in fs::read_dir(Path::new("/dev")).unwrap() {
+        let pathbuf = entry.unwrap().path();
+        let path = pathbuf.to_str().unwrap();
+
+        if gpiod_is_gpiochip_device(path) {
+            let chip = Chip::open(path).unwrap();
+            let ngpio = chip.get_num_lines();
+
+            println!(
+                "{} [{}] ({})",
+                chip.get_name().unwrap(),
+                chip.get_label().unwrap(),
+                ngpio
+            );
+        }
+    }
+}
bindings/rust/examples/gpiofind.rs new file +42 -0

42 lines not on this page · raw message

bindings/rust/examples/gpioget.rs new file +42 -0

42 lines not on this page · raw message

bindings/rust/examples/gpioinfo.rs new file +89 -0

89 lines not on this page · raw message

bindings/rust/examples/gpiomon.rs new file +68 -0

68 lines not on this page · raw message

bindings/rust/examples/gpioset.rs new file +52 -0

52 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#4 lore raw

PATCH v3 4/4 libgpiod: Integrate building of rust bindings with make

In reply to Viresh Kumar

Let make build rust bindings as well.

---
 README                    |  8 +++++---
 TODO                      |  8 --------
 bindings/Makefile.am      |  6 ++++++
 bindings/rust/Makefile.am | 27 +++++++++++++++++++++++++++
 configure.ac              | 16 ++++++++++++++++
 5 files changed, 54 insertions(+), 11 deletions(-)
 create mode 100644 bindings/rust/Makefile.am
README +5 -3
index 814a0f161fd2..68b5d69f9b66 100644
@@ -119,9 +119,9 @@ TOOLS
 BINDINGS
 --------
 
-High-level, object-oriented bindings for C++ and python3 are provided. They
-can be enabled by passing --enable-bindings-cxx and --enable-bindings-python
-arguments respectively to configure.
+High-level, object-oriented bindings for C++, python3 and Rust are provided.
+They can be enabled by passing --enable-bindings-cxx, --enable-bindings-python
+and --enable-bindings-rust arguments respectively to configure.
 
 C++ bindings require C++11 support and autoconf-archive collection if building
 from git.
@@ -132,6 +132,8 @@ the PYTHON_CPPFLAGS and PYTHON_LIBS variables in order to point the build
 system to the correct locations. During native builds, the configure script
 can auto-detect the location of the development files.
 
+Rust bindings require cargo support.
+
 TESTING
 -------
 
TODO +0 -8
index 8bb4d8f3ad56..cf4fd7b4a962 100644
@@ -28,14 +28,6 @@ and is partially functional.
 
 ----------
 
-* implement rust bindings
-
-With Rust gaining popularity as a low-level system's language and the
-possibility of it making its way into the linux kernel, it's probably time to
-provide Rust bindings to libgpiod as part of the project.
-
-----------
-
 * implement a simple daemon for controlling GPIOs in C together with a client
   program
 
bindings/Makefile.am +6 -0
index 8f8c762f254f..004ae23dbc58 100644
@@ -14,3 +14,9 @@ if WITH_BINDINGS_PYTHON
 SUBDIRS += python
 
 endif
+
+if WITH_BINDINGS_RUST
+
+SUBDIRS += rust
+
+endif
bindings/rust/Makefile.am new file +27 -0
new file mode 100644
index 000000000000..9799f0036e2f
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2021 Viresh Kumar <[email protected]>
+
+LIBGPIOD_SRC =					\
+	Cargo.toml				\
+	src/chip.rs				\
+	src/edge_event.rs			\
+	src/event_buffer.rs			\
+	src/info_event.rs			\
+	src/lib.rs				\
+	src/line_config.rs			\
+	src/line_info.rs			\
+	src/line_request.rs			\
+	src/request_config.rs			\
+	examples/gpiodetect.rs			\
+	examples/gpiofind.rs			\
+	examples/gpioget.rs			\
+	examples/gpioinfo.rs			\
+	examples/gpiomon.rs			\
+	examples/gpioset.rs
+
+
+all: $(LIBGPIOD_SRC)
+	cargo build --lib --examples
+
+clean:
+	cargo clean
configure.ac +16 -0
index ce6de99c1edd..e83eca2a5e14 100644
@@ -199,6 +199,21 @@ then
 		[AC_SUBST(PYTHON_LIBS, [`$PYTHON-config --libs`])])
 fi
 
+AC_ARG_ENABLE([bindings-rust],
+	[AS_HELP_STRING([--enable-bindings-rust],[enable rust bindings [default=no]])],
+	[if test "x$enableval" = xyes; then with_bindings_rust=true; fi],
+	[with_bindings_rust=false])
+AM_CONDITIONAL([WITH_BINDINGS_RUST], [test "x$with_bindings_rust" = xtrue])
+
+if test "x$with_bindings_rust" = xtrue
+then
+	AC_CHECK_PROG([has_cargo], [cargo], [true], [false])
+	if test "x$has_cargo" = xfalse
+	then
+		AC_MSG_ERROR([cargo not found - needed for rust bindings])
+	fi
+fi
+
 AC_CHECK_PROG([has_doxygen], [doxygen], [true], [false])
 AM_CONDITIONAL([HAS_DOXYGEN], [test "x$has_doxygen" = xtrue])
 if test "x$has_doxygen" = xfalse
@@ -232,6 +247,7 @@ AC_CONFIG_FILES([Makefile
 		 bindings/python/Makefile
 		 bindings/python/examples/Makefile
 		 bindings/python/tests/Makefile
+		 bindings/rust/Makefile
 		 man/Makefile])
 
 AC_OUTPUT
Signature · 1 line
2.31.1.272.g89b43f80a514