Skip to content

Commit

Permalink
first step to runtime onnx shared library loading support
Browse files Browse the repository at this point in the history
change absolutely path
concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/src/generated/****"
)
to relative because full paths break Clion rust analyser
  • Loading branch information
chertov committed Feb 26, 2021
1 parent 3b5fcd3 commit b94870f
Show file tree
Hide file tree
Showing 12 changed files with 17,093 additions and 63 deletions.
10 changes: 9 additions & 1 deletion onnxruntime-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ repository = "https://github.com/nbigaouette/onnxruntime-rs"
categories = ["science"]
keywords = ["neuralnetworks", "onnx", "bindings"]

[[example]]
name = "c_api_sample"
# try to use "dynamic-loading" feature to load custom ONNX shared library at runtime
# required-features = ["dynamic-loading"]

[dependencies]
libloading = {version = "0.7", optional = true}

[build-dependencies]
bindgen = {version = "0.55", optional = true}
bindgen = {version = "0.57", optional = true}
ureq = "1.5.1"

# Used on Windows
Expand All @@ -34,6 +40,8 @@ default = []
disable-sys-build-script = []
# Use bindgen to generate bindings in build.rs
generate-bindings = ["bindgen"]
# Use dynamic library loading for onnx runtime
dynamic-loading = ["libloading"]

[package.metadata.docs.rs]
# Disable the build.rs on https://docs.rs since it can cause
Expand Down
46 changes: 32 additions & 14 deletions onnxruntime-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,50 +55,68 @@ fn main() {
println!("cargo:rerun-if-env-changed={}", ORT_ENV_GPU);
println!("cargo:rerun-if-env-changed={}", ORT_ENV_SYSTEM_LIB_LOCATION);

generate_bindings(&include_dir);
generate_bindings(&include_dir, false);
generate_bindings(&include_dir, true);
}

#[cfg(not(feature = "generate-bindings"))]
fn generate_bindings(_include_dir: &Path) {
fn generate_bindings(_include_dir: &Path, _dynamic_loading: bool) {
println!("Bindings not generated automatically, using committed files instead.");
println!("Enable with the 'bindgen' cargo feature.");
}

#[cfg(feature = "generate-bindings")]
fn generate_bindings(include_dir: &Path) {
let clang_arg = format!("-I{}", include_dir.display());
fn generate_bindings(onnxruntime_include_dir: &Path, dynamic_loading: bool) {

// Tell cargo to invalidate the built crate whenever the wrapper changes
println!("cargo:rerun-if-changed=wrapper.h");
println!("cargo:rerun-if-changed=src/generated/bindings.rs");

let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();

let mut clang_args = vec![];
clang_args.push(format!("-I{}", onnxruntime_include_dir.display()));
clang_args.push(format!("-I{}/onnxruntime/core/session", onnxruntime_include_dir.display()));
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
let builder = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("wrapper.h")
// The current working directory is 'onnxruntime-sys'
.clang_arg(clang_arg)
.clang_args(clang_args)

// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
// Format using rustfmt
.rustfmt_bindings(true)
.rustified_enum("*")
// Finish the builder and generate the bindings.
.generate()
.rustified_enum("*");

let builder = match dynamic_loading {
true => builder.dynamic_library_name("OnnxRuntime"),
false => builder
};

// Finish the builder and generate the bindings.
let bindings = builder.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");

// Write the bindings to (source controlled) src/generated/<os>/<arch>/bindings.rs
let generated_file = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
// Write the bindings to (source controlled) src/generated/<os>/<arch>/bindings_<dynamic>.rs
let generated_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
.join("src")
.join("generated")
.join(env::var("CARGO_CFG_TARGET_OS").unwrap())
.join(env::var("CARGO_CFG_TARGET_ARCH").unwrap())
.join("bindings.rs");
.join(target_os)
.join(target_arch);
std::fs::create_dir_all(&generated_dir).unwrap();
let generated_file = generated_dir.join(match dynamic_loading {
true => "bindings_dynamic.rs",
false => "bindings.rs"
});

println!("cargo:rerun-if-changed={:?}", generated_file);
bindings
.write_to_file(&generated_file)
Expand Down
16 changes: 15 additions & 1 deletion onnxruntime-sys/examples/c_api_sample.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![feature(stmt_expr_attributes)]
#![allow(non_snake_case)]

#[cfg(not(target_family = "windows"))]
Expand All @@ -10,7 +11,20 @@ use onnxruntime_sys::*;
// https://github.com/microsoft/onnxruntime/blob/v1.4.0/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests.Capi/C_Api_Sample.cpp

fn main() {
let g_ort = unsafe { OrtGetApiBase().as_ref().unwrap().GetApi.unwrap()(ORT_API_VERSION) };
let ort_api_base;
#[cfg(feature = "dynamic-loading")] {
// your shared ONNX runtime library
// for example on macos full path to library: ~/dev/onnxruntime/build/MacOS/RelWithDebInfo/libonnxruntime.1.7.0.dylib
let onnxruntime_path = "libonnxruntime.so";
let onnxruntime = unsafe { onnxruntime_sys::OnnxRuntime::new(onnxruntime_path) }.unwrap();
ort_api_base = unsafe { onnxruntime.OrtGetApiBase() };
}
#[cfg(not(feature = "dynamic-loading"))] {
ort_api_base = unsafe { OrtGetApiBase() };
}

let g_ort = unsafe { ort_api_base.as_ref().unwrap().GetApi.unwrap()(ORT_API_VERSION) };

assert_ne!(g_ort, std::ptr::null_mut());

//*************************************************************************
Expand Down
7 changes: 2 additions & 5 deletions onnxruntime-sys/src/generated/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ include!(concat!(
"/src/generated/linux/x86_64/bindings.rs"
));

#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
include!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/src/generated/macos/x86_64/bindings.rs"
));
#[cfg(all(target_os = "macos"))]
include!("./macos/bindings.rs");

#[cfg(all(target_os = "windows", target_arch = "x86"))]
include!(concat!(
Expand Down
7 changes: 7 additions & 0 deletions onnxruntime-sys/src/generated/macos/bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[cfg(not(feature = "dynamic-loading"))]
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
include!("./x86_64/bindings.rs");

#[cfg(feature = "dynamic-loading")]
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
include!("./x86_64/bindings_dynamic.rs");
Loading

0 comments on commit b94870f

Please sign in to comment.