Follow "A little C with your Rust" [1].
Set up cargo and main.rs skeleton and call one of the simplest possible
functions from libmount: mnt_get_fstab_path().
Use bindgen [1] to translate libmount's header file into a Rust
interface. This requires a few hacks:
- bindgen does not accept the original header right away, as it can't
find stdarg.h. Avoid this by dropping the (unnecessary) stdio.h
include.
- bindgen does not know about `size_t`. Hack around that with a typedef
for now.
- Suppress warnings about constant/identifier naming.
[1] https://rust-lang.github.io/rust-bindgen/command-line-usage.html
[2] https://docs.rust-embedded.org/book/interoperability/c-with-rust.html
--- /dev/null
+[build]
+rustflags = "-C link-args=-lmount"
--- /dev/null
+[package]
+name = "learning-c-from-rust"
+version = "0.1.0"
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
CFLAGS += $(shell pkg-config --cflags mount)
LIBMOUNT = $(shell pkg-config --libs mount)
CFLAGS += $(shell pkg-config --cflags mount)
LIBMOUNT = $(shell pkg-config --libs mount)
-all: c-mounts c-langinfo
+all: c-mounts c-langinfo target/debug/learning-c-from-rust
c-mounts: c-mounts.o
$(CC) -Wall -o $@ $^ $(LIBMOUNT)
c-mounts: c-mounts.o
$(CC) -Wall -o $@ $^ $(LIBMOUNT)
c-langinfo: c-langinfo.o
$(CC) -Wall -o $@ $^
c-langinfo: c-langinfo.o
$(CC) -Wall -o $@ $^
+# HACK: does not find stdarg.h (through stdio.h), missing size_t
+# also avoid hundreds of "should have an upper camel case name" warnings
+src/libmount.rs:
+ sed 's/#include.*stdio.h.*/typedef unsigned long size_t;/' /usr/include/libmount/libmount.h > libmount-hack.h
+ bindgen libmount-hack.h -- -I/usr/include/linux/ > $@.tmp
+ (echo '#![allow(non_camel_case_types,non_upper_case_globals,dead_code)]'; cat $@.tmp) > $@
+ rm libmount-hack.h $@.tmp
+
+target/debug/learning-c-from-rust: src/libmount.rs src/main.rs
+ cargo build
+
- rm -f c-mounts c-langinfo *.o
+ rm -f c-mounts c-langinfo *.o src/libmount.rs
run: all
LANG=en_US.UTF-8 ./c-langinfo
LANG=en_GB.UTF-8 ./c-langinfo
LANG=en_IE.UTF-8 ./c-langinfo
./c-mounts
run: all
LANG=en_US.UTF-8 ./c-langinfo
LANG=en_GB.UTF-8 ./c-langinfo
LANG=en_IE.UTF-8 ./c-langinfo
./c-mounts
+ target/debug/learning-c-from-rust
--- /dev/null
+mod libmount;
+
+use std::ffi::CStr;
+
+fn main() {
+ let fstab_path_cstr: &CStr = unsafe { CStr::from_ptr (libmount::mnt_get_fstab_path()) };
+ println!("fstab path C-String: {:?}", fstab_path_cstr);
+ let fstab_path = fstab_path_cstr.to_str().unwrap(); // may cause UTF-8 decoding error
+ println!("fstab path str: {}", fstab_path);
+}