Skip to content

Commit 2195648

Browse files
authored
Merge pull request #31 from nbigaouette/split-autogenerated
Refactor build script (and feature flags)
2 parents 7de15a0 + cee42bd commit 2195648

File tree

8 files changed

+149
-59
lines changed

8 files changed

+149
-59
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12-
- Update ONNX Runtime to 1.5.2 from 1.4.0 ([#30](https://github.com/nbigaouette/onnxruntime-rs/pull/30))
12+
- Update ONNX Runtime to 1.5.2 from 1.4.0 ([#30](https://github.com/nbigaouette/onnxruntime-rs/pull/30))
13+
- Refactor feature flags and how bindings are generated ([#31](https://github.com/nbigaouette/onnxruntime-rs/pull/31))
1314

1415
## [0.0.9] - 2020-10-13
1516

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,18 @@ Dropping the environment.
157157
See also the integration tests ([`onnxruntime/tests/integration_tests.rs`](onnxruntime/tests/integration_tests.rs))
158158
that performs simple model download and inference, validating the results.
159159

160+
## Bindings Generation
161+
162+
Bindings (the basis of `onnxruntime-sys`) are committed to the git repository. This means `bindgen` is not
163+
a dependency anymore on every build (it was made optional) and thus build times are better.
164+
165+
To generate new bindings (for example if they don't exists for your platform or if a version bump occurred), run the
166+
following on all platforms and commit the changes:
167+
168+
```sh
169+
cargo build --package onnxruntime-sys --features generate-bindings
170+
```
171+
160172
## Conduct
161173

162174
The [Rust Code of Conduct](https://www.rust-lang.org/conduct.html) shall be respected. For

onnxruntime-sys/Cargo.toml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
authors = ["Nicolas Bigaouette <[email protected]>"]
33
edition = "2018"
44
name = "onnxruntime-sys"
5-
version = "0.0.9"
5+
version = "0.0.10"
66

77
description = "Unsafe wrapper around Microsoft's ONNX Runtime"
88
documentation = "https://docs.rs/onnxruntime-sys"
@@ -17,7 +17,7 @@ keywords = ["neuralnetworks", "onnx", "bindings"]
1717
[dependencies]
1818

1919
[build-dependencies]
20-
bindgen = "0.55"
20+
bindgen = {version = "0.55", optional = true}
2121
ureq = "1.5.1"
2222

2323
[target.'cfg(windows)'.build-dependencies]
@@ -28,8 +28,14 @@ flate2 = "1.0"
2828
tar = "0.4"
2929

3030
[features]
31-
# Disable build script; used by https://docs.rs
32-
disable-bindgen = []
31+
default = []
32+
33+
# Disable build script, used to prevent issues with docs.rs
34+
disable-sys-build-script = []
35+
# Use bindgen to generate bindings in build.rs
36+
generate-bindings = ["bindgen"]
3337

3438
[package.metadata.docs.rs]
35-
features = ["disable-bindgen"]
39+
# Disable the build.rs on https://docs.rs since it can cause
40+
# issue there and it's not needed.
41+
features = ["disable-sys-build-script"]

onnxruntime-sys/build.rs

Lines changed: 114 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
#![allow(dead_code)]
2+
13
use io::Write;
24
use std::{
35
env, fs,
4-
io::{self, Read},
6+
io::{self, BufWriter, Read},
57
path::{Path, PathBuf},
68
};
79

810
/// ONNX Runtime version
11+
///
12+
/// WARNING: If version is changed, bindings for all platforms will have to be re-generated.
13+
/// To do so, run this:
14+
/// cargo build --package onnxruntime-sys --features generate-bindings
915
const ORT_VERSION: &str = "1.5.2";
1016

1117
/// Base Url from which to download pre-built releases/
@@ -27,53 +33,113 @@ const ORT_ENV_GPU: &str = "ORT_USE_CUDA";
2733
/// Subdirectory (of the 'target' directory) into which to extract the prebuilt library.
2834
const ORT_PREBUILT_EXTRACT_DIR: &str = "onnxruntime";
2935

36+
#[cfg(feature = "disable-sys-build-script")]
3037
fn main() {
31-
if !cfg!(feature = "disable-bindgen") {
32-
let libort_install_dir = prepare_libort_dir();
33-
34-
let lib_dir = libort_install_dir.join("lib");
35-
let include_dir = libort_install_dir.join("include");
36-
let clang_arg = format!("-I{}", include_dir.display());
37-
38-
println!("Include directory: {:?}", include_dir);
39-
println!("Lib directory: {:?}", lib_dir);
40-
41-
// Tell cargo to tell rustc to link onnxruntime shared library.
42-
println!("cargo:rustc-link-lib=onnxruntime");
43-
println!("cargo:rustc-link-search=native={}", lib_dir.display());
44-
45-
// Tell cargo to invalidate the built crate whenever the wrapper changes
46-
println!("cargo:rerun-if-changed=wrapper.h");
47-
48-
println!("cargo:rerun-if-env-changed={}", ORT_ENV_STRATEGY);
49-
println!("cargo:rerun-if-env-changed={}", ORT_ENV_GPU);
50-
println!("cargo:rerun-if-env-changed={}", ORT_ENV_SYSTEM_LIB_LOCATION);
51-
52-
// The bindgen::Builder is the main entry point
53-
// to bindgen, and lets you build up options for
54-
// the resulting bindings.
55-
let bindings = bindgen::Builder::default()
56-
// The input header we would like to generate
57-
// bindings for.
58-
.header("wrapper.h")
59-
// The current working directory is 'onnxruntime-sys'
60-
.clang_arg(clang_arg)
61-
// Tell cargo to invalidate the built crate whenever any of the
62-
// included header files changed.
63-
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
64-
// Finish the builder and generate the bindings.
65-
.generate()
66-
// Unwrap the Result and panic on failure.
67-
.expect("Unable to generate bindings");
68-
69-
// Write the bindings to (source controlled) src/generated/bindings.rs
70-
let out_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
71-
.join("src")
72-
.join("generated");
73-
bindings
74-
.write_to_file(out_path.join("bindings.rs"))
75-
.expect("Couldn't write bindings!");
76-
}
38+
println!("Build script disabled!");
39+
40+
generate_file_including_platform_bindings().unwrap();
41+
}
42+
43+
#[cfg(not(feature = "disable-sys-build-script"))]
44+
fn main() {
45+
let libort_install_dir = prepare_libort_dir();
46+
47+
let include_dir = libort_install_dir.join("include");
48+
let lib_dir = libort_install_dir.join("lib");
49+
50+
println!("Include directory: {:?}", include_dir);
51+
println!("Lib directory: {:?}", lib_dir);
52+
53+
// Tell cargo to tell rustc to link onnxruntime shared library.
54+
println!("cargo:rustc-link-lib=onnxruntime");
55+
println!("cargo:rustc-link-search=native={}", lib_dir.display());
56+
57+
println!("cargo:rerun-if-env-changed={}", ORT_ENV_STRATEGY);
58+
println!("cargo:rerun-if-env-changed={}", ORT_ENV_GPU);
59+
println!("cargo:rerun-if-env-changed={}", ORT_ENV_SYSTEM_LIB_LOCATION);
60+
61+
generate_bindings(&include_dir);
62+
63+
generate_file_including_platform_bindings().unwrap();
64+
}
65+
66+
#[cfg(not(feature = "generate-bindings"))]
67+
fn generate_bindings(_include_dir: &Path) {
68+
println!("Bindings not generated automatically, using committed files instead.");
69+
println!("Enable with the 'bindgen' cargo feature.");
70+
}
71+
72+
#[cfg(feature = "generate-bindings")]
73+
fn generate_bindings(include_dir: &Path) {
74+
let clang_arg = format!("-I{}", include_dir.display());
75+
76+
// Tell cargo to invalidate the built crate whenever the wrapper changes
77+
println!("cargo:rerun-if-changed=wrapper.h");
78+
79+
// The bindgen::Builder is the main entry point
80+
// to bindgen, and lets you build up options for
81+
// the resulting bindings.
82+
let bindings = bindgen::Builder::default()
83+
// The input header we would like to generate
84+
// bindings for.
85+
.header("wrapper.h")
86+
// The current working directory is 'onnxruntime-sys'
87+
.clang_arg(clang_arg)
88+
// Tell cargo to invalidate the built crate whenever any of the
89+
// included header files changed.
90+
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
91+
// Finish the builder and generate the bindings.
92+
.generate()
93+
// Unwrap the Result and panic on failure.
94+
.expect("Unable to generate bindings");
95+
96+
// Write the bindings to (source controlled) src/generated/<os>/<arch>/bindings.rs
97+
let generated_file = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
98+
.join("src")
99+
.join("generated")
100+
.join(env::var("CARGO_CFG_TARGET_OS").unwrap())
101+
.join(env::var("CARGO_CFG_TARGET_ARCH").unwrap())
102+
.join("bindings.rs");
103+
bindings
104+
.write_to_file(&generated_file)
105+
.expect("Couldn't write bindings!");
106+
}
107+
108+
fn generate_file_including_platform_bindings() -> Result<(), std::io::Error> {
109+
let generic_binding_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
110+
.join("src")
111+
.join("generated")
112+
.join("bindings.rs");
113+
114+
let mut fh = BufWriter::new(fs::File::create(&generic_binding_path)?);
115+
116+
let platform_bindings = PathBuf::from("src")
117+
.join("generated")
118+
.join(env::var("CARGO_CFG_TARGET_OS").unwrap())
119+
.join(env::var("CARGO_CFG_TARGET_ARCH").unwrap())
120+
.join("bindings.rs");
121+
122+
// Build a (relative) path, as a string, to the platform-specific bindings.
123+
// Required so that we can escape backslash (Windows path separators) before
124+
// writing to the file.
125+
let include_path = format!(
126+
"{}{}",
127+
std::path::MAIN_SEPARATOR,
128+
platform_bindings.display()
129+
)
130+
.replace(r#"\"#, r#"\\"#);
131+
fh.write_all(
132+
format!(
133+
r#"include!(concat!(
134+
env!("CARGO_MANIFEST_DIR"),
135+
"{}"
136+
));"#,
137+
include_path
138+
)
139+
.as_bytes(),
140+
)?;
141+
142+
Ok(())
77143
}
78144

79145
fn download<P: AsRef<Path>>(source_url: &str, target_file: P) {
@@ -125,7 +191,7 @@ fn extract_zip(filename: &Path, outpath: &Path) {
125191
let mut archive = zip::ZipArchive::new(buf).unwrap();
126192
for i in 0..archive.len() {
127193
let mut file = archive.by_index(i).unwrap();
128-
let outpath = outpath.as_ref().join(file.sanitized_name());
194+
let outpath = outpath.join(file.sanitized_name());
129195
if !(&*file.name()).ends_with('/') {
130196
println!(
131197
"File {} extracted to \"{}\" ({} bytes)",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bindings.rs

onnxruntime-sys/src/generated/linux/x86_64/bindings.rs

Lines changed: 3 additions & 0 deletions
Large diffs are not rendered by default.

onnxruntime/Cargo.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
authors = ["Nicolas Bigaouette <[email protected]>"]
33
edition = "2018"
44
name = "onnxruntime"
5-
version = "0.0.9"
5+
version = "0.0.10"
66

77
description = "Wrapper around Microsoft's ONNX Runtime"
88
documentation = "https://docs.rs/onnxruntime"
@@ -19,7 +19,7 @@ name = "integration_tests"
1919
required-features = ["model-fetching"]
2020

2121
[dependencies]
22-
onnxruntime-sys = {version = "0.0.9", path = "../onnxruntime-sys"}
22+
onnxruntime-sys = {version = "0.0.10", path = "../onnxruntime-sys"}
2323

2424
lazy_static = "1.4"
2525
ndarray = "0.13"
@@ -38,8 +38,9 @@ ureq = "1.5.1"
3838
[features]
3939
# Fetch model from ONNX Model Zoo (https://github.com/onnx/models)
4040
model-fetching = ["ureq"]
41-
# Disable build script; used by https://docs.rs
42-
disable-bindgen = ["onnxruntime-sys/disable-bindgen"]
41+
# Disable build script; used for https://docs.rs
42+
disable-sys-build-script = ["onnxruntime-sys/disable-sys-build-script"]
43+
generate-bindings = ["onnxruntime-sys/generate-bindings"]
4344

4445
[package.metadata.docs.rs]
45-
features = ["disable-bindgen", "model-fetching"]
46+
features = ["disable-sys-build-script", "model-fetching"]

0 commit comments

Comments
 (0)