From 98dcc5bc886f0850a8ec787cab6edfbc0f78a2a0 Mon Sep 17 00:00:00 2001 From: Andrew Gaspar Date: Tue, 4 Dec 2018 23:20:30 -0700 Subject: [PATCH 1/3] Adds code to build script to search the standard Windows environment variable CUDA_PATH when CUDA_LIBRARY_PATH is not set --- build.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/build.rs b/build.rs index 659c7a8..4a97162 100644 --- a/build.rs +++ b/build.rs @@ -1,13 +1,79 @@ use std::env; fn find_library_paths() -> Vec { - match env::var("CUDA_LIBRARY_PATH") { - Ok(path) => { - let split_char = if cfg!(target_os = "windows") { ";" } else { ":" }; + if let Ok(path) = env::var("CUDA_LIBRARY_PATH") { + // The location of the libcuda, libcudart, and libcublas can be hardcoded with the + // CUDA_LIBRARY_PATH environment variable. + let split_char = if cfg!(target_os = "windows") { + ";" + } else { + ":" + }; - path.split(split_char).map(|s| s.to_owned()).collect::>() + path.split(split_char) + .map(|s| s.to_owned()) + .collect::>() + } else if let Ok(path) = env::var("CUDA_PATH") { + // If CUDA_LIBRARY_PATH is not found, then CUDA_PATH will be used when building for Windows + // to locate the Cuda installation. Cuda installs the full Cuda SDK for 64-bit, but only + // a limited set of libraries for 32-bit. Namely, it does not include cublas in 32-bit, + // which cuda-sys requires. + + // 'path' points to the base of the CUDA Installation. The lib directory is a sub-directory. + let path = std::path::Path::new(&path); + + // To do this the right way, we check to see which target we're building for. + let target = env::var("TARGET") + .expect("cargo did not set the TARGET environment variable as required."); + + // Targets use '-' separators. e.g. x86_64-pc-windows-msvc + let target_components: Vec<_> = target.as_str().split("-").collect(); + + // We check that we're building for Windows. This code assumes that the layout in CUDA_PATH + // matches Windows. + if target_components[2] != "windows" { + println!( + "INFO: The CUDA_PATH variable is only used by cuda-sys on Windows. Your target is \ + {}.", + target + ); + return vec![]; } - Err(_) => vec![], + + // Sanity check that the second component of 'target' is "pc" + debug_assert_eq!( + "pc", target_components[1], + "Expected a Windows target to have the second component be 'pc'. Target: {}", + target + ); + + // x86_64 should use the libs in the "lib/x64" directory. If we ever support i686 (which + // does not ship with cublas support), its libraries are in "lib/Win32". + let lib_path = match target_components[0] { + "x86_64" => "x64", + "i686" => { + // lib path would be "Win32" if we support i686. "cublas" is not present in the + // 32-bit install. + println!("INFO: Rust cuda-sys does not currently support 32-bit Windows."); + return vec![]; + } + _ => { + println!("INFO: Rust cuda-sys only supports the x86_64 Windows architecture."); + return vec![]; + } + }; + + vec![ + // i.e. $CUDA_PATH/lib/x64 + path.join("lib") + .join(lib_path) + .to_str() + .unwrap() + .to_string(), + ] + } else { + // No idea where to look for CUDA + vec![] } } From 702944cea7a7b671479be4ce420b45a027d2d5e0 Mon Sep 17 00:00:00 2001 From: Andrew Gaspar Date: Tue, 4 Dec 2018 23:27:44 -0700 Subject: [PATCH 2/3] Document Windows Cuda discovery in README --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 475835d..c39551b 100644 --- a/README.md +++ b/README.md @@ -7,5 +7,10 @@ cuda-sys Rust binding to CUDA Driver(`libcuda.so`)/Runtime(`libcudart.so`) APIs -- This crate does not include CUDA itself. You need to install on your own. -- `$CUDA_LIBRARY_PATH` (e.g. `/opt/cuda/lib64`) will be used for `cargo:rustc-link-search` +This crate does not include CUDA itself. You need to install on your own. + +`$CUDA_LIBRARY_PATH` (e.g. `/opt/cuda/lib64`) will be used for +`cargo:rustc-link-search`. `$CUDA_LIBRARY_PATH` is not required on Windows when +Cuda is installed via the typical Windows installer. To verify that cuda-sys can +find your Cuda installation, you can check that the `CUDA_PATH` environment +variable has been set. From 5a8742a029110a7eebca2cf42b7ff370ed603a70 Mon Sep 17 00:00:00 2001 From: Andrew Gaspar Date: Sun, 6 Jan 2019 15:01:57 -0700 Subject: [PATCH 3/3] Guard CUDA_PATH search behind `cfg!(target_os = "windows")` --- build.rs | 115 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/build.rs b/build.rs index 4a97162..ad6d66f 100644 --- a/build.rs +++ b/build.rs @@ -10,71 +10,74 @@ fn find_library_paths() -> Vec { ":" }; - path.split(split_char) - .map(|s| s.to_owned()) - .collect::>() - } else if let Ok(path) = env::var("CUDA_PATH") { - // If CUDA_LIBRARY_PATH is not found, then CUDA_PATH will be used when building for Windows - // to locate the Cuda installation. Cuda installs the full Cuda SDK for 64-bit, but only - // a limited set of libraries for 32-bit. Namely, it does not include cublas in 32-bit, - // which cuda-sys requires. + return path.split(split_char).map(|s| s.to_owned()).collect(); + } - // 'path' points to the base of the CUDA Installation. The lib directory is a sub-directory. - let path = std::path::Path::new(&path); + if cfg!(target_os = "windows") { + if let Ok(path) = env::var("CUDA_PATH") { + // If CUDA_LIBRARY_PATH is not found, then CUDA_PATH will be used when building for + // Windows to locate the Cuda installation. Cuda installs the full Cuda SDK for 64-bit, + // but only a limited set of libraries for 32-bit. Namely, it does not include cublas in + // 32-bit, which cuda-sys requires. - // To do this the right way, we check to see which target we're building for. - let target = env::var("TARGET") - .expect("cargo did not set the TARGET environment variable as required."); + // 'path' points to the base of the CUDA Installation. The lib directory is a + // sub-directory. + let path = std::path::Path::new(&path); - // Targets use '-' separators. e.g. x86_64-pc-windows-msvc - let target_components: Vec<_> = target.as_str().split("-").collect(); + // To do this the right way, we check to see which target we're building for. + let target = env::var("TARGET") + .expect("cargo did not set the TARGET environment variable as required."); - // We check that we're building for Windows. This code assumes that the layout in CUDA_PATH - // matches Windows. - if target_components[2] != "windows" { - println!( - "INFO: The CUDA_PATH variable is only used by cuda-sys on Windows. Your target is \ - {}.", - target - ); - return vec![]; - } + // Targets use '-' separators. e.g. x86_64-pc-windows-msvc + let target_components: Vec<_> = target.as_str().split("-").collect(); - // Sanity check that the second component of 'target' is "pc" - debug_assert_eq!( - "pc", target_components[1], - "Expected a Windows target to have the second component be 'pc'. Target: {}", - target - ); - - // x86_64 should use the libs in the "lib/x64" directory. If we ever support i686 (which - // does not ship with cublas support), its libraries are in "lib/Win32". - let lib_path = match target_components[0] { - "x86_64" => "x64", - "i686" => { - // lib path would be "Win32" if we support i686. "cublas" is not present in the - // 32-bit install. - println!("INFO: Rust cuda-sys does not currently support 32-bit Windows."); - return vec![]; - } - _ => { - println!("INFO: Rust cuda-sys only supports the x86_64 Windows architecture."); + // We check that we're building for Windows. This code assumes that the layout in + // CUDA_PATH matches Windows. + if target_components[2] != "windows" { + println!( + "INFO: The CUDA_PATH variable is only used by cuda-sys on Windows. Your target \ + is {}.", + target + ); return vec![]; } - }; - vec![ - // i.e. $CUDA_PATH/lib/x64 - path.join("lib") - .join(lib_path) - .to_str() - .unwrap() - .to_string(), - ] - } else { - // No idea where to look for CUDA - vec![] + // Sanity check that the second component of 'target' is "pc" + debug_assert_eq!( + "pc", target_components[1], + "Expected a Windows target to have the second component be 'pc'. Target: {}", + target + ); + + // x86_64 should use the libs in the "lib/x64" directory. If we ever support i686 (which + // does not ship with cublas support), its libraries are in "lib/Win32". + let lib_path = match target_components[0] { + "x86_64" => "x64", + "i686" => { + // lib path would be "Win32" if we support i686. "cublas" is not present in the + // 32-bit install. + println!("INFO: Rust cuda-sys does not currently support 32-bit Windows."); + return vec![]; + } + _ => { + println!("INFO: Rust cuda-sys only supports the x86_64 Windows architecture."); + return vec![]; + } + }; + + return vec![ + // i.e. $CUDA_PATH/lib/x64 + path.join("lib") + .join(lib_path) + .to_str() + .unwrap() + .to_string(), + ]; + } } + + // No idea where to look for CUDA + vec![] } fn main() {