From a12e70726c30a5f9269b4f9b179021be58b7df04 Mon Sep 17 00:00:00 2001 From: Gemingyang Date: Fri, 29 Nov 2024 02:29:34 +0000 Subject: [PATCH 1/2] refactor code ande remove the check of fortran --- openblas-build/src/build.rs | 103 ++++++++++++++++-------------------- openblas-build/src/check.rs | 4 ++ openblas-src/build.rs | 87 ++---------------------------- 3 files changed, 55 insertions(+), 139 deletions(-) diff --git a/openblas-build/src/build.rs b/openblas-build/src/build.rs index 770e9e0..5f5e817 100644 --- a/openblas-build/src/build.rs +++ b/openblas-build/src/build.rs @@ -1,7 +1,7 @@ //! Execute make of OpenBLAS, and its options use crate::{check::*, error::*}; -use std::{fs, path::*, process::Command, str::FromStr}; +use std::{env, fs, path::*, process::Command, str::FromStr}; use walkdir::WalkDir; /// Interface for 32-bit interger (LP64) and 64-bit integer (ILP64) @@ -303,6 +303,14 @@ impl FromStr for Target { } } +#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)] +pub struct Compilers { + pub cc: Option, + pub fc: Option, + pub hostcc: Option, + pub ranlib: Option, +} + /// make option generator #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Configure { @@ -316,6 +324,7 @@ pub struct Configure { pub dynamic_arch: bool, pub interface: Interface, pub target: Option, + pub compilers: Compilers, } impl Default for Configure { @@ -331,45 +340,18 @@ impl Default for Configure { dynamic_arch: false, interface: Interface::LP64, target: None, + compilers: Compilers::default(), } } } /// Deliverables of `make` command pub struct Deliverables { - /// None if `no_static` - pub static_lib: Option, - /// None if `no_shared` - pub shared_lib: Option, /// Inspection what `make` command really show. pub make_conf: MakeConf, } impl Configure { - fn cross_compile_args(&self) -> Result, Error> { - let mut args = Vec::new(); - for name in ["CC", "FC", "HOSTCC"] { - if let Ok(value) = std::env::var(format!("OPENBLAS_{}", name)) { - args.push(format!("{}={}", name, value)); - eprintln!("{}={}", name, value); - } else { - eprintln!("not found {}", name); - } - } - // for successful compile all 3 env-vars must be set - if !args.is_empty() && args.len() != 3 { - return Err(Error::MissingCrossCompileInfo); - } - // optional flags - for name in ["RANLIB"] { - if let Ok(value) = std::env::var(format!("OPENBLAS_{}", name)) { - args.push(format!("{}={}", name, value)); - eprintln!("{}={}", name, value); - } - } - Ok(args) - } - fn make_args(&self) -> Vec { let mut args = Vec::new(); if self.no_static { @@ -399,13 +381,18 @@ impl Configure { if let Some(target) = self.target.as_ref() { args.push(format!("TARGET={:?}", target)) } - - for name in ["CC", "FC", "HOSTCC"] { - if let Ok(value) = std::env::var(format!("OPENBLAS_{}", name)) { - args.push(format!("{}={}", name, value)); - } + if let Some(compiler_cc) = self.compilers.cc.as_ref() { + args.push(format!("CC={}", compiler_cc)) + } + if let Some(compiler_fc) = self.compilers.fc.as_ref() { + args.push(format!("FC={}", compiler_fc)) + } + if let Some(compiler_hostcc) = self.compilers.hostcc.as_ref() { + args.push(format!("HOSTCC={}", compiler_hostcc)) + } + if let Some(compiler_ranlib) = self.compilers.ranlib.as_ref() { + args.push(format!("RANLIB={}", compiler_ranlib)) } - args } @@ -420,28 +407,24 @@ impl Configure { pub fn inspect(&self, out_dir: impl AsRef) -> Result { let out_dir = out_dir.as_ref(); let make_conf = MakeConf::new(out_dir.join("Makefile.conf"))?; - - if !self.no_lapack && make_conf.no_fortran { - return Err(Error::FortranCompilerNotFound); + if !self.no_static { + let lib_path = out_dir.join("libopenblas.a"); + if !lib_path.exists() { + return Err(Error::LibraryNotExist { path: lib_path }); + } } - - Ok(Deliverables { - static_lib: if !self.no_static { - Some(LibInspect::new(out_dir.join("libopenblas.a"))?) - } else { - None - }, - shared_lib: if !self.no_shared { - Some(LibInspect::new(if cfg!(target_os = "macos") { - out_dir.join("libopenblas.dylib") - } else { - out_dir.join("libopenblas.so") - })?) + if !self.no_shared { + let lib_path = if cfg!(target_os = "macos") { + out_dir.join("libopenblas.dylib") } else { - None - }, - make_conf, - }) + out_dir.join("libopenblas.so") + }; + if !lib_path.exists() { + return Err(Error::LibraryNotExist { path: lib_path }); + } + } + + Ok(Deliverables { make_conf }) } /// Build OpenBLAS @@ -492,6 +475,14 @@ impl Configure { } } + // check if cross compile is needed + let build_target = env::var("TARGET").unwrap_or_default(); + let build_host = env::var("HOST").unwrap_or_default(); + let is_cross_compile = build_target != build_host; + if is_cross_compile && (self.compilers.cc.is_none() || self.compilers.hostcc.is_none()) { + return Err(Error::MissingCrossCompileInfo); + } + // Run `make` as an subprocess // // - This will automatically run in parallel without `-j` flag @@ -507,7 +498,6 @@ impl Configure { .stdout(out) .stderr(err) .args(self.make_args()) - .args(self.cross_compile_args()?) .args(["all"]) .env_remove("TARGET") .check_call() @@ -524,7 +514,6 @@ impl Configure { return Err(e); } } - self.inspect(out_dir) } } diff --git a/openblas-build/src/check.rs b/openblas-build/src/check.rs index dd7d768..698ef08 100644 --- a/openblas-build/src/check.rs +++ b/openblas-build/src/check.rs @@ -93,6 +93,8 @@ impl MakeConf { "FEXTRALIB" => detail.f_extra_libs = LinkFlags::parse(entry[1])?, _ => continue, } + #[cfg(target_os = "macos")] + detail.c_extra_libs.libs.retain(|lib| lib != "to_library"); } Ok(detail) } @@ -103,11 +105,13 @@ impl MakeConf { /// - Linked shared libraries using `objdump -p` external command. /// - Global "T" symbols in the text (code) section of library using `nm -g` external command. #[derive(Debug, Clone)] +#[allow(dead_code)] pub struct LibInspect { pub libs: Vec, pub symbols: Vec, } +#[allow(dead_code)] impl LibInspect { /// Inspect library file /// diff --git a/openblas-src/build.rs b/openblas-src/build.rs index 4708b58..e4197ba 100644 --- a/openblas-src/build.rs +++ b/openblas-src/build.rs @@ -122,7 +122,6 @@ fn main() { } /// Build OpenBLAS using openblas-build crate -#[cfg(target_os = "linux")] fn build() { println!("cargo:rerun-if-env-changed=OPENBLAS_TARGET"); println!("cargo:rerun-if-env-changed=OPENBLAS_CC"); @@ -150,6 +149,10 @@ fn build() { // Do not default to the native target (represented by `cfg.target == None`) // because most user set `$OPENBLAS_TARGET` explicitly will hope not to use the native target. } + cfg.compilers.cc = env::var("OPENBLAS_CC").ok(); + cfg.compilers.hostcc = env::var("OPENBLAS_HOSTCC").ok(); + cfg.compilers.fc = env::var("OPENBLAS_FC").ok(); + cfg.compilers.ranlib = env::var("OPENBLAS_RANLIB").ok(); let output = if feature_enabled("cache") { use std::hash::*; @@ -183,7 +186,7 @@ fn build() { // // Be sure that `cargo:warning` is shown only when openblas-src is build as path dependency... // https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargowarningmessage - if !feature_enabled("static") { + if !feature_enabled("static") && cfg!(not(target_os = "macos")) { println!( "cargo:warning=OpenBLAS is built as a shared library. You need to set LD_LIBRARY_PATH={}", output.display() @@ -207,83 +210,3 @@ fn build() { println!("cargo:rustc-link-lib={}", lib); } } - -/// openblas-src 0.9.0 compatible `make` runner -/// -/// This cannot detect that OpenBLAS skips LAPACK build due to the absense of Fortran compiler. -/// openblas-build crate can detect it by sneaking OpenBLAS build system, but only works on Linux. -/// -#[cfg(not(target_os = "linux"))] -fn build() { - use std::fs; - - let output = PathBuf::from(env::var("OUT_DIR").unwrap().replace(r"\", "/")); - let mut make = Command::new("make"); - make.args(&["all"]) - .arg(format!("BINARY={}", binary())) - .arg(format!( - "{}_CBLAS=1", - if feature_enabled("cblas") { - "YES" - } else { - "NO" - } - )) - .arg(format!( - "{}_LAPACKE=1", - if feature_enabled("lapacke") { - "YES" - } else { - "NO" - } - )); - match env::var("OPENBLAS_ARGS") { - Ok(args) => { - make.args(args.split_whitespace()); - } - _ => (), - }; - if let Ok(num_jobs) = env::var("NUM_JOBS") { - make.arg(format!("-j{}", num_jobs)); - } - let target = match env::var("OPENBLAS_TARGET") { - Ok(target) => { - make.arg(format!("TARGET={}", target)); - target - } - _ => env::var("TARGET").unwrap(), - }; - env::remove_var("TARGET"); - let source = if feature_enabled("cache") { - PathBuf::from(format!("source_{}", target.to_lowercase())) - } else { - output.join(format!("source_{}", target.to_lowercase())) - }; - - if !source.exists() { - let source_tmp = openblas_build::download(&output).unwrap(); - fs::rename(&source_tmp, &source).unwrap(); - } - for name in &vec!["CC", "FC", "HOSTCC"] { - if let Ok(value) = env::var(format!("OPENBLAS_{}", name)) { - make.arg(format!("{}={}", name, value)); - } - } - run(&mut make.current_dir(&source)); - run(Command::new("make") - .arg("install") - .arg(format!("DESTDIR={}", output.display())) - .current_dir(&source)); - println!( - "cargo:rustc-link-search={}", - output.join("opt/OpenBLAS/lib").display(), - ); - - fn binary() -> &'static str { - if cfg!(target_pointer_width = "32") { - "32" - } else { - "64" - } - } -} From 5c906fa93ecde17c95dcfdece9de22aff0ca0eb3 Mon Sep 17 00:00:00 2001 From: Gemingyang Date: Fri, 29 Nov 2024 16:40:28 +0000 Subject: [PATCH 2/2] Drop LAPACK symbol inspection --- openblas-build/Cargo.toml | 3 +- openblas-build/nofortran.conf | 44 --------- openblas-build/src/build.rs | 174 ++++++++++++++-------------------- openblas-build/src/check.rs | 17 +--- openblas-src/build.rs | 16 ++-- 5 files changed, 85 insertions(+), 169 deletions(-) delete mode 100644 openblas-build/nofortran.conf diff --git a/openblas-build/Cargo.toml b/openblas-build/Cargo.toml index 9a3386b..6d82362 100644 --- a/openblas-build/Cargo.toml +++ b/openblas-build/Cargo.toml @@ -22,5 +22,6 @@ ureq = { version = "2.5.0", default-features = false, features = [ "gzip", ] } native-tls = { version = "0.2.11" } -walkdir = "2.3.1" +[dev-dependencies] +walkdir = "2.0" diff --git a/openblas-build/nofortran.conf b/openblas-build/nofortran.conf deleted file mode 100644 index 64411c1..0000000 --- a/openblas-build/nofortran.conf +++ /dev/null @@ -1,44 +0,0 @@ -OSNAME=Linux -ARCH=x86_64 -C_COMPILER=GCC -BINARY32= -BINARY64=1 -CEXTRALIB=-L/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0 -L/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../.. -lc -F_COMPILER=GFORTRAN -FC=gfortran -BU=_ -NOFORTRAN=1 -CORE=HASWELL -LIBCORE=haswell -NUM_CORES=12 -HAVE_MMX=1 -HAVE_SSE=1 -HAVE_SSE2=1 -HAVE_SSE3=1 -HAVE_SSSE3=1 -HAVE_SSE4_1=1 -HAVE_SSE4_2=1 -HAVE_AVX=1 -HAVE_AVX2=1 -HAVE_FMA3=1 -MAKE += -j 12 -SHGEMM_UNROLL_M=8 -SHGEMM_UNROLL_N=4 -SGEMM_UNROLL_M=8 -SGEMM_UNROLL_N=4 -DGEMM_UNROLL_M=4 -DGEMM_UNROLL_N=8 -QGEMM_UNROLL_M=2 -QGEMM_UNROLL_N=2 -CGEMM_UNROLL_M=8 -CGEMM_UNROLL_N=2 -ZGEMM_UNROLL_M=4 -ZGEMM_UNROLL_N=2 -XGEMM_UNROLL_M=1 -XGEMM_UNROLL_N=1 -CGEMM3M_UNROLL_M=8 -CGEMM3M_UNROLL_N=4 -ZGEMM3M_UNROLL_M=4 -ZGEMM3M_UNROLL_N=4 -XGEMM3M_UNROLL_M=2 -XGEMM3M_UNROLL_N=2 diff --git a/openblas-build/src/build.rs b/openblas-build/src/build.rs index 5f5e817..1dbe4ec 100644 --- a/openblas-build/src/build.rs +++ b/openblas-build/src/build.rs @@ -2,7 +2,6 @@ use crate::{check::*, error::*}; use std::{env, fs, path::*, process::Command, str::FromStr}; -use walkdir::WalkDir; /// Interface for 32-bit interger (LP64) and 64-bit integer (ILP64) #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -345,12 +344,6 @@ impl Default for Configure { } } -/// Deliverables of `make` command -pub struct Deliverables { - /// Inspection what `make` command really show. - pub make_conf: MakeConf, -} - impl Configure { fn make_args(&self) -> Vec { let mut args = Vec::new(); @@ -396,37 +389,6 @@ impl Configure { args } - /// Inspect existing build deliverables, and validate them. - /// - /// Error - /// ------ - /// - No build deliverables exist - /// - Build deliverables are not valid - /// - e.g. `self.no_lapack == false`, but the existing library does not contains LAPACK symbols. - /// - pub fn inspect(&self, out_dir: impl AsRef) -> Result { - let out_dir = out_dir.as_ref(); - let make_conf = MakeConf::new(out_dir.join("Makefile.conf"))?; - if !self.no_static { - let lib_path = out_dir.join("libopenblas.a"); - if !lib_path.exists() { - return Err(Error::LibraryNotExist { path: lib_path }); - } - } - if !self.no_shared { - let lib_path = if cfg!(target_os = "macos") { - out_dir.join("libopenblas.dylib") - } else { - out_dir.join("libopenblas.so") - }; - if !lib_path.exists() { - return Err(Error::LibraryNotExist { path: lib_path }); - } - } - - Ok(Deliverables { make_conf }) - } - /// Build OpenBLAS /// /// Libraries are created directly under `out_dir` e.g. `out_dir/libopenblas.a` @@ -437,42 +399,11 @@ impl Configure { /// This means that the system environment is not appropriate to execute `make`, /// e.g. LAPACK is required but there is no Fortran compiler. /// - pub fn build( - self, - openblas_root: impl AsRef, - out_dir: impl AsRef, - ) -> Result { - let out_dir = out_dir.as_ref(); - if !out_dir.exists() { - fs::create_dir_all(out_dir)?; - } - - // Do not build if libraries and Makefile.conf already exist and are valid - if let Ok(deliv) = self.inspect(out_dir) { - return Ok(deliv); - } - - // Copy OpenBLAS sources from this crate to `out_dir` + pub fn build>(self, openblas_root: P) -> Result { let root = openblas_root.as_ref(); - for entry in WalkDir::new(root) { - let entry = entry.expect("Unknown IO error while walkdir"); - let dest = out_dir.join( - entry - .path() - .strip_prefix(root) - .expect("Directory entry is not under root"), - ); - if dest.exists() { - // Do not overwrite - // Cache of previous build should be cleaned by `cargo clean` - continue; - } - if entry.file_type().is_dir() { - fs::create_dir(&dest)?; - } - if entry.file_type().is_file() { - fs::copy(entry.path(), &dest)?; - } + // Do not build if libraries and Makefile.conf already exist and are valid + if let Ok(make_conf) = MakeConf::new(root.join("Makefile.conf")) { + return Ok(make_conf); } // check if cross compile is needed @@ -491,10 +422,10 @@ impl Configure { // - cargo sets `TARGET` environment variable as target triple (e.g. x86_64-unknown-linux-gnu) // while binding build.rs, but `make` read it as CPU target specification. // - let out = fs::File::create(out_dir.join("out.log")).expect("Cannot create log file"); - let err = fs::File::create(out_dir.join("err.log")).expect("Cannot create log file"); + let out = fs::File::create(root.join("out.log")).expect("Cannot create log file"); + let err = fs::File::create(root.join("err.log")).expect("Cannot create log file"); match Command::new("make") - .current_dir(out_dir) + .current_dir(root) .stdout(out) .stderr(err) .args(self.make_args()) @@ -506,7 +437,7 @@ impl Configure { Err(err @ Error::NonZeroExitStatus { .. }) => { eprintln!( "{}", - fs::read_to_string(out_dir.join("err.log")).expect("Cannot read log file") + fs::read_to_string(root.join("err.log")).expect("Cannot read log file") ); return Err(err); } @@ -514,7 +445,8 @@ impl Configure { return Err(e); } } - self.inspect(out_dir) + + MakeConf::new(root.join("Makefile.conf")) } } @@ -531,62 +463,96 @@ mod tests { )); } - fn get_openblas_source() -> PathBuf { - let openblas_src_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../openblas-src"); - crate::download(&openblas_src_root).unwrap() + fn get_openblas_source>(out_dir: P) -> PathBuf { + let openblas_src_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../openblas-src/"); + let source = crate::download(&openblas_src_root).unwrap(); + // copy files to the target directory + let out_dir = out_dir.as_ref(); + fs::create_dir_all(out_dir).unwrap(); + for entry in walkdir::WalkDir::new(&source) { + let entry = entry.unwrap(); + let src = entry.path(); + let dest = out_dir.join(src.strip_prefix(&source).unwrap()); + if entry.file_type().is_dir() { + fs::create_dir_all(&dest).unwrap(); + } else { + fs::copy(src, dest).unwrap(); + } + } + out_dir.to_path_buf() } #[ignore] #[test] fn build_default() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let out_dir = root.join("test_build/build_default"); let opt = Configure::default(); - let _detail = opt - .build(get_openblas_source(), root.join("test_build/build_default")) - .unwrap(); + let _ = opt.build(get_openblas_source(&out_dir)).unwrap(); } #[ignore] #[test] fn build_no_shared() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let out_dir = root.join("test_build/build_no_shared"); let mut opt = Configure::default(); opt.no_shared = true; - let detail = opt - .build( - get_openblas_source(), - root.join("test_build/build_no_shared"), - ) - .unwrap(); - assert!(detail.shared_lib.is_none()); + opt.build(get_openblas_source(&out_dir)).unwrap(); + let _ = LibInspect::new(out_dir.join("libopenblas.a")).unwrap(); } #[ignore] #[test] fn build_no_lapacke() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let out_dir = root.join("test_build/build_no_lapacke"); let mut opt = Configure::default(); opt.no_lapacke = true; - let detail = opt - .build( - get_openblas_source(), - root.join("test_build/build_no_lapacke"), - ) - .unwrap(); - let shared_lib = detail.shared_lib.unwrap(); - assert!(shared_lib.has_lapack()); - assert!(!shared_lib.has_lapacke()); + let _ = opt.build(get_openblas_source(&out_dir)).unwrap(); + let lib_name = if cfg!(target_os = "macos") { + "libopenblas.dylib" + } else { + "libopenblas.so" + }; + let lib_inspect = LibInspect::new(out_dir.join(lib_name)).unwrap(); + + assert!(lib_inspect.has_lapack()); + assert!(!lib_inspect.has_lapacke()); + } + + #[ignore] + #[test] + fn build_no_cblas() { + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let out_dir = root.join("test_build/build_no_cblas"); + let mut opt = Configure::default(); + opt.no_lapacke = true; + let _ = opt.build(get_openblas_source(&out_dir)).unwrap(); + let lib_name = if cfg!(target_os = "macos") { + "libopenblas.dylib" + } else { + "libopenblas.so" + }; + let lib_inspect = LibInspect::new(out_dir.join(lib_name)).unwrap(); + + assert!(!lib_inspect.has_cblas()); } #[ignore] #[test] fn build_openmp() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let out_dir = root.join("test_build/build_openmp"); let mut opt = Configure::default(); opt.use_openmp = true; - let detail = opt - .build(get_openblas_source(), root.join("test_build/build_openmp")) - .unwrap(); - assert!(detail.shared_lib.unwrap().has_lib("gomp")); + let _ = opt.build(get_openblas_source(&out_dir)).unwrap(); + let lib_name = if cfg!(target_os = "macos") { + "libopenblas.dylib" + } else { + "libopenblas.so" + }; + let lib_inspect = LibInspect::new(out_dir.join(lib_name)).unwrap(); + assert!(lib_inspect.has_lib("gomp")); } } diff --git a/openblas-build/src/check.rs b/openblas-build/src/check.rs index 698ef08..0bb68b5 100644 --- a/openblas-build/src/check.rs +++ b/openblas-build/src/check.rs @@ -7,7 +7,6 @@ use std::{ hash::Hash, io::{self, BufRead}, path::*, - process::Command, }; /// Parse compiler linker flags, `-L` and `-l` @@ -105,18 +104,19 @@ impl MakeConf { /// - Linked shared libraries using `objdump -p` external command. /// - Global "T" symbols in the text (code) section of library using `nm -g` external command. #[derive(Debug, Clone)] -#[allow(dead_code)] -pub struct LibInspect { +#[cfg(test)] +pub(crate) struct LibInspect { pub libs: Vec, pub symbols: Vec, } -#[allow(dead_code)] +#[cfg(test)] impl LibInspect { /// Inspect library file /// /// Be sure that `nm -g` and `objdump -p` are executed in this function pub fn new>(path: P) -> Result { + use std::process::Command; let path = path.as_ref(); if !path.exists() { return Err(Error::LibraryNotExist { @@ -208,7 +208,6 @@ impl LibInspect { #[cfg(test)] mod tests { use super::*; - #[test] fn detail_from_makefile_conf() { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("Makefile.conf"); @@ -216,12 +215,4 @@ mod tests { let detail = MakeConf::new(path).unwrap(); assert!(!detail.no_fortran); } - - #[test] - fn detail_from_nofortran_conf() { - let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("nofortran.conf"); - assert!(path.exists()); - let detail = MakeConf::new(path).unwrap(); - assert!(detail.no_fortran); - } } diff --git a/openblas-src/build.rs b/openblas-src/build.rs index e4197ba..1b6366c 100644 --- a/openblas-src/build.rs +++ b/openblas-src/build.rs @@ -50,7 +50,9 @@ fn windows_msvc_system() { env::set_var("VCPKGRS_DYNAMIC", "1"); } #[cfg(target_env = "msvc")] - vcpkg::find_package("openblas").unwrap(); + vcpkg::find_package("openblas").expect( + "vcpkg failed to find OpenBLAS package , Try to install it using `vcpkg install openblas:$(ARCH)-windows(-static)(-md)`" + ); if !cfg!(target_env = "msvc") { unreachable!(); } @@ -194,19 +196,19 @@ fn build() { } let source = openblas_build::download(&output).unwrap(); - let deliv = cfg.build(source, &output).unwrap(); + let make_conf = cfg.build(&source).unwrap(); - println!("cargo:rustc-link-search={}", output.display()); - for search_path in &deliv.make_conf.c_extra_libs.search_paths { + println!("cargo:rustc-link-search={}", source.display()); + for search_path in &make_conf.c_extra_libs.search_paths { println!("cargo:rustc-link-search={}", search_path.display()); } - for lib in &deliv.make_conf.c_extra_libs.libs { + for lib in &make_conf.c_extra_libs.libs { println!("cargo:rustc-link-lib={}", lib); } - for search_path in &deliv.make_conf.f_extra_libs.search_paths { + for search_path in &make_conf.f_extra_libs.search_paths { println!("cargo:rustc-link-search={}", search_path.display()); } - for lib in &deliv.make_conf.f_extra_libs.libs { + for lib in &make_conf.f_extra_libs.libs { println!("cargo:rustc-link-lib={}", lib); } }