From 81468be08426846ba6ce16d10e27aefc646abb9d Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Mon, 22 Apr 2019 15:55:09 -0700 Subject: [PATCH 1/2] Allow overriding system root via environment Use the PKG_CONFIG_SYSROOT_DIR (preferred) or SYSROOT (fallback) environment variables to override the default path used to determine whether a library is a system library or not (/usr). This enables cross-compilation scenarios where the system root is not a subdirectory of /usr. Specifically, when building Rust packages in the Chomium OS SDK, each board's sysroot is located in /build/$BOARD rather than a subdirectory of /usr. Additionally, cros_sdk only specifies SYSROOT (PKG_CONFIG_SYSROOT_DIR is set by the pkg-config-$BOARD cross compilation helpers, but that isn't available in pkg-config-rs). This has only been tested on Linux, as I don't have a macOS machine handy, but I believe the macOS path should work as before (it does not consider the new sysroot variables). Signed-off-by: Daniel Verkamp --- src/lib.rs | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e68371d..f95b648 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,7 +75,7 @@ use std::ffi::{OsStr, OsString}; use std::fmt; use std::io; use std::ops::{Bound, RangeBounds}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::process::{Command, Output}; use std::str; @@ -145,7 +145,7 @@ impl fmt::Display for Error { Install a sysroot for the target platform and configure it via PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_PATH, or install a cross-compiling wrapper for pkg-config and set it via - PKG_CONFIG environment variable." + PKG_CONFIG environment variable.", ), Error::Command { ref command, @@ -499,6 +499,17 @@ impl Library { } } + let system_roots = if cfg!(target_os = "macos") { + vec![PathBuf::from("/Library"), PathBuf::from("/System")] + } else { + let sysroot = config + .env_var_os("PKG_CONFIG_SYSROOT_DIR") + .or_else(|| config.env_var_os("SYSROOT")) + .map(PathBuf::from) + .unwrap_or_else(|| PathBuf::from("/usr")); + vec![sysroot] + }; + let words = split_flags(output); let parts = words .iter() @@ -530,7 +541,7 @@ impl Library { continue; } - if statik && is_static_available(val, &dirs) { + if statik && is_static_available(val, &system_roots, &dirs) { let meta = format!("rustc-link-lib=static={}", val); config.print_metadata(&meta); } else { @@ -583,13 +594,8 @@ fn envify(name: &str) -> String { } /// System libraries should only be linked dynamically -fn is_static_available(name: &str, dirs: &[PathBuf]) -> bool { +fn is_static_available(name: &str, system_roots: &[PathBuf], dirs: &[PathBuf]) -> bool { let libname = format!("lib{}.a", name); - let system_roots = if cfg!(target_os = "macos") { - vec![Path::new("/Library"), Path::new("/System")] - } else { - vec![Path::new("/usr")] - }; dirs.iter().any(|dir| { !system_roots.iter().any(|sys| dir.starts_with(sys)) && dir.join(&libname).exists() @@ -654,18 +660,23 @@ fn split_flags(output: &[u8]) -> Vec { #[test] #[cfg(target_os = "macos")] fn system_library_mac_test() { + let system_roots = vec![PathBuf::from("/Library"), PathBuf::from("/System")]; + assert!(!is_static_available( "PluginManager", + system_roots, &[PathBuf::from("/Library/Frameworks")] )); assert!(!is_static_available( "python2.7", + system_roots, &[PathBuf::from( "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config" )] )); assert!(!is_static_available( "ffi_convenience", + system_roots, &[PathBuf::from( "/Library/Ruby/Gems/2.0.0/gems/ffi-1.9.10/ext/ffi_c/libffi-x86_64/.libs" )] @@ -675,6 +686,7 @@ fn system_library_mac_test() { if Path::new("/usr/local/lib/libpng16.a").exists() { assert!(is_static_available( "png16", + system_roots, &[PathBuf::from("/usr/local/lib")] )); @@ -691,7 +703,12 @@ fn system_library_mac_test() { fn system_library_linux_test() { assert!(!is_static_available( "util", + &[PathBuf::from("/usr")], &[PathBuf::from("/usr/lib/x86_64-linux-gnu")] )); - assert!(!is_static_available("dialog", &[PathBuf::from("/usr/lib")])); + assert!(!is_static_available( + "dialog", + &[PathBuf::from("/usr")], + &[PathBuf::from("/usr/lib")] + )); } From e94a5336cd66451df892af2399dd1b38577db5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 4 Sep 2020 11:05:40 +0300 Subject: [PATCH 2/2] Don't use /usr as fallback sysroot on Windows --- src/lib.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f95b648..1587d69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -505,9 +505,17 @@ impl Library { let sysroot = config .env_var_os("PKG_CONFIG_SYSROOT_DIR") .or_else(|| config.env_var_os("SYSROOT")) - .map(PathBuf::from) - .unwrap_or_else(|| PathBuf::from("/usr")); - vec![sysroot] + .map(PathBuf::from); + + if cfg!(target_os = "windows") { + if let Some(sysroot) = sysroot { + vec![sysroot] + } else { + vec![] + } + } else { + vec![sysroot.unwrap_or_else(|| PathBuf::from("/usr"))] + } }; let words = split_flags(output);