11#![ allow( dead_code) ]
22
33use std:: {
4+ borrow:: Cow ,
45 env, fs,
56 io:: { self , Read , Write } ,
67 path:: { Path , PathBuf } ,
8+ str:: FromStr ,
79} ;
810
911/// ONNX Runtime version
1012///
1113/// WARNING: If version is changed, bindings for all platforms will have to be re-generated.
1214/// To do so, run this:
1315/// cargo build --package onnxruntime-sys --features generate-bindings
14- const ORT_VERSION : & str = "1.7.0 " ;
16+ const ORT_VERSION : & str = "1.8.1 " ;
1517
1618/// Base Url from which to download pre-built releases/
1719const ORT_RELEASE_BASE_URL : & str = "https://github.com/microsoft/onnxruntime/releases/download" ;
@@ -63,14 +65,15 @@ fn generate_bindings(_include_dir: &Path) {
6365 println ! ( "Bindings not generated automatically, using committed files instead." ) ;
6466 println ! ( "Enable with the 'generate-bindings' cargo feature." ) ;
6567
66- let os = env:: var ( "CARGO_CFG_TARGET_OS" ) . expect ( "Unable to get TARGET_OS" ) ;
67- let arch = env:: var ( "CARGO_CFG_TARGET_ARCH" ) . expect ( "Unable to get TARGET_ARCH" ) ;
68- if os == "macos" && arch == "aarch64" {
69- panic ! (
70- "OnnxRuntime {} bindings for Apple M1 are not available" ,
71- ORT_VERSION
72- ) ;
73- }
68+ // NOTE: If bindings could not be be generated for Apple Sillicon M1, please uncomment the following
69+ // let os = env::var("CARGO_CFG_TARGET_OS").expect("Unable to get TARGET_OS");
70+ // let arch = env::var("CARGO_CFG_TARGET_ARCH").expect("Unable to get TARGET_ARCH");
71+ // if os == "macos" && arch == "aarch64" {
72+ // panic!(
73+ // "OnnxRuntime {} bindings for Apple M1 are not available",
74+ // ORT_VERSION
75+ // );
76+ // }
7477}
7578
7679#[ cfg( feature = "generate-bindings" ) ]
@@ -193,57 +196,180 @@ fn extract_zip(filename: &Path, outpath: &Path) {
193196 }
194197}
195198
196- fn prebuilt_archive_url ( ) -> ( PathBuf , String ) {
197- let os = env:: var ( "CARGO_CFG_TARGET_OS" ) . expect ( "Unable to get TARGET_OS" ) ;
198- let arch = env:: var ( "CARGO_CFG_TARGET_ARCH" ) . expect ( "Unable to get TARGET_ARCH" ) ;
199-
200- let gpu_str = match env:: var ( ORT_ENV_GPU ) {
201- Ok ( cuda_env) => match cuda_env. to_lowercase ( ) . as_str ( ) {
202- "1" | "yes" | "true" | "on" => match os. as_str ( ) {
203- "linux" | "windows" => "-gpu" ,
204- os_str => panic ! (
205- "Use of CUDA was specified with `{}` environment variable, but pre-built \
206- binaries with CUDA are only available for Linux and Windows, not: {}.",
207- ORT_ENV_GPU , os_str
208- ) ,
209- } ,
210- _ => "" ,
211- } ,
212- Err ( _) => "" ,
213- } ;
199+ trait OnnxPrebuiltArchive {
200+ fn as_onnx_str ( & self ) -> Cow < str > ;
201+ }
214202
215- let arch_str = match arch. as_str ( ) {
216- "x86_64" => "x64" ,
217- "x86" => "x86" ,
218- unsupported => panic ! ( "Unsupported architecture {:?}" , unsupported) ,
219- } ;
203+ #[ derive( Debug ) ]
204+ enum Architecture {
205+ X86 ,
206+ X86_64 ,
207+ Arm ,
208+ Arm64 ,
209+ }
220210
221- if arch. as_str ( ) == "x86" && os. as_str ( ) != "windows" {
222- panic ! (
223- "ONNX Runtime only supports x86 (i686) architecture on Windows (not {:?})." ,
224- os
225- ) ;
211+ impl FromStr for Architecture {
212+ type Err = String ;
213+
214+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
215+ match s. to_lowercase ( ) . as_str ( ) {
216+ "x86" => Ok ( Architecture :: X86 ) ,
217+ "x86_64" => Ok ( Architecture :: X86_64 ) ,
218+ "arm" => Ok ( Architecture :: Arm ) ,
219+ "aarch64" => Ok ( Architecture :: Arm64 ) ,
220+ _ => Err ( format ! ( "Unsupported architecture: {}" , s) ) ,
221+ }
226222 }
223+ }
227224
228- // Only Windows and Linux x64 support GPU
229- if !gpu_str. is_empty ( ) {
230- if arch_str == "x64" && ( os == "windows" || os == "linux" ) {
231- println ! ( "Supported GPU platform: {} {}" , os, arch_str) ;
232- } else {
233- panic ! ( "Unsupported GPU platform: {} {}" , os, arch_str) ;
225+ impl OnnxPrebuiltArchive for Architecture {
226+ fn as_onnx_str ( & self ) -> Cow < str > {
227+ match self {
228+ Architecture :: X86 => Cow :: from ( "x86" ) ,
229+ Architecture :: X86_64 => Cow :: from ( "x64" ) ,
230+ Architecture :: Arm => Cow :: from ( "arm" ) ,
231+ Architecture :: Arm64 => Cow :: from ( "arm64" ) ,
234232 }
235233 }
234+ }
236235
237- let ( os_str, archive_extension) = match os. as_str ( ) {
238- "windows" => ( "win" , "zip" ) ,
239- "macos" => ( "osx" , "tgz" ) ,
240- "linux" => ( "linux" , "tgz" ) ,
241- _ => panic ! ( "Unsupported target os {:?}" , os) ,
236+ #[ derive( Debug ) ]
237+ #[ allow( clippy:: enum_variant_names) ]
238+ enum Os {
239+ Windows ,
240+ Linux ,
241+ MacOs ,
242+ }
243+
244+ impl Os {
245+ fn archive_extension ( & self ) -> & ' static str {
246+ match self {
247+ Os :: Windows => "zip" ,
248+ Os :: Linux => "tgz" ,
249+ Os :: MacOs => "tgz" ,
250+ }
251+ }
252+ }
253+
254+ impl FromStr for Os {
255+ type Err = String ;
256+
257+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
258+ match s. to_lowercase ( ) . as_str ( ) {
259+ "windows" => Ok ( Os :: Windows ) ,
260+ "macos" => Ok ( Os :: MacOs ) ,
261+ "linux" => Ok ( Os :: Linux ) ,
262+ _ => Err ( format ! ( "Unsupported os: {}" , s) ) ,
263+ }
264+ }
265+ }
266+
267+ impl OnnxPrebuiltArchive for Os {
268+ fn as_onnx_str ( & self ) -> Cow < str > {
269+ match self {
270+ Os :: Windows => Cow :: from ( "win" ) ,
271+ Os :: Linux => Cow :: from ( "linux" ) ,
272+ Os :: MacOs => Cow :: from ( "osx" ) ,
273+ }
274+ }
275+ }
276+
277+ #[ derive( Debug ) ]
278+ enum Accelerator {
279+ None ,
280+ Gpu ,
281+ }
282+
283+ impl FromStr for Accelerator {
284+ type Err = String ;
285+
286+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
287+ match s. to_lowercase ( ) . as_str ( ) {
288+ "1" | "yes" | "true" | "on" => Ok ( Accelerator :: Gpu ) ,
289+ _ => Ok ( Accelerator :: None ) ,
290+ }
291+ }
292+ }
293+
294+ impl OnnxPrebuiltArchive for Accelerator {
295+ fn as_onnx_str ( & self ) -> Cow < str > {
296+ match self {
297+ Accelerator :: None => Cow :: from ( "" ) ,
298+ Accelerator :: Gpu => Cow :: from ( "gpu" ) ,
299+ }
300+ }
301+ }
302+
303+ #[ derive( Debug ) ]
304+ struct Triplet {
305+ os : Os ,
306+ arch : Architecture ,
307+ accelerator : Accelerator ,
308+ }
309+
310+ impl OnnxPrebuiltArchive for Triplet {
311+ fn as_onnx_str ( & self ) -> Cow < str > {
312+ match ( & self . os , & self . arch , & self . accelerator ) {
313+ // onnxruntime-win-x86-1.8.1.zip
314+ // onnxruntime-win-x64-1.8.1.zip
315+ // onnxruntime-win-arm-1.8.1.zip
316+ // onnxruntime-win-arm64-1.8.1.zip
317+ // onnxruntime-linux-x64-1.8.1.tgz
318+ // onnxruntime-osx-x64-1.8.1.tgz
319+ ( Os :: Windows , Architecture :: X86 , Accelerator :: None )
320+ | ( Os :: Windows , Architecture :: X86_64 , Accelerator :: None )
321+ | ( Os :: Windows , Architecture :: Arm , Accelerator :: None )
322+ | ( Os :: Windows , Architecture :: Arm64 , Accelerator :: None )
323+ | ( Os :: Linux , Architecture :: X86_64 , Accelerator :: None )
324+ | ( Os :: MacOs , Architecture :: X86_64 , Accelerator :: None ) => Cow :: from ( format ! (
325+ "{}-{}" ,
326+ self . os. as_onnx_str( ) ,
327+ self . arch. as_onnx_str( )
328+ ) ) ,
329+ // onnxruntime-win-gpu-x64-1.8.1.zip
330+ // Note how this one is inverted from the linux one next
331+ ( Os :: Windows , Architecture :: X86_64 , Accelerator :: Gpu ) => Cow :: from ( format ! (
332+ "{}-{}-{}" ,
333+ self . os. as_onnx_str( ) ,
334+ self . accelerator. as_onnx_str( ) ,
335+ self . arch. as_onnx_str( ) ,
336+ ) ) ,
337+ // onnxruntime-linux-x64-gpu-1.8.1.tgz
338+ // Note how this one is inverted from the windows one above
339+ ( Os :: Linux , Architecture :: X86_64 , Accelerator :: Gpu ) => Cow :: from ( format ! (
340+ "{}-{}-{}" ,
341+ self . os. as_onnx_str( ) ,
342+ self . arch. as_onnx_str( ) ,
343+ self . accelerator. as_onnx_str( ) ,
344+ ) ) ,
345+ _ => {
346+ panic ! (
347+ "Unsupported prebuilt triplet: {:?}, {:?}, {:?}. Please use {}=system and {}=/path/to/onnxruntime" ,
348+ self . os, self . arch, self . accelerator, ORT_ENV_STRATEGY , ORT_ENV_SYSTEM_LIB_LOCATION
349+ ) ;
350+ }
351+ }
352+ }
353+ }
354+
355+ fn prebuilt_archive_url ( ) -> ( PathBuf , String ) {
356+ let triplet = Triplet {
357+ os : env:: var ( "CARGO_CFG_TARGET_OS" )
358+ . expect ( "Unable to get TARGET_OS" )
359+ . parse ( )
360+ . unwrap ( ) ,
361+ arch : env:: var ( "CARGO_CFG_TARGET_ARCH" )
362+ . expect ( "Unable to get TARGET_ARCH" )
363+ . parse ( )
364+ . unwrap ( ) ,
365+ accelerator : env:: var ( ORT_ENV_GPU ) . unwrap_or_default ( ) . parse ( ) . unwrap ( ) ,
242366 } ;
243367
244368 let prebuilt_archive = format ! (
245- "onnxruntime-{}-{}{}-{}.{}" ,
246- os_str, arch_str, gpu_str, ORT_VERSION , archive_extension
369+ "onnxruntime-{}-{}.{}" ,
370+ triplet. as_onnx_str( ) ,
371+ ORT_VERSION ,
372+ triplet. os. archive_extension( )
247373 ) ;
248374 let prebuilt_url = format ! (
249375 "{}/v{}/{}" ,
@@ -260,6 +386,8 @@ fn prepare_libort_dir_prebuilt() -> PathBuf {
260386 let extract_dir = out_dir. join ( ORT_PREBUILT_EXTRACT_DIR ) ;
261387 let downloaded_file = out_dir. join ( & prebuilt_archive) ;
262388
389+ println ! ( "cargo:rerun-if-changed={}" , downloaded_file. display( ) ) ;
390+
263391 if !downloaded_file. exists ( ) {
264392 println ! ( "Creating directory {:?}" , out_dir) ;
265393 fs:: create_dir_all ( & out_dir) . unwrap ( ) ;
0 commit comments