Skip to contentSkip to conversation

libgpiod: Add Rust bindings

PATCH Superseded Viresh Kumar 7 participants 49 messages Nov 7, 2022 – Nov 18, 2022 GPIO

v9 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v9 cover libgpiod: Add Rust bindings

Hello,

Here is another version of the rust bindings, based of the master branch.

Pushed here:

https://github.com/vireshk/libgpiod v9

V8->V9:
- Merged the last patch (supporting Events) with the other patches.
- Events implementation is simplified and made efficient. nth() is also implemented for the iterator.
- Unnecessary comment removed from Cargo.toml files.
- Updated categories in libgpiod's Cargo.toml.
- Updated gpio_events example to show cloned events live past another read_edge_events().
- Implement AsRawFd for Chip.
- Other minor changes.

V7->V8:
- Several updates to cargo.toml files, like license, version, etc.
- Removed Sync support for chip and gpiosim.
- Implemented, in a separate patch, iterator support for Events.
- Fixed missing SAFETY comments.
- Fixed build for 32 bit systems.
- Use errno::Errno.
- Removed Clone derive for many structures, that store raw pointers.
- line setting helpers return the object back, so another helper can be called directly on them. Also made all helpers public and used the same in tests and example for single configurations.
- Enums for gpiosim constants.
- New examples to demonstrate parallelism and event handling.
- Separated out HTE tests and marked as #[ignore] now.
- Updated commit subjects.
- Other minor changes.

V6->V7:
- Don't let buffer read new events if the earlier events are still referenced.
- BufferIntenal is gone now, to make the above work.
- Update example and tests too for the same.

V5->V6:
- Updates according to the new line-settings interface.
- New file, line_settings.rs.
- Renamed 'enum Setting' as 'SettingVal' to avoid conflicting names, as we also have 'struct Settings' now.
- Support for HTE clock type.
- Implement 'Eq' for public structure/enums (reported by build).
- Remove 'SettingKindMap' and 'SettingMap' as they aren't required anymore.
- Updated tests based on new interface.

V4->V5:
- Arrange as workspace with crates for libgpiod-sys, libgpiod, gpiosim.
- Use static libgpiod and libgpiosim libraries instead of rebuilding again.
- Arrange in modules instead of flattened approach.
- New enums like Setting and SettingKind and new types based on them SettingMap and SettingKindMap.
- New property independent helpers for line_config, like set_prop_default().
- Improved tests/examples, new example for gpiowatch.
- Add pre-built bindings for gpiosim too.
- Many other changes.

V3->V4:
- Rebased on top of new changes, and made changes accordingly.
- Added rust integration tests with gpiosim.
- Found a kernel bug with tests, sent a patch for that to LKML.

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 (8):
bindings: rust: Add libgpiod-sys rust crate
bindings: rust: Add pre generated bindings for libgpiod-sys
bindings: rust: Add gpiosim crate
bindings: rust: Add pre generated bindings for gpiosim
bindings: rust: Add libgpiod crate
bindings: rust: Add examples to libgpiod crate
bindings: rust: Add tests for libgpiod crate
bindings: rust: Integrate building of bindings with make

 .gitignore                                    |    5 +
 README                                        |    8 +-
 TODO                                          |    8 -
 bindings/Makefile.am                          |    6 +
 bindings/rust/Cargo.toml                      |    7 +
 bindings/rust/Makefile.am                     |   18 +
 bindings/rust/gpiosim/Cargo.toml              |   22 +
 bindings/rust/gpiosim/README.md               |   11 +
 bindings/rust/gpiosim/build.rs                |   43 +
 bindings/rust/gpiosim/src/bindings.rs         |  180 +++
 bindings/rust/gpiosim/src/lib.rs              |   79 ++
 bindings/rust/gpiosim/src/sim.rs              |  331 +++++
 bindings/rust/libgpiod-sys/Cargo.toml         |   20 +
 bindings/rust/libgpiod-sys/README.md          |   11 +
 bindings/rust/libgpiod-sys/build.rs           |   41 +
 bindings/rust/libgpiod-sys/src/bindings.rs    | 1173 +++++++++++++++++
 bindings/rust/libgpiod-sys/src/lib.rs         |   13 +
 bindings/rust/libgpiod/Cargo.toml             |   21 +
 .../rust/libgpiod/examples/gpio_events.rs     |   89 ++
 .../examples/gpio_threaded_info_events.rs     |  133 ++
 bindings/rust/libgpiod/examples/gpiodetect.rs |   31 +
 bindings/rust/libgpiod/examples/gpiofind.rs   |   37 +
 bindings/rust/libgpiod/examples/gpioget.rs    |   46 +
 bindings/rust/libgpiod/examples/gpioinfo.rs   |   98 ++
 bindings/rust/libgpiod/examples/gpiomon.rs    |   75 ++
 bindings/rust/libgpiod/examples/gpioset.rs    |   64 +
 bindings/rust/libgpiod/examples/gpiowatch.rs  |   54 +
 bindings/rust/libgpiod/src/chip.rs            |  310 +++++
 bindings/rust/libgpiod/src/edge_event.rs      |   93 ++
 bindings/rust/libgpiod/src/event_buffer.rs    |  167 +++
 bindings/rust/libgpiod/src/info_event.rs      |   69 +
 bindings/rust/libgpiod/src/lib.rs             |  479 +++++++
 bindings/rust/libgpiod/src/line_config.rs     |  135 ++
 bindings/rust/libgpiod/src/line_info.rs       |  162 +++
 bindings/rust/libgpiod/src/line_request.rs    |  227 ++++
 bindings/rust/libgpiod/src/line_settings.rs   |  297 +++++
 bindings/rust/libgpiod/src/request_config.rs  |   95 ++
 bindings/rust/libgpiod/tests/chip.rs          |   98 ++
 bindings/rust/libgpiod/tests/common/config.rs |  143 ++
 bindings/rust/libgpiod/tests/common/mod.rs    |   10 +
 bindings/rust/libgpiod/tests/edge_event.rs    |  298 +++++
 bindings/rust/libgpiod/tests/info_event.rs    |  167 +++
 bindings/rust/libgpiod/tests/line_config.rs   |   96 ++
 bindings/rust/libgpiod/tests/line_info.rs     |  276 ++++
 bindings/rust/libgpiod/tests/line_request.rs  |  510 +++++++
 bindings/rust/libgpiod/tests/line_settings.rs |  204 +++
 .../rust/libgpiod/tests/request_config.rs     |   39 +
 configure.ac                                  |   16 +
 48 files changed, 6504 insertions(+), 11 deletions(-)
 create mode 100644 bindings/rust/Cargo.toml
 create mode 100644 bindings/rust/Makefile.am
 create mode 100644 bindings/rust/gpiosim/Cargo.toml
 create mode 100644 bindings/rust/gpiosim/README.md
 create mode 100644 bindings/rust/gpiosim/build.rs
 create mode 100644 bindings/rust/gpiosim/src/bindings.rs
 create mode 100644 bindings/rust/gpiosim/src/lib.rs
 create mode 100644 bindings/rust/gpiosim/src/sim.rs
 create mode 100644 bindings/rust/libgpiod-sys/Cargo.toml
 create mode 100644 bindings/rust/libgpiod-sys/README.md
 create mode 100644 bindings/rust/libgpiod-sys/build.rs
 create mode 100644 bindings/rust/libgpiod-sys/src/bindings.rs
 create mode 100644 bindings/rust/libgpiod-sys/src/lib.rs
 create mode 100644 bindings/rust/libgpiod/Cargo.toml
 create mode 100644 bindings/rust/libgpiod/examples/gpio_events.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiodetect.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiofind.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioget.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioinfo.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiomon.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioset.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiowatch.rs
 create mode 100644 bindings/rust/libgpiod/src/chip.rs
 create mode 100644 bindings/rust/libgpiod/src/edge_event.rs
 create mode 100644 bindings/rust/libgpiod/src/event_buffer.rs
 create mode 100644 bindings/rust/libgpiod/src/info_event.rs
 create mode 100644 bindings/rust/libgpiod/src/lib.rs
 create mode 100644 bindings/rust/libgpiod/src/line_config.rs
 create mode 100644 bindings/rust/libgpiod/src/line_info.rs
 create mode 100644 bindings/rust/libgpiod/src/line_request.rs
 create mode 100644 bindings/rust/libgpiod/src/line_settings.rs
 create mode 100644 bindings/rust/libgpiod/src/request_config.rs
 create mode 100644 bindings/rust/libgpiod/tests/chip.rs
 create mode 100644 bindings/rust/libgpiod/tests/common/config.rs
 create mode 100644 bindings/rust/libgpiod/tests/common/mod.rs
 create mode 100644 bindings/rust/libgpiod/tests/edge_event.rs
 create mode 100644 bindings/rust/libgpiod/tests/info_event.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_config.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_info.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_request.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_settings.rs
 create mode 100644 bindings/rust/libgpiod/tests/request_config.rs
Signature · 1 line
2.31.1.272.g89b43f80a514
#1 lore raw

PATCH v9 1/8 bindings: rust: 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/Cargo.toml              |  5 ++++
 bindings/rust/libgpiod-sys/Cargo.toml | 20 +++++++++++++
 bindings/rust/libgpiod-sys/build.rs   | 41 +++++++++++++++++++++++++++
 bindings/rust/libgpiod-sys/src/lib.rs | 13 +++++++++
 5 files changed, 84 insertions(+)
 create mode 100644 bindings/rust/Cargo.toml
 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
.gitignore +5 -0
index 6c08415b390d..9f2fcf440c5d 100644
@@ -35,3 +35,8 @@ stamp-h1
 # profiling
 *.gcda
 *.gcno
+
+# Added by cargo
+
+target
+Cargo.lock
bindings/rust/Cargo.toml new file +5 -0
new file mode 100644
index 000000000000..c7bbcc798920
@@ -0,0 +1,5 @@
+[workspace]
+
+members = [
+    "libgpiod-sys"
+]
bindings/rust/libgpiod-sys/Cargo.toml new file +20 -0
new file mode 100644
index 000000000000..47d0c2a7311c
@@ -0,0 +1,20 @@
+[package]
+name = "libgpiod-sys"
+version = "0.1.0"
+authors = ["Viresh Kumar <[email protected]>"]
+description = "libgpiod public header bindings"
+repository = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git"
+categories = ["external-ffi-bindings", "os::linux-apis"]
+rust-version = "1.56"
+keywords = ["libgpiod", "gpio"]
+license = "Apache-2.0 OR BSD-3-Clause"
+edition = "2021"
+
+[dependencies]
+
+[features]
+generate = [ "bindgen" ]
+
+[build-dependencies]
+bindgen = { version = "0.59.1", optional = true }
+cc = "1.0.46"
bindings/rust/libgpiod-sys/build.rs new file +41 -0

41 lines not on this page · raw message

bindings/rust/libgpiod-sys/src/lib.rs new file +13 -0
new file mode 100644
index 000000000000..a1d1db19afe3
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+
+#[allow(non_camel_case_types, non_upper_case_globals)]
+#[cfg_attr(test, allow(deref_nullptr, non_snake_case))]
+
+mod bindings_raw {
+    #[cfg(feature = "generate")]
+    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
+    #[cfg(not(feature = "generate"))]
+    include!("bindings.rs");
+}
+pub use bindings_raw::*;
Signature · 1 line
2.31.1.272.g89b43f80a514
#2 lore raw

Re: [libgpiod][PATCH V9 1/8] bindings: rust: Add libgpiod-sys rust crate

Quoted 22 lines · Viresh Kumar

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

---
 .gitignore                            |  5 ++++
 bindings/rust/Cargo.toml              |  5 ++++
 bindings/rust/libgpiod-sys/Cargo.toml | 20 +++++++++++++
 bindings/rust/libgpiod-sys/build.rs   | 41 +++++++++++++++++++++++++++
 bindings/rust/libgpiod-sys/src/lib.rs | 13 +++++++++
 5 files changed, 84 insertions(+)
 create mode 100644 bindings/rust/Cargo.toml
 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
.gitignore +0 -0
index 6c08415b390d..9f2fcf440c5d 100644

.gitignore stamp-h1 · line 42

Quoted 8 lines
.gitignore +5 -0
@@ -35,3 +35,8 @@ stamp-h1
 # profiling
 *.gcda
 *.gcno
+
+# Added by cargo
+
+target
+Cargo.lock

This should be put into bindings/rust/.gitignore

Bart

#3 lore raw

Re: [libgpiod][PATCH V9 1/8] bindings: rust: Add libgpiod-sys rust crate

Quoted 18 lines · Bartosz Golaszewski
Quoted 17 lines · Viresh Kumar

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

---
 .gitignore                            |  5 ++++
 bindings/rust/Cargo.toml              |  5 ++++
 bindings/rust/libgpiod-sys/Cargo.toml | 20 +++++++++++++
 bindings/rust/libgpiod-sys/build.rs   | 41 +++++++++++++++++++++++++++
 bindings/rust/libgpiod-sys/src/lib.rs | 13 +++++++++
 5 files changed, 84 insertions(+)
 create mode 100644 bindings/rust/Cargo.toml
 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
Quoted 15 lines

.gitignore stamp-h1 · line 42

Quoted 13 lines
.gitignore +5 -0
index 6c08415b390d..9f2fcf440c5d 100644
@@ -35,3 +35,8 @@ stamp-h1
 # profiling
 *.gcda
 *.gcno
+
+# Added by cargo
+
+target
+Cargo.lock

This should be put into bindings/rust/.gitignore

Should I resend the series with this one change ? Or just an incremental fix is enough ?

Signature · 1 line
viresh
#4 lore raw

Re: [libgpiod][PATCH V9 1/8] bindings: rust: Add libgpiod-sys rust crate

Quoted 36 lines · Viresh Kumar
Quoted 18 lines · Bartosz Golaszewski
Quoted 17 lines · Viresh Kumar

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

---
 .gitignore                            |  5 ++++
 bindings/rust/Cargo.toml              |  5 ++++
 bindings/rust/libgpiod-sys/Cargo.toml | 20 +++++++++++++
 bindings/rust/libgpiod-sys/build.rs   | 41 +++++++++++++++++++++++++++
 bindings/rust/libgpiod-sys/src/lib.rs | 13 +++++++++
 5 files changed, 84 insertions(+)
 create mode 100644 bindings/rust/Cargo.toml
 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
Quoted 15 lines

.gitignore stamp-h1 · line 42

Quoted 13 lines
.gitignore +5 -0
index 6c08415b390d..9f2fcf440c5d 100644
@@ -35,3 +35,8 @@ stamp-h1
 # profiling
 *.gcda
 *.gcno
+
+# Added by cargo
+
+target
+Cargo.lock

This should be put into bindings/rust/.gitignore

Quoted 5 lines

Should I resend the series with this one change ? Or just an incremental fix is enough ?

--
viresh

I'll fix it locally.

Bart

#5 lore raw

PATCH v9 2/8 bindings: rust: Add pre generated bindings for libgpiod-sys

In reply to Viresh Kumar

This adds a copy of pre generated bindings and adds the suggested way of updating those in README.

---
 bindings/rust/libgpiod-sys/README.md       |   11 +
 bindings/rust/libgpiod-sys/src/bindings.rs | 1173 ++++++++++++++++++++
 2 files changed, 1184 insertions(+)
 create mode 100644 bindings/rust/libgpiod-sys/README.md
 create mode 100644 bindings/rust/libgpiod-sys/src/bindings.rs
bindings/rust/libgpiod-sys/README.md new file +11 -0
new file mode 100644
index 000000000000..ecf75b31c41e
@@ -0,0 +1,11 @@
+# Generated libgpiod-sys Rust FFI bindings
+Automatically generated Rust FFI bindings via
+	[bindgen](https://github.com/rust-lang/rust-bindgen).
+
+## Updating bindings
+1. Clone the source from
+	<https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/>
+2. run `cd libgpiod/bindings/rust/libgpiod-sys/`
+2. run `cargo build --features generate`
+3. Copy the bindings 'cp ../target/debug/build/libgpiod-sys-###/out/bindings.rs src/bindings.rs'
+4. Commit changes in `src/bindings.rs`
bindings/rust/libgpiod-sys/src/bindings.rs new file +1173 -0

1,173 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#6 lore raw

PATCH v9 3/8 bindings: rust: Add gpiosim crate

In reply to Viresh Kumar

This adds gpiosim rust crate, which provides helpers to emulate GPIO chips.

---
 bindings/rust/Cargo.toml         |   1 +
 bindings/rust/gpiosim/Cargo.toml |  22 ++
 bindings/rust/gpiosim/build.rs   |  43 ++++
 bindings/rust/gpiosim/src/lib.rs |  79 ++++++++
 bindings/rust/gpiosim/src/sim.rs | 331 +++++++++++++++++++++++++++++++
 5 files changed, 476 insertions(+)
 create mode 100644 bindings/rust/gpiosim/Cargo.toml
 create mode 100644 bindings/rust/gpiosim/build.rs
 create mode 100644 bindings/rust/gpiosim/src/lib.rs
 create mode 100644 bindings/rust/gpiosim/src/sim.rs
bindings/rust/Cargo.toml +1 -0
index c7bbcc798920..b9eea6b3a5ea 100644
@@ -1,5 +1,6 @@
 [workspace]
 
 members = [
+    "gpiosim",
     "libgpiod-sys"
 ]
bindings/rust/gpiosim/Cargo.toml new file +22 -0
new file mode 100644
index 000000000000..f8f7e7f79b77
@@ -0,0 +1,22 @@
+[package]
+name = "gpiosim"
+version = "0.1.0"
+authors = ["Viresh Kumar <[email protected]>"]
+description = "gpiosim header bindings"
+repository = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git"
+categories = ["external-ffi-bindings", "os::linux-apis"]
+rust-version = "1.56"
+keywords = ["libgpiod", "gpio", "gpiosim"]
+license = "Apache-2.0 OR BSD-3-Clause"
+edition = "2021"
+
+[dependencies]
+errno = "0.2.8"
+libgpiod = { path = "../libgpiod" }
+
+[features]
+generate = [ "bindgen" ]
+
+[build-dependencies]
+bindgen = { version = "0.59.1", optional = true }
+cc = "1.0.46"
bindings/rust/gpiosim/build.rs new file +43 -0

43 lines not on this page · raw message

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

79 lines not on this page · raw message

bindings/rust/gpiosim/src/sim.rs new file +331 -0

331 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#7 lore raw

PATCH v9 4/8 bindings: rust: Add pre generated bindings for gpiosim

In reply to Viresh Kumar

This adds a copy of pre generated bindings and adds the suggested way of updating those in README.

---
 bindings/rust/gpiosim/README.md       |  11 ++
 bindings/rust/gpiosim/src/bindings.rs | 180 ++++++++++++++++++++++++++
 2 files changed, 191 insertions(+)
 create mode 100644 bindings/rust/gpiosim/README.md
 create mode 100644 bindings/rust/gpiosim/src/bindings.rs
bindings/rust/gpiosim/README.md new file +11 -0
new file mode 100644
index 000000000000..acb84543dbdc
@@ -0,0 +1,11 @@
+# Generated gpiosim Rust FFI bindings
+Automatically generated Rust FFI bindings via
+	[bindgen](https://github.com/rust-lang/rust-bindgen).
+
+## Updating bindings
+1. Clone the source from
+	<https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/>
+2. run `cd libgpiod/bindings/rust/gpiosim/`
+2. run `cargo build --features generate`
+3. Copy the bindings 'cp ../target/debug/build/gpiosim-###/out/bindings.rs src/bindings.rs'
+4. Commit changes in `src/bindings.rs`
bindings/rust/gpiosim/src/bindings.rs new file +180 -0

180 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#8 lore raw

PATCH v9 5/8 bindings: rust: Add libgpiod 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                     |   1 +
 bindings/rust/libgpiod/Cargo.toml            |  18 +
 bindings/rust/libgpiod/src/chip.rs           | 310 ++++++++++++
 bindings/rust/libgpiod/src/edge_event.rs     |  93 ++++
 bindings/rust/libgpiod/src/event_buffer.rs   | 167 +++++++
 bindings/rust/libgpiod/src/info_event.rs     |  69 +++
 bindings/rust/libgpiod/src/lib.rs            | 479 +++++++++++++++++++
 bindings/rust/libgpiod/src/line_config.rs    | 135 ++++++
 bindings/rust/libgpiod/src/line_info.rs      | 162 +++++++
 bindings/rust/libgpiod/src/line_request.rs   | 227 +++++++++
 bindings/rust/libgpiod/src/line_settings.rs  | 297 ++++++++++++
 bindings/rust/libgpiod/src/request_config.rs |  95 ++++
 12 files changed, 2053 insertions(+)
 create mode 100644 bindings/rust/libgpiod/Cargo.toml
 create mode 100644 bindings/rust/libgpiod/src/chip.rs
 create mode 100644 bindings/rust/libgpiod/src/edge_event.rs
 create mode 100644 bindings/rust/libgpiod/src/event_buffer.rs
 create mode 100644 bindings/rust/libgpiod/src/info_event.rs
 create mode 100644 bindings/rust/libgpiod/src/lib.rs
 create mode 100644 bindings/rust/libgpiod/src/line_config.rs
 create mode 100644 bindings/rust/libgpiod/src/line_info.rs
 create mode 100644 bindings/rust/libgpiod/src/line_request.rs
 create mode 100644 bindings/rust/libgpiod/src/line_settings.rs
 create mode 100644 bindings/rust/libgpiod/src/request_config.rs
bindings/rust/Cargo.toml +1 -0
index b9eea6b3a5ea..4fdf4e06ff90 100644
@@ -2,5 +2,6 @@
 
 members = [
     "gpiosim",
+    "libgpiod",
     "libgpiod-sys"
 ]
bindings/rust/libgpiod/Cargo.toml new file +18 -0
new file mode 100644
index 000000000000..65ca079b5e15
@@ -0,0 +1,18 @@
+[package]
+name = "libgpiod"
+version = "0.1.0"
+authors = ["Viresh Kumar <[email protected]>"]
+description = "libgpiod wrappers"
+repository = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git"
+categories = ["api-bindings", "hardware-support", "embedded", "os::linux-apis"]
+rust-version = "1.56"
+keywords = ["libgpiod", "gpio"]
+license = "Apache-2.0 OR BSD-3-Clause"
+edition = "2021"
+
+[dependencies]
+errno = "0.2.8"
+intmap = "2.0.0"
+libc = "0.2.39"
+libgpiod-sys = { path = "../libgpiod-sys" }
+thiserror = "1.0"
bindings/rust/libgpiod/src/chip.rs new file +310 -0

310 lines not on this page · raw message

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

93 lines not on this page · raw message

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

167 lines not on this page · raw message

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

69 lines not on this page · raw message

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

479 lines not on this page · raw message

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

135 lines not on this page · raw message

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

162 lines not on this page · raw message

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

227 lines not on this page · raw message

bindings/rust/libgpiod/src/line_settings.rs new file +297 -0

297 lines not on this page · raw message

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

95 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#9 lore raw

PATCH v9 6/8 bindings: rust: Add examples to libgpiod crate

In reply to Viresh Kumar

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

---
 .../rust/libgpiod/examples/gpio_events.rs     |  89 ++++++++++++
 .../examples/gpio_threaded_info_events.rs     | 133 ++++++++++++++++++
 bindings/rust/libgpiod/examples/gpiodetect.rs |  31 ++++
 bindings/rust/libgpiod/examples/gpiofind.rs   |  37 +++++
 bindings/rust/libgpiod/examples/gpioget.rs    |  46 ++++++
 bindings/rust/libgpiod/examples/gpioinfo.rs   |  98 +++++++++++++
 bindings/rust/libgpiod/examples/gpiomon.rs    |  75 ++++++++++
 bindings/rust/libgpiod/examples/gpioset.rs    |  64 +++++++++
 bindings/rust/libgpiod/examples/gpiowatch.rs  |  54 +++++++
 9 files changed, 627 insertions(+)
 create mode 100644 bindings/rust/libgpiod/examples/gpio_events.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiodetect.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiofind.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioget.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioinfo.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiomon.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioset.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiowatch.rs
bindings/rust/libgpiod/examples/gpio_events.rs new file +89 -0
new file mode 100644
index 000000000000..6f3c4d5cadb3
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+//
+// Copyright 2022 Linaro Ltd. All Rights Reserved.
+//     Viresh Kumar <[email protected]>
+//
+// Simplified Rust implementation to show handling of events, when the buffer
+// is read into multiple times. Based on gpiomon example.
+
+use std::env;
+
+use libgpiod::{
+    chip::Chip,
+    line::{self, Edge, Offset},
+    request, Error, Result,
+};
+
+fn usage(name: &str) {
+    println!("Usage: {} <chip> <offset0> ...", name);
+}
+
+fn main() -> Result<()> {
+    let args: Vec<String> = env::args().collect();
+    if args.len() < 3 {
+        usage(&args[0]);
+        return Err(Error::InvalidArguments);
+    }
+
+    let mut lsettings = line::Settings::new()?;
+    let lconfig = line::Config::new()?;
+    let mut offsets = Vec::<Offset>::new();
+
+    for arg in &args[2..] {
+        let offset = arg.parse::<Offset>().map_err(|_| Error::InvalidArguments)?;
+        offsets.push(offset);
+    }
+
+    lsettings.set_edge_detection(Some(Edge::Both))?;
+    lconfig.add_line_settings(&offsets, lsettings)?;
+
+    let path = format!("/dev/gpiochip{}", args[1]);
+    let chip = Chip::open(&path)?;
+
+    let rconfig = request::Config::new()?;
+
+    let mut buffer = request::Buffer::new(1)?;
+    let request = chip.request_lines(&rconfig, &lconfig)?;
+
+    loop {
+        match request.wait_edge_event(None) {
+            Err(x) => {
+                println!("{:?}", x);
+                return Err(Error::InvalidArguments);
+            }
+
+            Ok(false) => {
+                // This shouldn't happen as the call is blocking.
+                panic!();
+            }
+            Ok(true) => (),
+        }
+
+        let mut events = request.read_edge_events(&mut buffer)?;
+
+        // This can't be used across the next read_edge_events().
+        let event = events.next().unwrap()?;
+
+        // This will out live `event` and the next read_edge_events().
+        let cloned_event = request::Event::event_clone(event)?;
+
+        let events = request.read_edge_events(&mut buffer)?;
+        for event in events {
+            let event = event?;
+            println!(
+                "line: {} type: {:?}, time: {:?}",
+                event.line_offset(),
+                event.event_type(),
+                event.timestamp()
+            );
+        }
+
+        // `cloned_event` is still available to be used.
+        println!(
+            "line: {} type: {:?}, time: {:?}",
+            cloned_event.line_offset(),
+            cloned_event.event_type(),
+            cloned_event.timestamp()
+        );
+    }
+}
bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs new file +133 -0

133 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpiodetect.rs new file +31 -0
new file mode 100644
index 000000000000..e1d8f59268b5
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+//
+// Copyright 2022 Linaro Ltd. All Rights Reserved.
+//     Viresh Kumar <[email protected]>
+//
+// Simplified Rust implementation of gpiodetect tool.
+
+use std::env;
+use std::path::Path;
+
+use libgpiod::{self, Error, Result};
+
+fn main() -> Result<()> {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 {
+        println!("Usage: {}", args[0]);
+        return Err(Error::InvalidArguments);
+    }
+
+    for chip in libgpiod::gpiochip_devices(&Path::new("/dev"))? {
+        let info = chip.info()?;
+        println!(
+            "{} [{}] ({})",
+            info.name()?,
+            info.label()?,
+            info.num_lines(),
+        );
+    }
+
+    Ok(())
+}
bindings/rust/libgpiod/examples/gpiofind.rs new file +37 -0
new file mode 100644
index 000000000000..daaa93cc1bd2
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+//
+// Copyright 2022 Linaro Ltd. All Rights Reserved.
+//     Viresh Kumar <[email protected]>
+//
+// Simplified Rust implementation of gpiofind tool.
+
+use std::env;
+use std::path::Path;
+
+use libgpiod::{self, Error, Result};
+
+fn main() -> Result<()> {
+    let args: Vec<String> = env::args().collect();
+    if args.len() != 2 {
+        println!("Usage: {} <line-name>", args[0]);
+        return Err(Error::InvalidArguments);
+    }
+
+    for chip in libgpiod::gpiochip_devices(&Path::new("/dev"))? {
+        let offset = chip.line_offset_from_name(&args[1]);
+        let info = chip.info()?;
+
+        if offset.is_ok() {
+            println!(
+                "Line {} found: Chip: {}, offset: {}",
+                args[1],
+                info.name()?,
+                offset?
+            );
+            return Ok(());
+        }
+    }
+
+    println!("Failed to find line: {}", args[1]);
+    Ok(())
+}
bindings/rust/libgpiod/examples/gpioget.rs new file +46 -0

46 lines not on this page · raw message

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

98 lines not on this page · raw message

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

75 lines not on this page · raw message

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

64 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpiowatch.rs new file +54 -0

54 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#10 lore raw

Re: [libgpiod][PATCH V9 6/8] bindings: rust: Add examples to libgpiod crate

Quoted 47 lines
bindings/rust/libgpiod/examples/gpioset.rs new file +41 -0
new file mode 100644
index 000000000000..f72a623ab28c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+//
+// Copyright 2022 Linaro Ltd. All Rights Reserved.
+//     Viresh Kumar <[email protected]>
+//
+// Simplified Rust implementation of the gpioset tool.
+
+use std::env;
+use std::io::{stdin, Read};
+
+use libgpiod::{
+    chip::Chip,
+    line::{self, Direction, Offset, SettingVal, Value},
+    request, Error, Result,
+};
+
+fn usage(name: &str) {
+    println!("Usage: {} <chip> <line_offset0>=<value0> ...", name);
+}
+
+fn main() -> Result<()> {
+    let args: Vec<String> = env::args().collect();
+    if args.len() < 3 {
+        usage(&args[0]);
+        return Err(Error::InvalidArguments);
+    }
+
+    let lconfig = line::Config::new()?;
+
+    for arg in &args[2..] {
+        let pair: Vec<&str> = arg.split('=').collect();
+        if pair.len() != 2 {
+            usage(&args[0]);
+            return Err(Error::InvalidArguments);
+        }
+
+        let offset = pair[0]
+            .parse::<Offset>()
+            .map_err(|_| Error::InvalidArguments)?;
+        let value = pair[1]
+            .parse::<i32>()

bindings/rust/libgpiod/examples/gpioset.rs line 51

Quoted 10 lines
bindings/rust/libgpiod/examples/gpioset.rs new file +10 -0
+            .map_err(|_| Error::InvalidArguments)?;
+
+        let mut lsettings = line::Settings::new()?;
+        lsettings.set_prop(&[
+            SettingVal::Direction(Direction::Output),
+            SettingVal::OutputValue(Value::new(value)?),
+        ])?;
+        lconfig.add_line_settings(&[offset], lsettings)?;
+    }
+

I'm looking at it and thinking that it would look much better as:

let settings = line::Settings::new()

    .set_direction(Direction::Output)
    .set_output_value(Value::new(value))
    .build()?;

settings would not need to be mutable (we'd have some intermediate SettingsBuilder object?) and could be directly passed to add_line_settings()?

We now have chained mutators for LineSettings in C++ and keyword arguments in Python - somehow I think that the former suits rust much better than passing an array of properties.

Bartosz

#11 lore raw

Re: [libgpiod][PATCH V9 6/8] bindings: rust: Add examples to libgpiod crate

Quoted 7 lines · Bartosz Golaszewski

I'm looking at it and thinking that it would look much better as:

let settings = line::Settings::new()

    .set_direction(Direction::Output)
    .set_output_value(Value::new(value))
    .build()?;
Quoted 7 lines

settings would not need to be mutable (we'd have some intermediate SettingsBuilder object?) and could be directly passed to add_line_settings()?

We now have chained mutators for LineSettings in C++ and keyword arguments in Python - somehow I think that the former suits rust much better than passing an array of properties.

We already support chained mutators in the Rust bindings. This example can also be written as:

         let mut lsettings = line::Settings::new()?;
 
         lsettings
             .set_direction(Direction::Output)?
             .set_output_value(Value::new(value)?)?;
Signature · 1 line
viresh
#12 lore raw

Re: [libgpiod][PATCH V9 6/8] bindings: rust: Add examples to libgpiod crate

Quoted 20 lines · Viresh Kumar
Quoted 7 lines · Bartosz Golaszewski

I'm looking at it and thinking that it would look much better as:

let settings = line::Settings::new()

    .set_direction(Direction::Output)
    .set_output_value(Value::new(value))
    .build()?;
Quoted 7 lines

settings would not need to be mutable (we'd have some intermediate SettingsBuilder object?) and could be directly passed to add_line_settings()?

We now have chained mutators for LineSettings in C++ and keyword arguments in Python - somehow I think that the former suits rust much better than passing an array of properties.

We already support chained mutators in the Rust bindings. This example can also be written as:

Quoted 8 lines
         let mut lsettings = line::Settings::new()?;

         lsettings
             .set_direction(Direction::Output)?
             .set_output_value(Value::new(value)?)?;

--
viresh

Ah, I missed that, my bad.

Would it also work in non-mutable way like

let lsettings = line::Settings::new.set_direction(Direction::Output)?;

?

#13 lore raw

Re: [libgpiod][PATCH V9 6/8] bindings: rust: Add examples to libgpiod crate

Quoted 5 lines · Bartosz Golaszewski

Ah, I missed that, my bad.

Would it also work in non-mutable way like

let lsettings = line::Settings::new.set_direction(Direction::Output)?;

No, since set_direction() expects a reference instead of the object itself. So currently we need to do Settings::new() in a separate statement and so mutable is required too. But then we don't need a build() routine to covert to lsettings here.

Signature · 1 line
viresh
#14 lore raw

PATCH v9 7/8 bindings: rust: Add tests for libgpiod crate

In reply to Viresh Kumar

Add tests for the rust bindings, quite similar to the ones in cxx bindings.

---
 bindings/rust/libgpiod/Cargo.toml             |   3 +
 bindings/rust/libgpiod/tests/chip.rs          |  98 ++++
 bindings/rust/libgpiod/tests/common/config.rs | 143 +++++
 bindings/rust/libgpiod/tests/common/mod.rs    |  10 +
 bindings/rust/libgpiod/tests/edge_event.rs    | 298 ++++++++++
 bindings/rust/libgpiod/tests/info_event.rs    | 167 ++++++
 bindings/rust/libgpiod/tests/line_config.rs   |  96 ++++
 bindings/rust/libgpiod/tests/line_info.rs     | 276 ++++++++++
 bindings/rust/libgpiod/tests/line_request.rs  | 510 ++++++++++++++++++
 bindings/rust/libgpiod/tests/line_settings.rs | 204 +++++++
 .../rust/libgpiod/tests/request_config.rs     |  39 ++
 11 files changed, 1844 insertions(+)
 create mode 100644 bindings/rust/libgpiod/tests/chip.rs
 create mode 100644 bindings/rust/libgpiod/tests/common/config.rs
 create mode 100644 bindings/rust/libgpiod/tests/common/mod.rs
 create mode 100644 bindings/rust/libgpiod/tests/edge_event.rs
 create mode 100644 bindings/rust/libgpiod/tests/info_event.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_config.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_info.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_request.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_settings.rs
 create mode 100644 bindings/rust/libgpiod/tests/request_config.rs
bindings/rust/libgpiod/Cargo.toml +3 -0
index 65ca079b5e15..e3fb9b800030 100644
@@ -16,3 +16,6 @@ intmap = "2.0.0"
 libc = "0.2.39"
 libgpiod-sys = { path = "../libgpiod-sys" }
 thiserror = "1.0"
+
+[dev-dependencies]
+gpiosim = { path = "../gpiosim" }
bindings/rust/libgpiod/tests/chip.rs new file +98 -0

98 lines not on this page · raw message

bindings/rust/libgpiod/tests/common/config.rs new file +143 -0

143 lines not on this page · raw message

bindings/rust/libgpiod/tests/common/mod.rs new file +10 -0
new file mode 100644
index 000000000000..b795d8d8bfb1
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+//
+// Copyright 2022 Linaro Ltd. All Rights Reserved.
+//     Viresh Kumar <[email protected]>
+
+#[allow(dead_code)]
+mod config;
+
+#[allow(unused_imports)]
+pub(crate) use config::*;
bindings/rust/libgpiod/tests/edge_event.rs new file +298 -0

298 lines not on this page · raw message

bindings/rust/libgpiod/tests/info_event.rs new file +167 -0

167 lines not on this page · raw message

bindings/rust/libgpiod/tests/line_config.rs new file +96 -0

96 lines not on this page · raw message

bindings/rust/libgpiod/tests/line_info.rs new file +276 -0

276 lines not on this page · raw message

bindings/rust/libgpiod/tests/line_request.rs new file +510 -0

510 lines not on this page · raw message

bindings/rust/libgpiod/tests/line_settings.rs new file +204 -0

204 lines not on this page · raw message

bindings/rust/libgpiod/tests/request_config.rs new file +39 -0
new file mode 100644
index 000000000000..9729fb17368b
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+//
+// Copyright 2022 Linaro Ltd. All Rights Reserved.
+//     Viresh Kumar <[email protected]>
+
+mod common;
+
+mod request_config {
+    use libgpiod::{request, Error as ChipError, OperationType};
+
+    mod verify {
+        use super::*;
+
+        #[test]
+        fn default() {
+            let rconfig = request::Config::new().unwrap();
+
+            assert_eq!(rconfig.event_buffer_size(), 0);
+            assert_eq!(
+                rconfig.consumer().unwrap_err(),
+                ChipError::OperationFailed(
+                    OperationType::RequestConfigGetConsumer,
+                    errno::Errno(0),
+                )
+            );
+        }
+
+        #[test]
+        fn initialized() {
+            const CONSUMER: &str = "foobar";
+            let rconfig = request::Config::new().unwrap();
+            rconfig.set_consumer(CONSUMER).unwrap();
+            rconfig.set_event_buffer_size(64);
+
+            assert_eq!(rconfig.event_buffer_size(), 64);
+            assert_eq!(rconfig.consumer().unwrap(), CONSUMER);
+        }
+    }
+}
Signature · 1 line
2.31.1.272.g89b43f80a514
#15 lore raw

Re: [libgpiod][PATCH V9 7/8] bindings: rust: Add tests for libgpiod crate

Quoted 5 lines · Viresh Kumar

Add tests for the rust bindings, quite similar to the ones in cxx bindings.

Without modifying udev rules on my system - is there a one-liner I could use to launch the tests? I guess using cargo as sudo is wrong but the executables are there so can I somehow run them all at once as if running cargo test?

Bartosz

#16 lore raw

Re: [libgpiod][PATCH V9 7/8] bindings: rust: Add tests for libgpiod crate

Quoted 5 lines · Bartosz Golaszewski
Quoted 4 lines · Viresh Kumar

Add tests for the rust bindings, quite similar to the ones in cxx bindings.

Quoted 7 lines
Quoted 1 line

Without modifying udev rules on my system - is there a one-liner I could use to launch the tests? I guess using cargo as sudo is wrong but the executables are there so can I somehow run them all at once as if running cargo test?

I use:

sudo /home/dev/.cargo/bin/cargo test

so using the cargo installed in the dev account on my test machine.

That way I can build, clippy and generate docs etc as dev, but require sudo for the tests.

I would love to know how to do it without the sudo, but as you suggest, that would probably require some udev magic or something to set the configfs and sysfs file permissions, as well as the gpiochips themselves, and given the above works for me I've not had sufficient incentive to look into it.

Cheers,
Kent.

#17 lore raw

Re: [libgpiod][PATCH V9 7/8] bindings: rust: Add tests for libgpiod crate

Quoted 20 lines · Kent Gibson
Quoted 5 lines · Bartosz Golaszewski
Quoted 4 lines · Viresh Kumar

Add tests for the rust bindings, quite similar to the ones in cxx bindings.

Quoted 7 lines
Quoted 1 line

Without modifying udev rules on my system - is there a one-liner I could use to launch the tests? I guess using cargo as sudo is wrong but the executables are there so can I somehow run them all at once as if running cargo test?

I use:

sudo /home/dev/.cargo/bin/cargo test

so using the cargo installed in the dev account on my test machine.

Quoted 9 lines

That way I can build, clippy and generate docs etc as dev, but require sudo for the tests.

I would love to know how to do it without the sudo, but as you suggest, that would probably require some udev magic or something to set the configfs and sysfs file permissions, as well as the gpiochips themselves, and given the above works for me I've not had sufficient incentive to look into it.

And just to be clear, my libgpiod test machine is a VM, so running as root isn't a huge issue.

Being able to run tests against gpiosim on a real machine, without requiring root, would be really nice to have though.

Cheers,
Kent.

#18 lore raw

Re: [libgpiod][PATCH V9 7/8] bindings: rust: Add tests for libgpiod crate

In reply to Bartosz Golaszewski
Quoted 11 lines · Bartosz Golaszewski
Quoted 5 lines · Viresh Kumar

Add tests for the rust bindings, quite similar to the ones in cxx bindings.

Without modifying udev rules on my system - is there a one-liner I could use to launch the tests? I guess using cargo as sudo is wrong but the executables are there so can I somehow run them all at once as if running cargo test?

What I think the DevOps:y people do is run tests as root but in some virtualized or containerized machine. I don't know how well that approach works with gpiosim though, virtualized probably, containerized hardly, GPIO is just too real.

Yours,
Linus Walleij

#19 lore raw

Re: [libgpiod][PATCH V9 7/8] bindings: rust: Add tests for libgpiod crate

In reply to Bartosz Golaszewski
Quoted 8 lines · Bartosz Golaszewski
Quoted 4 lines · On Mon, Nov 7, 2022 at 10:58 AM Viresh Kumar [email protected] wrote:

Add tests for the rust bindings, quite similar to the ones in cxx bindings.

Quoted 6 lines

Without modifying udev rules on my system - is there a one-liner I could use to launch the tests? I guess using cargo as sudo is wrong but the executables are there so can I somehow run them all at once as if running cargo test?

Bartosz

For running doc tests setting the RUSTDOC env var to a shell script that runs rustdoc as sudo may work. You should probably unset it when using cargo doc though to prevent the generated documentation from being owned by root. For unit tests and integration tests you can set the CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER (adapt for the target triple of your system) env var to "sudo" to run just the tests as root using sudo, but keep cargo running as regular user. The runner env var also applies to cargo run and cargo bench. See [1] for some basic documentation.

[1] https://doc.rust-lang.org/cargo/reference/config.html#targettriplerunner

Cheers,
Björn

#20 lore raw

PATCH v9 8/8 bindings: rust: Integrate building of bindings with make

In reply to Viresh Kumar

Lets make build rust bindings as well.

---
 README                    |  8 +++++---
 TODO                      |  8 --------
 bindings/Makefile.am      |  6 ++++++
 bindings/rust/Makefile.am | 18 ++++++++++++++++++
 configure.ac              | 16 ++++++++++++++++
 5 files changed, 45 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 +18 -0
new file mode 100644
index 000000000000..79a52bc691ae
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2022 Viresh Kumar <[email protected]>
+
+command = cargo build --release --lib
+
+if WITH_TESTS
+command += --tests
+endif
+
+if WITH_EXAMPLES
+command += --examples
+endif
+
+all:
+	$(command)
+
+clean:
+	cargo clean
configure.ac +16 -0
index 048b2ac7af8f..4a2cdb68b8b0 100644
@@ -212,6 +212,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
@@ -249,6 +264,7 @@ AC_CONFIG_FILES([Makefile
 		 bindings/python/examples/Makefile
 		 bindings/python/tests/Makefile
 		 bindings/python/tests/gpiosim/Makefile
+		 bindings/rust/Makefile
 		 man/Makefile])
 
 AC_OUTPUT
Signature · 1 line
2.31.1.272.g89b43f80a514
#21 lore raw
In reply to Viresh Kumar
Quoted 9 lines · Viresh Kumar

Hello,

Here is another version of the rust bindings, based of the master branch.

Pushed here:

https://github.com/vireshk/libgpiod v9

Quoted 11 lines

V8->V9:
- Merged the last patch (supporting Events) with the other patches.
- Events implementation is simplified and made efficient. nth() is also implemented for the iterator.
- Unnecessary comment removed from Cargo.toml files.
- Updated categories in libgpiod's Cargo.toml.
- Updated gpio_events example to show cloned events live past another read_edge_events().
- Implement AsRawFd for Chip.
- Other minor changes.

Kent, Miguel: if you are ok with this version - can you add your review tags?

Bart

Reviewed-by
#22 lore raw
Quoted 22 lines · Bartosz Golaszewski
Quoted 9 lines · Viresh Kumar

Hello,

Here is another version of the rust bindings, based of the master branch.

Pushed here:

https://github.com/vireshk/libgpiod v9

Quoted 11 lines

V8->V9:
- Merged the last patch (supporting Events) with the other patches.
- Events implementation is simplified and made efficient. nth() is also implemented for the iterator.
- Unnecessary comment removed from Cargo.toml files.
- Updated categories in libgpiod's Cargo.toml.
- Updated gpio_events example to show cloned events live past another read_edge_events().
- Implement AsRawFd for Chip.
- Other minor changes.

Quoted 3 lines

Kent, Miguel: if you are ok with this version - can you add your review tags?

Bart

As mentioned elsewhere, I'm a bit iffy about the handling of non-UTF-8 names, which are treated as errors, but are valid in the C API. But that is an extreme corner case that can be addressed later, so I have no objection to this version being merged.

Cheers,
Kent.

#23 lore raw
Quoted 32 lines · On Wed, 16 Nov 2022 09:12:01 +0800 Kent Gibson <[email protected]> wrote:
Quoted 22 lines · Bartosz Golaszewski
Quoted 9 lines · Viresh Kumar

Hello,

Here is another version of the rust bindings, based of the master branch.

Pushed here:

https://github.com/vireshk/libgpiod v9

Quoted 11 lines

V8->V9:
- Merged the last patch (supporting Events) with the other patches.
- Events implementation is simplified and made efficient. nth() is also implemented for the iterator.
- Unnecessary comment removed from Cargo.toml files.
- Updated categories in libgpiod's Cargo.toml.
- Updated gpio_events example to show cloned events live past another read_edge_events().
- Implement AsRawFd for Chip.
- Other minor changes.

Quoted 3 lines

Kent, Miguel: if you are ok with this version - can you add your review tags?

Bart

As mentioned elsewhere, I'm a bit iffy about the handling of non-UTF-8 names, which are treated as errors, but are valid in the C API. But that is an extreme corner case that can be addressed later, so I have no objection to this version being merged.

Quoted 4 lines

Cheers,
Kent.

I have glanced through the code and I find no reason that the str used couldn't be replaced with [u8] or OsStr. The former might be a little bit difficult to use, but OsStr could be easily converted into str by just .to_str().expect("name should be utf-8") if the user don't care about non-UTF-8 or is certain that names are indeed UTF-8.

I am not sure about whether this would be worthwhile though, because I doubt if anyone is actually using non-UTF-8 strings in those places. Non-ASCII usages should already be rare?

Best,
Gary

#24 lore raw
Quoted 37 lines · Gary Guo
Quoted 34 lines · On Wed, 16 Nov 2022 09:12:01 +0800 Kent Gibson <[email protected]> wrote:
Quoted 22 lines · Bartosz Golaszewski
Quoted 9 lines · Viresh Kumar

Hello,

Here is another version of the rust bindings, based of the master branch.

Pushed here:

https://github.com/vireshk/libgpiod v9

Quoted 11 lines

V8->V9:
- Merged the last patch (supporting Events) with the other patches.
- Events implementation is simplified and made efficient. nth() is also implemented for the iterator.
- Unnecessary comment removed from Cargo.toml files.
- Updated categories in libgpiod's Cargo.toml.
- Updated gpio_events example to show cloned events live past another read_edge_events().
- Implement AsRawFd for Chip.
- Other minor changes.

Quoted 3 lines

Kent, Miguel: if you are ok with this version - can you add your review tags?

Bart

As mentioned elsewhere, I'm a bit iffy about the handling of non-UTF-8 names, which are treated as errors, but are valid in the C API. But that is an extreme corner case that can be addressed later, so I have no objection to this version being merged.

Quoted 9 lines
Quoted 2 lines

Cheers,
Kent.

I have glanced through the code and I find no reason that the str used couldn't be replaced with [u8] or OsStr. The former might be a little bit difficult to use, but OsStr could be easily converted into str by just .to_str().expect("name should be utf-8") if the user don't care about non-UTF-8 or is certain that names are indeed UTF-8.

Or you can use OsStr::to_string_lossy() though that requires allocation.

str is preferable as it is easer to use, and 99.99% of the time will be fine. I have toyed with using OsStr, but having to do the conversion becomes really tedious really fast.

Quoted 4 lines

I am not sure about whether this would be worthwhile though, because I doubt if anyone is actually using non-UTF-8 strings in those places. Non-ASCII usages should already be rare?

That is what I meant by "an extreme corner case".

The problem with the GPIO uAPI is that it limits names to 32 bytes, and valid UTF-8 passed in may get truncated mid-codepoint, resulting in invalid UTF-8 when read back.
Handling that case by truncating the string before the split codepoint would at least ensure that the Rust API would round-trip.

Cheers,
Kent.

#25 lore raw
In reply to Viresh Kumar
Quoted 193 lines · Viresh Kumar

Hello,

Here is another version of the rust bindings, based of the master branch.

Pushed here:

https://github.com/vireshk/libgpiod v9

V8->V9:
- Merged the last patch (supporting Events) with the other patches.
- Events implementation is simplified and made efficient. nth() is also implemented for the iterator.
- Unnecessary comment removed from Cargo.toml files.
- Updated categories in libgpiod's Cargo.toml.
- Updated gpio_events example to show cloned events live past another read_edge_events().
- Implement AsRawFd for Chip.
- Other minor changes.

V7->V8:
- Several updates to cargo.toml files, like license, version, etc.
- Removed Sync support for chip and gpiosim.
- Implemented, in a separate patch, iterator support for Events.
- Fixed missing SAFETY comments.
- Fixed build for 32 bit systems.
- Use errno::Errno.
- Removed Clone derive for many structures, that store raw pointers.
- line setting helpers return the object back, so another helper can be called directly on them. Also made all helpers public and used the same in tests and example for single configurations.
- Enums for gpiosim constants.
- New examples to demonstrate parallelism and event handling.
- Separated out HTE tests and marked as #[ignore] now.
- Updated commit subjects.
- Other minor changes.

V6->V7:
- Don't let buffer read new events if the earlier events are still referenced.
- BufferIntenal is gone now, to make the above work.
- Update example and tests too for the same.

V5->V6:
- Updates according to the new line-settings interface.
- New file, line_settings.rs.
- Renamed 'enum Setting' as 'SettingVal' to avoid conflicting names, as we also have 'struct Settings' now.
- Support for HTE clock type.
- Implement 'Eq' for public structure/enums (reported by build).
- Remove 'SettingKindMap' and 'SettingMap' as they aren't required anymore.
- Updated tests based on new interface.

V4->V5:
- Arrange as workspace with crates for libgpiod-sys, libgpiod, gpiosim.
- Use static libgpiod and libgpiosim libraries instead of rebuilding again.
- Arrange in modules instead of flattened approach.
- New enums like Setting and SettingKind and new types based on them SettingMap and SettingKindMap.
- New property independent helpers for line_config, like set_prop_default().
- Improved tests/examples, new example for gpiowatch.
- Add pre-built bindings for gpiosim too.
- Many other changes.

V3->V4:
- Rebased on top of new changes, and made changes accordingly.
- Added rust integration tests with gpiosim.
- Found a kernel bug with tests, sent a patch for that to LKML.

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 (8):
bindings: rust: Add libgpiod-sys rust crate
bindings: rust: Add pre generated bindings for libgpiod-sys
bindings: rust: Add gpiosim crate
bindings: rust: Add pre generated bindings for gpiosim
bindings: rust: Add libgpiod crate
bindings: rust: Add examples to libgpiod crate
bindings: rust: Add tests for libgpiod crate
bindings: rust: Integrate building of bindings with make

 .gitignore                                    |    5 +
 README                                        |    8 +-
 TODO                                          |    8 -
 bindings/Makefile.am                          |    6 +
 bindings/rust/Cargo.toml                      |    7 +
 bindings/rust/Makefile.am                     |   18 +
 bindings/rust/gpiosim/Cargo.toml              |   22 +
 bindings/rust/gpiosim/README.md               |   11 +
 bindings/rust/gpiosim/build.rs                |   43 +
 bindings/rust/gpiosim/src/bindings.rs         |  180 +++
 bindings/rust/gpiosim/src/lib.rs              |   79 ++
 bindings/rust/gpiosim/src/sim.rs              |  331 +++++
 bindings/rust/libgpiod-sys/Cargo.toml         |   20 +
 bindings/rust/libgpiod-sys/README.md          |   11 +
 bindings/rust/libgpiod-sys/build.rs           |   41 +
 bindings/rust/libgpiod-sys/src/bindings.rs    | 1173 +++++++++++++++++
 bindings/rust/libgpiod-sys/src/lib.rs         |   13 +
 bindings/rust/libgpiod/Cargo.toml             |   21 +
 .../rust/libgpiod/examples/gpio_events.rs     |   89 ++
 .../examples/gpio_threaded_info_events.rs     |  133 ++
 bindings/rust/libgpiod/examples/gpiodetect.rs |   31 +
 bindings/rust/libgpiod/examples/gpiofind.rs   |   37 +
 bindings/rust/libgpiod/examples/gpioget.rs    |   46 +
 bindings/rust/libgpiod/examples/gpioinfo.rs   |   98 ++
 bindings/rust/libgpiod/examples/gpiomon.rs    |   75 ++
 bindings/rust/libgpiod/examples/gpioset.rs    |   64 +
 bindings/rust/libgpiod/examples/gpiowatch.rs  |   54 +
 bindings/rust/libgpiod/src/chip.rs            |  310 +++++
 bindings/rust/libgpiod/src/edge_event.rs      |   93 ++
 bindings/rust/libgpiod/src/event_buffer.rs    |  167 +++
 bindings/rust/libgpiod/src/info_event.rs      |   69 +
 bindings/rust/libgpiod/src/lib.rs             |  479 +++++++
 bindings/rust/libgpiod/src/line_config.rs     |  135 ++
 bindings/rust/libgpiod/src/line_info.rs       |  162 +++
 bindings/rust/libgpiod/src/line_request.rs    |  227 ++++
 bindings/rust/libgpiod/src/line_settings.rs   |  297 +++++
 bindings/rust/libgpiod/src/request_config.rs  |   95 ++
 bindings/rust/libgpiod/tests/chip.rs          |   98 ++
 bindings/rust/libgpiod/tests/common/config.rs |  143 ++
 bindings/rust/libgpiod/tests/common/mod.rs    |   10 +
 bindings/rust/libgpiod/tests/edge_event.rs    |  298 +++++
 bindings/rust/libgpiod/tests/info_event.rs    |  167 +++
 bindings/rust/libgpiod/tests/line_config.rs   |   96 ++
 bindings/rust/libgpiod/tests/line_info.rs     |  276 ++++
 bindings/rust/libgpiod/tests/line_request.rs  |  510 +++++++
 bindings/rust/libgpiod/tests/line_settings.rs |  204 +++
 .../rust/libgpiod/tests/request_config.rs     |   39 +
 configure.ac                                  |   16 +
 48 files changed, 6504 insertions(+), 11 deletions(-)
 create mode 100644 bindings/rust/Cargo.toml
 create mode 100644 bindings/rust/Makefile.am
 create mode 100644 bindings/rust/gpiosim/Cargo.toml
 create mode 100644 bindings/rust/gpiosim/README.md
 create mode 100644 bindings/rust/gpiosim/build.rs
 create mode 100644 bindings/rust/gpiosim/src/bindings.rs
 create mode 100644 bindings/rust/gpiosim/src/lib.rs
 create mode 100644 bindings/rust/gpiosim/src/sim.rs
 create mode 100644 bindings/rust/libgpiod-sys/Cargo.toml
 create mode 100644 bindings/rust/libgpiod-sys/README.md
 create mode 100644 bindings/rust/libgpiod-sys/build.rs
 create mode 100644 bindings/rust/libgpiod-sys/src/bindings.rs
 create mode 100644 bindings/rust/libgpiod-sys/src/lib.rs
 create mode 100644 bindings/rust/libgpiod/Cargo.toml
 create mode 100644 bindings/rust/libgpiod/examples/gpio_events.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiodetect.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiofind.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioget.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioinfo.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiomon.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpioset.rs
 create mode 100644 bindings/rust/libgpiod/examples/gpiowatch.rs
 create mode 100644 bindings/rust/libgpiod/src/chip.rs
 create mode 100644 bindings/rust/libgpiod/src/edge_event.rs
 create mode 100644 bindings/rust/libgpiod/src/event_buffer.rs
 create mode 100644 bindings/rust/libgpiod/src/info_event.rs
 create mode 100644 bindings/rust/libgpiod/src/lib.rs
 create mode 100644 bindings/rust/libgpiod/src/line_config.rs
 create mode 100644 bindings/rust/libgpiod/src/line_info.rs
 create mode 100644 bindings/rust/libgpiod/src/line_request.rs
 create mode 100644 bindings/rust/libgpiod/src/line_settings.rs
 create mode 100644 bindings/rust/libgpiod/src/request_config.rs
 create mode 100644 bindings/rust/libgpiod/tests/chip.rs
 create mode 100644 bindings/rust/libgpiod/tests/common/config.rs
 create mode 100644 bindings/rust/libgpiod/tests/common/mod.rs
 create mode 100644 bindings/rust/libgpiod/tests/edge_event.rs
 create mode 100644 bindings/rust/libgpiod/tests/info_event.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_config.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_info.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_request.rs
 create mode 100644 bindings/rust/libgpiod/tests/line_settings.rs
 create mode 100644 bindings/rust/libgpiod/tests/request_config.rs
Quoted 3 lines

--
2.31.1.272.g89b43f80a514

Hi Viresh,

There are some licensing issues I noticed now: can you make sure reuse lint doesn't return errors for rust bindings?

One other thing is the license of the rust bindings themselves - I'm not a lawyer but it seems to me that if you link against LGPL code statically, your code must be licensed under an LGPL-compatible license. It seems that BSD-3-Clause and Apache-2.0 are compatible but it would be great to have someone knowledgeable comment on that. Is there anyone at linaro we could contact?

Bart

#26 lore raw
Quoted 4 lines · Bartosz Golaszewski

Hi Viresh,

There are some licensing issues I noticed now: can you make sure reuse lint doesn't return errors for rust bindings?

I have fixed couple of those now, but there are few which I am not sure about.

# MISSING COPYRIGHT AND LICENSING INFORMATION

The following files have no copyright and licensing information:
* ../../bindings/rust/Cargo.toml
* ../../bindings/rust/gpiosim/Cargo.toml
* ../../bindings/rust/gpiosim/README.md
* ../../bindings/rust/gpiosim/src/bindings.rs
* ../../bindings/rust/libgpiod/Cargo.toml
* ../../bindings/rust/libgpiod-sys/Cargo.toml
* ../../bindings/rust/libgpiod-sys/README.md
* ../../bindings/rust/libgpiod-sys/src/bindings.rs

File types:
- Cargo.toml

Most of these have a different style for versioning, though the workspace specific files doesn't have a version set. I checked few other projects and they didn't mention it as well.

- README.md

Here also version is mentioned differently (added now), based on how I found it elsewhere, i.e. towards the bottom of the file.

- bindings.rs

These are automatically genrated files, with bindgen. Not sure if we should edit them to add Licensing info.

Quoted 6 lines

One other thing is the license of the rust bindings themselves - I'm not a lawyer but it seems to me that if you link against LGPL code statically, your code must be licensed under an LGPL-compatible license. It seems that BSD-3-Clause and Apache-2.0 are compatible but it would be great to have someone knowledgeable comment on that. Is there anyone at linaro we could contact?

Hmm, not sure. Cc'ing Arnd, in case he can help.

Signature · 1 line
viresh
#27 lore raw
Quoted 21 lines · Viresh Kumar
Quoted 4 lines · Bartosz Golaszewski

Hi Viresh,

There are some licensing issues I noticed now: can you make sure reuse lint doesn't return errors for rust bindings?

I have fixed couple of those now, but there are few which I am not sure about.

# MISSING COPYRIGHT AND LICENSING INFORMATION

The following files have no copyright and licensing information:
* ../../bindings/rust/Cargo.toml
* ../../bindings/rust/gpiosim/Cargo.toml
* ../../bindings/rust/gpiosim/README.md
* ../../bindings/rust/gpiosim/src/bindings.rs
* ../../bindings/rust/libgpiod/Cargo.toml
* ../../bindings/rust/libgpiod-sys/Cargo.toml
* ../../bindings/rust/libgpiod-sys/README.md
* ../../bindings/rust/libgpiod-sys/src/bindings.rs

Quoted 7 lines

File types:
- Cargo.toml

Most of these have a different style for versioning, though the workspace specific files doesn't have a version set. I checked few other projects and they didn't mention it as well.

Just use regular SPDX header at the top of the file in a # comment block?

Quoted 5 lines

- README.md

Here also version is mentioned differently (added now), based on how I found it elsewhere, i.e. towards the bottom of the file.

The main README.md just has a regular header at the top of the file. I'm fine with this. I guess the bottom of the file is good too.

Quoted 5 lines

- bindings.rs

These are automatically genrated files, with bindgen. Not sure if we should edit them to add Licensing info.

Can we not generate them at build-time then? When I was first flirting with implementing a dbus daemon for libgpiod, I used gdbus-codegen to generate dbus bindings from xml but I generated them at build-time instead of putting them into the repo. It would also shrink the release checklist for rust if we didn't have to manually regenerate them.

Bart

Quoted 9 lines
Quoted 6 lines

One other thing is the license of the rust bindings themselves - I'm not a lawyer but it seems to me that if you link against LGPL code statically, your code must be licensed under an LGPL-compatible license. It seems that BSD-3-Clause and Apache-2.0 are compatible but it would be great to have someone knowledgeable comment on that. Is there anyone at linaro we could contact?

Hmm, not sure. Cc'ing Arnd, in case he can help.

I think that's been clarified by Linus below. We should be good.

Bartosz

#28 lore raw
Quoted 9 lines · Bartosz Golaszewski
Quoted 7 lines

File types:
- Cargo.toml

Most of these have a different style for versioning, though the workspace specific files doesn't have a version set. I checked few other projects and they didn't mention it as well.

Just use regular SPDX header at the top of the file in a # comment block?

Miguel ? Kent ?

Quoted 7 lines
Quoted 5 lines

- bindings.rs

These are automatically genrated files, with bindgen. Not sure if we should edit them to add Licensing info.

Can we not generate them at build-time then?

We can, and we do when we do "cargo build --features=generate".

There are reasons to keep them merged though. It lets the users avoid generating them on the go, like the vhost-device [1] crate in my case. I also faced issues with the rust-vmm containers, where vhost-device stuff gets auto-tested, in enabling bindgen support and finally went back to keeping them generated in advance. This is also the normal practice it seems, from whatever I have seen from the rust-vmm community at least.

Maybe then add the header manually to them ?

Signature · 3 lines
viresh

[1] https://github.com/rust-vmm/vhost-device
#29 lore raw
Quoted 22 lines · Viresh Kumar
Quoted 9 lines · Bartosz Golaszewski
Quoted 7 lines

File types:
- Cargo.toml

Most of these have a different style for versioning, though the workspace specific files doesn't have a version set. I checked few other projects and they didn't mention it as well.

Just use regular SPDX header at the top of the file in a # comment block?

Miguel ? Kent ?

Quoted 7 lines
Quoted 5 lines

- bindings.rs

These are automatically genrated files, with bindgen. Not sure if we should edit them to add Licensing info.

Can we not generate them at build-time then?

Quoted 9 lines

We can, and we do when we do "cargo build --features=generate".

There are reasons to keep them merged though. It lets the users avoid generating them on the go, like the vhost-device [1] crate in my case. I also faced issues with the rust-vmm containers, where vhost-device stuff gets auto-tested, in enabling bindgen support and finally went back to keeping them generated in advance. This is also the normal practice it seems, from whatever I have seen from the rust-vmm community at least.

Do these problems you faced apply to libgpiod too? Honestly, putting automatically generated files in the repo just feels wrong. It defeats the whole purpose of code generation. If we can't reliably regenerate them, then it sounds like a problem with the tools, not the library. Maybe we don't need to worry about that just yet?

Bart

Quoted 6 lines

Maybe then add the header manually to them ?

--
viresh

[1] https://github.com/rust-vmm/vhost-device

#30 lore raw
Quoted 1 line · Bartosz Golaszewski

Do these problems you faced apply to libgpiod too?

I faced them with libgpiod only :(

Quoted 2 lines

Honestly, putting
automatically generated files in the repo just feels wrong.

I agree, but ...

Quoted 4 lines

It defeats
the whole purpose of code generation. If we can't reliably regenerate them, then it sounds like a problem with the tools, not the library. Maybe we don't need to worry about that just yet?

it isn't about reliability of the generated code, but making everyone do it, even if they don't need to.

Also, the code generated here is Rust code wrappers and other declarations, which let us call the C helpers eventually. It can be considered like hand written code here, for the argument that it is automatically generated stuff. Just that we have a tool (bindgen) here which lets us generate it automatically, without introducing bugs.

Anyway, I am fine with whatever you decide.

Signature · 1 line
viresh
#31 lore raw
Quoted 19 lines · Viresh Kumar
Quoted 1 line · Bartosz Golaszewski

Do these problems you faced apply to libgpiod too?

I faced them with libgpiod only :(

Quoted 2 lines

Honestly, putting
automatically generated files in the repo just feels wrong.

I agree, but ...

Quoted 4 lines

It defeats
the whole purpose of code generation. If we can't reliably regenerate them, then it sounds like a problem with the tools, not the library. Maybe we don't need to worry about that just yet?

it isn't about reliability of the generated code, but making everyone do it, even if they don't need to.

Quoted 8 lines

Also, the code generated here is Rust code wrappers and other declarations, which let us call the C helpers eventually. It can be considered like hand written code here, for the argument that it is automatically generated stuff. Just that we have a tool (bindgen) here which lets us generate it automatically, without introducing bugs.

Anyway, I am fine with whatever you decide.

Let me propose a different solution. When preparing release tarballs with autotools, certain files are generated automatically that go into the tarball but are never part of the repository. This way developers don't have to deal with the automatically generated files polluting the repo while end-users get a tarball with less dependencies and reproducible results.

It's called the dist-local hook in automake.

Does it sound like something we could use here?

Bart

#32 lore raw
Quoted 10 lines · Bartosz Golaszewski

Let me propose a different solution. When preparing release tarballs with autotools, certain files are generated automatically that go into the tarball but are never part of the repository. This way developers don't have to deal with the automatically generated files polluting the repo while end-users get a tarball with less dependencies and reproducible results.

It's called the dist-local hook in automake.

Does it sound like something we could use here?

These auto-generated bindings are used only by the code present in bindings/rust/libgpiod/src/, and are never visible to end user code.

The end user will use the new interface provided by the libgpiod Rust bindings instead and that works over the web and will be picked from libgpiod's git tree or crates.io (later).

Not sure how the tarball solution will work here.

Signature · 1 line
viresh
#33 lore raw
Quoted 13 lines · Viresh Kumar
Quoted 10 lines · Bartosz Golaszewski

Let me propose a different solution. When preparing release tarballs with autotools, certain files are generated automatically that go into the tarball but are never part of the repository. This way developers don't have to deal with the automatically generated files polluting the repo while end-users get a tarball with less dependencies and reproducible results.

It's called the dist-local hook in automake.

Does it sound like something we could use here?

Quoted 9 lines

These auto-generated bindings are used only by the code present in bindings/rust/libgpiod/src/, and are never visible to end user code.

The end user will use the new interface provided by the libgpiod Rust bindings instead and that works over the web and will be picked from libgpiod's git tree or crates.io (later).

Not sure how the tarball solution will work here.

So it already only impacts developers exclusively and not users who'd for example want to install libgpiod from crates.io? If so then I don't really see a reason to keep those files in the repo really.

I'm not familiar with rust-vmm containers but the fact that bindgen support is missing or causes problems sounds like a problem with rust-vmm and not users of bindgen, right?

Bart

#34 lore raw
Quoted 3 lines · Bartosz Golaszewski

So it already only impacts developers exclusively and not users who'd for example want to install libgpiod from crates.io? If so then I don't really see a reason to keep those files in the repo really.

Users are impacted in the sense that they will be forced to build the bindings using bindgen now, automatically of course. It is an extra, time consuming, operation which can be avoided. For rust-vmm projects, every pull request results in fresh rebuild of the entire crate, which would mean two additional bindgen builds too, just for gpio now. It isn't a huge problem, but it is time that could have been saved.

Quoted 3 lines

I'm not familiar with rust-vmm containers but the fact that bindgen support is missing or causes problems sounds like a problem with rust-vmm and not users of bindgen, right?

Yeah it can be, but IIUC, in the Rust world, more often than not such bindings are pre-generated, as this basically is Rust code only. These bindings will only change if we make a change to the gpiod API.

Perhaps that's why I was asked to avoid generating the bindings there, but I can ask again and try fixing the rust-vmm containers if it doesn't work.

Signature · 1 line
viresh
#35 lore raw
Quoted 6 lines · Viresh Kumar
Quoted 3 lines · Bartosz Golaszewski

So it already only impacts developers exclusively and not users who'd for example want to install libgpiod from crates.io? If so then I don't really see a reason to keep those files in the repo really.

Quoted 7 lines

Users are impacted in the sense that they will be forced to build the bindings using bindgen now, automatically of course. It is an extra, time consuming, operation which can be avoided. For rust-vmm projects, every pull request results in fresh rebuild of the entire crate, which would mean two additional bindgen builds too, just for gpio now. It isn't a huge problem, but it is time that could have been saved.

If build-time is the only issue then I vote for automatic generation at build-time and not storing those files.

Quoted 8 lines
Quoted 3 lines

I'm not familiar with rust-vmm containers but the fact that bindgen support is missing or causes problems sounds like a problem with rust-vmm and not users of bindgen, right?

Yeah it can be, but IIUC, in the Rust world, more often than not such bindings are pre-generated, as this basically is Rust code only. These bindings will only change if we make a change to the gpiod API.

Leaving space for maintainer errors when preparing releases I suppose. I don't know what the reason is for the Rust world to go that way but more often than not, files that are generated automatically are not checked in into repositories. This is my experience from working with Qt, GLib or the linux kernel (flex and bison files generated by kconfig).

Quoted 3 lines

Perhaps that's why I was asked to avoid generating the bindings there, but I can ask again and try fixing the rust-vmm containers if it doesn't work.

Yes, if there's no show-stopper then let's generate the files at build-time which also fixes the licensing issue.

Bart

#36 lore raw
In reply to Bartosz Golaszewski
Quoted 7 lines · Viresh Kumar

Do these problems you faced apply to libgpiod too? Honestly, putting automatically generated files in the repo just feels wrong. It defeats the whole purpose of code generation. If we can't reliably regenerate them, then it sounds like a problem with the tools, not the library. Maybe we don't need to worry about that just yet?

If the library is stable enough, then removing a heavy build dependency on bindgen may be worth it. But yeah, by default I would avoid it unless one is sure it is possible.

Though, if one can store it because it is fixed, at that point one may take advantage of that and manually write (or tweak) the bindings instead.

In any case, I would explain the rationale one way or the other in the commit message or ideally in the README.MD.

One thing I may have missed: why is there a -sys crate for one of the bindings but not the other? It may be a good idea to document the intention as well.

Cheers,
Miguel

#37 lore raw
Quoted 3 lines · Miguel Ojeda

One thing I may have missed: why is there a -sys crate for one of the bindings but not the other? It may be a good idea to document the intention as well.

gpiosim ? Maybe yeah, it should be gpiosim-sys too.

Signature · 1 line
viresh
#38 lore raw
In reply to Viresh Kumar
Quoted 6 lines · Viresh Kumar
Quoted 2 lines · Bartosz Golaszewski

Just use regular SPDX header at the top of the file in a # comment block?

Miguel ? Kent ?

In the kernel at least, all files (including docs) should have an SPDX line.

However, configuration files which use a publicly documented format (things like dot files) are not copyrightable apparently, and it was proposed that the scripts/spdxexclude kernel script excludes those [1], but the patch has not been merged (yet?) since I raised a couple questions about how to handle those (sorry...).

So I am not sure if e.g. Cargo.toml should have a SPDX license identifier or not.

[1] https://lore.kernel.org/lkml/[email protected]/

Cheers,
Miguel

#39 lore raw
Quoted 17 lines · Miguel Ojeda
Quoted 6 lines · Viresh Kumar
Quoted 2 lines · Bartosz Golaszewski

Just use regular SPDX header at the top of the file in a # comment block?

Miguel ? Kent ?

In the kernel at least, all files (including docs) should have an SPDX line.

However, configuration files which use a publicly documented format (things like dot files) are not copyrightable apparently, and it was proposed that the scripts/spdxexclude kernel script excludes those [1], but the patch has not been merged (yet?) since I raised a couple questions about how to handle those (sorry...).

Quoted 7 lines

So I am not sure if e.g. Cargo.toml should have a SPDX license identifier or not.

[1] https://lore.kernel.org/lkml/[email protected]/

Cheers,
Miguel

Ha! I wasn't even aware of this spdxexclude and spdxcheck mechanism. What does spdxcheck do better than reuse lint other than having its own ignore list?

I'm not sure I want to import it into libgpiod though.

Reuse docs say:

---
You probably will have files in your project that you do not find particularly copyrightable, for example configuration files such as .gitignore. Intuitively you may not want to license these files, but the fundamental idea of REUSE is that all your files will clearly have their copyright and licensing marked.
---

So I'd say - just use CC0-1.0 license in Cargo.toml?

Bart

#40 lore raw
Quoted 1 line · Bartosz Golaszewski

So I'd say - just use CC0-1.0 license in Cargo.toml?

The Cargo.toml files already have following currently:

license = "Apache-2.0 OR BSD-3-Clause"

Signature · 1 line
viresh
#41 lore raw
Quoted 8 lines · Viresh Kumar
Quoted 1 line · Bartosz Golaszewski

So I'd say - just use CC0-1.0 license in Cargo.toml?

The Cargo.toml files already have following currently:

license = "Apache-2.0 OR BSD-3-Clause"

Then let's just add the SPDX identifier on top to make reuse happy.

Bart

#42 lore raw
Quoted 1 line · Bartosz Golaszewski

Then let's just add the SPDX identifier on top to make reuse happy.

This looks fine ?

bindings/rust/Cargo.toml +5 -0
index 4fdf4e06ff90..85abe70b4aa5 100644
@@ -1,7 +1,12 @@
+# SPDX-License-Identifier: CC0-1.0
+#
+# Copyright 2022 Linaro Ltd. All Rights Reserved.
+#     Viresh Kumar <[email protected]>
+
 [workspace]
 
 
bindings/rust/libgpiod-sys/README.md +5 -1
index ecf75b31c41e..567891a30868 100644
@@ -1,11 +1,15 @@
+# SPDX-License-Identifier: CC0-1.0
+#
+# Copyright 2022 Linaro Ltd. All Rights Reserved.
+#     Viresh Kumar <[email protected]>
+
 # Generated libgpiod-sys Rust FFI bindings
 
-- 

viresh

#43 lore raw
Quoted 11 lines · Viresh Kumar
Quoted 1 line · Bartosz Golaszewski

Then let's just add the SPDX identifier on top to make reuse happy.

This looks fine ?

bindings/rust/Cargo.toml +0 -0
index 4fdf4e06ff90..85abe70b4aa5 100644

bindings/rust/Cargo.toml line 5

Quoted 5 lines
bindings/rust/Cargo.toml +5 -0
@@ -1,7 +1,12 @@
+# SPDX-License-Identifier: CC0-1.0
+#
+# Copyright 2022 Linaro Ltd. All Rights Reserved.
+#     Viresh Kumar <[email protected]>
+

Should be:

# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: 2022 Linaro Ltd.
# SPDX-FileCopyrightTest: 2022 Viresh Kumar <[email protected]>

Quoted 17 lines
bindings/rust/Cargo.toml +0 -0
 [workspace]
 
 
bindings/rust/libgpiod-sys/README.md +5 -1
index ecf75b31c41e..567891a30868 100644
@@ -1,11 +1,15 @@
+# SPDX-License-Identifier: CC0-1.0
+#
+# Copyright 2022 Linaro Ltd. All Rights Reserved.
+#     Viresh Kumar <[email protected]>
+
 # Generated libgpiod-sys Rust FFI bindings
 
--

viresh

#44 lore raw
Quoted 5 lines · Bartosz Golaszewski

Should be:

# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: 2022 Linaro Ltd.
# SPDX-FileCopyrightTest: 2022 Viresh Kumar <[email protected]>

For all files ? Or just Cargo.toml and README.md files ?

Signature · 1 line
viresh
#45 lore raw
Quoted 10 lines · Viresh Kumar
Quoted 5 lines · Bartosz Golaszewski

Should be:

# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: 2022 Linaro Ltd.
# SPDX-FileCopyrightTest: 2022 Viresh Kumar <[email protected]>

For all files ? Or just Cargo.toml and README.md files ?

All files. We're using unified SPFX-FileCopyrightText instead of custom notices.

Bart

#46 lore raw
In reply to Viresh Kumar
Quoted 7 lines · Viresh Kumar
Quoted 1 line · Bartosz Golaszewski

So I'd say - just use CC0-1.0 license in Cargo.toml?

The Cargo.toml files already have following currently:

license = "Apache-2.0 OR BSD-3-Clause"

That is the license for the resulting crate, not the Cargo.toml file itself. And they aren't necessarily the same.

Using CC0-1.0 for config and documentation makes sense to me.

Cheers,
Kent.

#47 lore raw
In reply to Bartosz Golaszewski
Quoted 4 lines · Bartosz Golaszewski

One other thing is the license of the rust bindings themselves - I'm not a lawyer but it seems to me that if you link against LGPL code statically, your code must be licensed under an LGPL-compatible license.

Nope. The LGPL was created exactly for clarifying and avoiding that situation.

https://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License

It is a common misunderstanding that GPL overall has anything to do with whether you link things this or that way, the legal term used is "derivative work" and the meaning of that can only be determined in court. The meaning can depend on the intent of the author and misc legal ramifications.

In many ways LGPL is unnecessary, but it was created exactly to make non-legal people less weary about situations relating to linking of libraries.

It is fine to link an LGPL statically into whatever software, but one needs to provide header files and linkable static objects (.a files) of the library to the user.

Yours,
Linus Walleij

#48 lore raw
Quoted 23 lines · Linus Walleij
Quoted 4 lines · Bartosz Golaszewski

One other thing is the license of the rust bindings themselves - I'm not a lawyer but it seems to me that if you link against LGPL code statically, your code must be licensed under an LGPL-compatible license.

Nope. The LGPL was created exactly for clarifying and avoiding that situation.

https://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License

It is a common misunderstanding that GPL overall has anything to do with whether you link things this or that way, the legal term used is "derivative work" and the meaning of that can only be determined in court. The meaning can depend on the intent of the author and misc legal ramifications.

In many ways LGPL is unnecessary, but it was created exactly to make non-legal people less weary about situations relating to linking of libraries.

Quoted 6 lines

It is fine to link an LGPL statically into whatever software, but one needs to provide header files and linkable static objects (.a files) of the library to the user.

Yours,
Linus Walleij

Thanks Linus! Makes perfect sense.

Bart