From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: getelson@nvidia.com, Bruce Richardson <bruce.richardson@intel.com>
Subject: [RFC PATCH] add rust binding support to DPDK
Date: Tue, 8 Apr 2025 15:58:38 +0100 [thread overview]
Message-ID: <20250408145838.2501034-1-bruce.richardson@intel.com> (raw)
In-Reply-To: <20250306133713.393057-1-getelson@nvidia.com>
Add a Cargo.toml file in the root folder and a number of other scripts
and rust-related files into buildtools/rust, which then enables DPDK to
be cloned and built as a rust crate - all-be-it one with only two
functions: rte_eal_init and rte_eal_cleanup.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
This RFC is proposed as an alternative approach to enabling rust support
in DPDK. The key difference vs previous is that we are taking the whole
DPDK project here as a rust "crate", which can then be used by other
higher-level crates as a dependency. Building the crate does a
(minimal) build of DPDK and statically links it in, so there is no
"install" step or anything needed - the Rust app just adds DPDK to their
Cargo.toml file and then should have everything they need.
---
Cargo.toml | 16 +++++++
buildtools/meson.build | 1 +
buildtools/rust/build.rs | 45 ++++++++++++++++++++
buildtools/rust/gen-cargo-bindgen-info.py | 52 +++++++++++++++++++++++
buildtools/rust/lib.rs | 25 +++++++++++
buildtools/rust/wrapper.h | 5 +++
meson.build | 3 ++
7 files changed, 147 insertions(+)
create mode 100644 Cargo.toml
create mode 100644 buildtools/rust/build.rs
create mode 100644 buildtools/rust/gen-cargo-bindgen-info.py
create mode 100644 buildtools/rust/lib.rs
create mode 100644 buildtools/rust/wrapper.h
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000000..fe0843975a
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2025 Intel Corporation
+
+[package]
+name = "dpdk-c"
+version = "25.0.7"
+build = "buildtools/rust/build.rs"
+edition = "2021"
+
+[lib]
+path = "buildtools/rust/lib.rs"
+doctest = false
+
+[build-dependencies]
+bindgen = "0.71"
+meson-next = "1"
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 4e2c1217a2..a13b5189c1 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -26,6 +26,7 @@ header_gen_cmd = py3 + files('gen-header.py')
has_hugepages_cmd = py3 + files('has-hugepages.py')
cmdline_gen_cmd = py3 + files('dpdk-cmdline-gen.py')
check_dts_requirements = py3 + files('check-dts-requirements.py')
+gen_cargo_bindgen_info = py3 + files('rust/gen-cargo-bindgen-info.py')
# install any build tools that end-users might want also
install_data([
diff --git a/buildtools/rust/build.rs b/buildtools/rust/build.rs
new file mode 100644
index 0000000000..1ffdf03d2f
--- /dev/null
+++ b/buildtools/rust/build.rs
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2025 Intel Corporation
+ */
+
+extern crate meson_next as meson;
+use std::collections::HashMap;
+use std::env;
+use std::path::PathBuf;
+
+fn main() {
+ let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
+ let build_dir = out_path.join("build");
+
+ let meson_cfg = meson::Config::new().options(HashMap::from([
+ ("enable_libs", "eal"),
+ ("enable_drivers", "net/*,net/intel/*"),
+ ("enable_apps", "test")
+ ]));
+ meson::build(".", build_dir.to_str().unwrap(), meson_cfg);
+
+ /* open and print file 'cargo_rules.txt' from build_dir */
+ let cargo_ldflags_file = build_dir.join("cargo_ldflags.txt");
+ println!("cargo:rerun-if-changed={}", cargo_ldflags_file.display());
+ print!("{}", std::fs::read_to_string(cargo_ldflags_file).unwrap());
+
+ let bindgen_include_file = build_dir.join("bindgen_cflags.txt");
+ let mut bindings = bindgen::Builder::default();
+ for line in std::fs::read_to_string(bindgen_include_file).unwrap().lines() {
+ bindings = bindings.clang_arg(line);
+ }
+
+ let bindings = bindings.header("buildtools/rust/wrapper.h")
+ .derive_default(true)
+ .allowlist_function("rte_eal_init")
+ .allowlist_function("rte_eal_cleanup")
+ // Tell cargo to invalidate the built crate whenever any of the
+ // included header files changed.
+ .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
+ .generate()
+ .expect("Unable to generate bindings");
+
+ bindings
+ .write_to_file(out_path.join("bindings.rs"))
+ .expect("Couldn't write bindings!");
+}
diff --git a/buildtools/rust/gen-cargo-bindgen-info.py b/buildtools/rust/gen-cargo-bindgen-info.py
new file mode 100644
index 0000000000..bea432ead3
--- /dev/null
+++ b/buildtools/rust/gen-cargo-bindgen-info.py
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2025 Intel Corporation
+
+# Script to generate cargo rules for static linking in rust builds
+# outputs one line per library, for drivers and libraries
+
+import os
+import os.path
+import sys
+import subprocess
+
+if 'MESON_BUILD_ROOT' not in os.environ:
+ print('This script must be called from a meson build environment')
+ sys.exit(1)
+
+pkgconf = sys.argv[1]
+os.environ['PKG_CONFIG_PATH'] = os.path.join(os.environ['MESON_BUILD_ROOT'], 'meson-uninstalled')
+linker_flags = subprocess.check_output([pkgconf, '--libs', '--static', 'libdpdk']).decode('utf-8')
+cflags = subprocess.check_output([pkgconf, '--cflags', 'libdpdk']).decode('utf-8')
+
+whole_archive = False
+with open(os.path.join(os.environ['MESON_BUILD_ROOT'], 'cargo_ldflags.txt'), 'w') as dst:
+ for flag in linker_flags.split():
+ if flag == '-pthread':
+ continue
+ elif flag == '-Wl,--whole-archive':
+ whole_archive = True
+ elif flag == '-Wl,--no-whole-archive':
+ whole_archive = False
+ elif flag.startswith('-L'):
+ dst.write(f'cargo:rustc-link-search=native={flag[2:]}\n')
+ elif flag.startswith('-l:'):
+ libname = flag[3:]
+ if libname.startswith('lib'):
+ libname = libname[3:]
+ if libname.endswith('.a'):
+ libname = libname[:-2]
+ if whole_archive:
+ dst.write(f'cargo:rustc-link-lib=static:+whole-archive={libname}\n')
+ else:
+ dst.write(f'cargo:rustc-link-lib=static={libname}\n')
+ elif flag.startswith('-lrte_'):
+ # skip any other DPDK lib flags, we already have them above
+ continue
+ elif flag.startswith('-l'):
+ dst.write(f'cargo:rustc-link-lib={flag[2:]}\n')
+ else:
+ print(f'Warning: Unknown flag: {flag}', file=sys.stderr)
+
+with open(os.path.join(os.environ['MESON_BUILD_ROOT'], 'bindgen_cflags.txt'), 'w') as dst:
+ for flag in cflags.split():
+ dst.write(f'{flag}\n')
diff --git a/buildtools/rust/lib.rs b/buildtools/rust/lib.rs
new file mode 100644
index 0000000000..f99c54ac42
--- /dev/null
+++ b/buildtools/rust/lib.rs
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2025 Intel Corporation
+ */
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_helloworld() {
+ let appname = std::ffi::CString::new("test-rs").unwrap();
+ let mut argv = [appname.into_raw()];
+ let ret = unsafe {
+ rte_eal_init(argv.len().try_into().unwrap(), argv.as_mut_ptr())
+ };
+ assert!(ret >= 0, "rte_eal_init failed");
+ unsafe { rte_eal_cleanup() };
+ }
+}
diff --git a/buildtools/rust/wrapper.h b/buildtools/rust/wrapper.h
new file mode 100644
index 0000000000..25f5bf94e2
--- /dev/null
+++ b/buildtools/rust/wrapper.h
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2025 Intel Corporation
+ */
+
+#include <rte_eal.h>
diff --git a/meson.build b/meson.build
index 8436d1dff8..72c82178e1 100644
--- a/meson.build
+++ b/meson.build
@@ -114,6 +114,9 @@ configure_file(output: build_cfg,
# build pkg-config files for dpdk
subdir('buildtools/pkg-config')
+# output a list of cargo parameters if DPDK is being built for rust use
+run_command([gen_cargo_bindgen_info, pkgconf], check: true)
+
if meson.is_subproject()
subdir('buildtools/subproject')
endif
--
2.45.2
next prev parent reply other threads:[~2025-04-08 14:58 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-06 13:37 [PATCH] rust: support DPDK API Gregory Etelson
2025-03-06 19:26 ` Van Haaren, Harry
2025-03-07 16:56 ` Etelson, Gregory
2025-03-07 15:54 ` Van Haaren, Harry
2025-03-07 16:20 ` Bruce Richardson
2025-03-07 18:15 ` Etelson, Gregory
2025-03-07 18:00 ` Etelson, Gregory
2025-03-08 14:28 ` Igor Gutorov
2025-03-08 19:14 ` Etelson, Gregory
2025-03-10 15:31 ` Stephen Hemminger
2025-03-12 5:21 ` Etelson, Gregory
2025-03-08 18:50 ` [PATCH v2] rust: support raw " Gregory Etelson
2025-03-10 16:13 ` Van Haaren, Harry
2025-03-10 16:25 ` Bruce Richardson
2025-03-12 17:19 ` Thomas Monjalon
2025-03-14 19:12 ` Etelson, Gregory
2025-03-10 15:00 ` [PATCH] rust: support " Stephen Hemminger
2025-03-12 5:12 ` Etelson, Gregory
2025-03-10 16:18 ` Stephen Hemminger
2025-03-10 16:30 ` Bruce Richardson
2025-03-12 14:30 ` Etelson, Gregory
2025-03-13 7:56 ` Igor Gutorov
2025-03-12 15:29 ` Igor Gutorov
2025-03-12 17:24 ` Thomas Monjalon
2025-03-14 18:38 ` [PATCH v3] rust: support raw " Gregory Etelson
2025-03-18 8:51 ` Dariusz Sosnowski
2025-03-18 9:12 ` Dariusz Sosnowski
2025-03-22 10:59 ` [PATCH v4] " Gregory Etelson
2025-03-22 17:39 ` Bruce Richardson
2025-03-27 5:51 ` Etelson, Gregory
2025-03-27 16:22 ` Bruce Richardson
2025-03-28 18:30 ` Etelson, Gregory
2025-03-27 8:23 ` DPDK for rust Morten Brørup
2025-03-27 9:00 ` Etelson, Gregory
2025-03-27 16:17 ` Bruce Richardson
2025-03-28 18:09 ` Etelson, Gregory
2025-03-28 19:25 ` Stephen Hemminger
2025-03-31 9:11 ` Bruce Richardson
2025-03-31 10:26 ` Luca Boccassi
2025-04-01 13:08 ` Etelson, Gregory
2025-03-31 9:03 ` Thomas Monjalon
2025-03-31 9:10 ` Bruce Richardson
2025-04-08 14:58 ` Bruce Richardson [this message]
2025-04-08 15:05 ` [RFC PATCH] add rust binding support to DPDK Bruce Richardson
2025-04-10 5:28 ` Etelson, Gregory
2025-04-11 13:13 ` Van Haaren, Harry
2025-04-11 15:39 ` Etelson, Gregory
2025-04-11 16:22 ` Van Haaren, Harry
2025-04-13 8:07 ` Etelson, Gregory
2025-04-13 17:09 ` Owen Hilyard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250408145838.2501034-1-bruce.richardson@intel.com \
--to=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=getelson@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).