diff options
Diffstat (limited to 'pkg-config')
-rw-r--r-- | pkg-config/.gitignore | 4 | ||||
-rw-r--r-- | pkg-config/.travis.yml | 23 | ||||
-rw-r--r-- | pkg-config/CHANGELOG.md | 19 | ||||
-rw-r--r-- | pkg-config/Cargo.toml | 19 | ||||
-rw-r--r-- | pkg-config/LICENSE-APACHE | 201 | ||||
-rw-r--r-- | pkg-config/LICENSE-MIT | 25 | ||||
-rw-r--r-- | pkg-config/README.md | 73 | ||||
-rw-r--r-- | pkg-config/src/lib.rs | 630 | ||||
-rw-r--r-- | pkg-config/tests/escape.pc | 5 | ||||
-rw-r--r-- | pkg-config/tests/foo.pc | 16 | ||||
-rw-r--r-- | pkg-config/tests/framework.pc | 16 | ||||
-rw-r--r-- | pkg-config/tests/test.rs | 118 |
12 files changed, 0 insertions, 1149 deletions
diff --git a/pkg-config/.gitignore b/pkg-config/.gitignore deleted file mode 100644 index d6904d2..0000000 --- a/pkg-config/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/target -/Cargo.lock -.idea -*.iml diff --git a/pkg-config/.travis.yml b/pkg-config/.travis.yml deleted file mode 100644 index f184052..0000000 --- a/pkg-config/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: rust -rust: - - stable - - beta - - nightly -sudo: false -before_script: - - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH -script: - - cargo build --verbose - - cargo test --verbose - - cargo doc --no-deps -after_success: - - travis-cargo --only nightly doc-upload -env: - global: - secure: "D/GKEEBQarjXTZ6NWzwQq39nQ892XJ9m3C9219K/6Us8jyjE5DBhosDPvg6pvRJtTLaghDxuhxqkHunayNL18IOvkNbfMjYsnkP8/yMftQUfRdNub6C1kXAi8guXjPd8rUwW0Oy8Nar61WAwWQgHkXfuSJ2em7u/Xk0tICPSwlA=" - - - -notifications: - email: - on_success: never diff --git a/pkg-config/CHANGELOG.md b/pkg-config/CHANGELOG.md deleted file mode 100644 index 3f56db1..0000000 --- a/pkg-config/CHANGELOG.md +++ /dev/null @@ -1,19 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [0.3.10] - 2018-04-23 - -### Added -- Allow static linking of /usr/ on macOS (#42) -- Add support for parsing `-Wl,` style framework flags (#48) -- Parse defines in `pkg-config` output (#49) -- Rerun on `PKG_CONFIG_PATH` changes (#50) -- Introduce target-scoped variables (#58) -- Respect pkg-config escaping rules used with --cflags and --libs (#61) - -### Changed -- Use `?` instead of `try!()` in the codebase (#63) diff --git a/pkg-config/Cargo.toml b/pkg-config/Cargo.toml deleted file mode 100644 index 6f06af5..0000000 --- a/pkg-config/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] - -name = "pkg-config" -version = "0.3.14" -authors = ["Alex Crichton <alex@alexcrichton.com>"] -license = "MIT/Apache-2.0" -repository = "https://github.com/alexcrichton/pkg-config-rs" -documentation = "https://docs.rs/pkg-config" -description = """ -A library to run the pkg-config system tool at build time in order to be used in -Cargo build scripts. -""" -keywords = ["build-dependencies"] - -[badges] -travis-ci = { repository = "alexcrichton/pkg-config-rs" } - -[dev-dependencies] -lazy_static = "1" diff --git a/pkg-config/LICENSE-APACHE b/pkg-config/LICENSE-APACHE deleted file mode 100644 index 16fe87b..0000000 --- a/pkg-config/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/pkg-config/LICENSE-MIT b/pkg-config/LICENSE-MIT deleted file mode 100644 index 39e0ed6..0000000 --- a/pkg-config/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2014 Alex Crichton - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/pkg-config/README.md b/pkg-config/README.md deleted file mode 100644 index cb9ebd5..0000000 --- a/pkg-config/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# pkg-config-rs - -[![Build Status](https://travis-ci.org/alexcrichton/pkg-config-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/pkg-config-rs) -[![Rust](https://img.shields.io/badge/rust-1.13%2B-blue.svg?maxAge=3600)](https://github.com/alexcrichton/pkg-config-rs/) - -[Documentation](https://docs.rs/pkg-config) - -A simple library meant to be used as a build dependency with Cargo packages in -order to use the system `pkg-config` tool (if available) to determine where a -library is located. - -You can use this crate directly to probe for specific libraries, or use -[metadeps](https://github.com/joshtriplett/metadeps) to declare all your -`pkg-config` dependencies in `Cargo.toml`. - -This library requires Rust 1.13+. - -# Example - -Find the system library named `foo`, with minimum version 1.2.3: - -```rust -extern crate pkg_config; - -fn main() { - pkg_config::Config::new().atleast_version("1.2.3").probe("foo").unwrap(); -} -``` - -Find the system library named `foo`, with no version requirement (not -recommended): - -```rust -extern crate pkg_config; - -fn main() { - pkg_config::probe_library("foo").unwrap(); -} -``` - -# External configuration via target-scoped environment variables - -In cross-compilation context, it is useful to manage separately PKG_CONFIG_PATH -and a few other variables for the `host` and the `target` platform. - -The supported variables are: `PKG_CONFIG_PATH`, `PKG_CONFIG_LIBDIR`, and -`PKG_CONFIG_SYSROOT_DIR`. - -Each of these variables can also be supplied with certain prefixes and suffixes, in the following prioritized order: - -1. `<var>_<target>` - for example, `PKG_CONFIG_PATH_x86_64-unknown-linux-gnu` -2. `<var>_<target_with_underscores>` - for example, `PKG_CONFIG_PATH_x86_64_unknown_linux_gnu` -3. `<build-kind>_<var>` - for example, `HOST_PKG_CONFIG_PATH` or `TARGET_PKG_CONFIG_PATH` -4. `<var>` - a plain `PKG_CONFIG_PATH` - -Also note that `PKG_CONFIG_ALLOW_CROSS` must always be set in cross-compilation context. - -# License - -This project is licensed under either of - - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or - http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. diff --git a/pkg-config/src/lib.rs b/pkg-config/src/lib.rs deleted file mode 100644 index 88dd310..0000000 --- a/pkg-config/src/lib.rs +++ /dev/null @@ -1,630 +0,0 @@ -//! A build dependency for Cargo libraries to find system artifacts through the -//! `pkg-config` utility. -//! -//! This library will shell out to `pkg-config` as part of build scripts and -//! probe the system to determine how to link to a specified library. The -//! `Config` structure serves as a method of configuring how `pkg-config` is -//! invoked in a builder style. -//! -//! A number of environment variables are available to globally configure how -//! this crate will invoke `pkg-config`: -//! -//! * `PKG_CONFIG_ALLOW_CROSS` - if this variable is not set, then `pkg-config` -//! will automatically be disabled for all cross compiles. -//! * `FOO_NO_PKG_CONFIG` - if set, this will disable running `pkg-config` when -//! probing for the library named `foo`. -//! -//! There are also a number of environment variables which can configure how a -//! library is linked to (dynamically vs statically). These variables control -//! whether the `--static` flag is passed. Note that this behavior can be -//! overridden by configuring explicitly on `Config`. The variables are checked -//! in the following order: -//! -//! * `FOO_STATIC` - pass `--static` for the library `foo` -//! * `FOO_DYNAMIC` - do not pass `--static` for the library `foo` -//! * `PKG_CONFIG_ALL_STATIC` - pass `--static` for all libraries -//! * `PKG_CONFIG_ALL_DYNAMIC` - do not pass `--static` for all libraries -//! -//! After running `pkg-config` all appropriate Cargo metadata will be printed on -//! stdout if the search was successful. -//! -//! # Example -//! -//! Find the system library named `foo`, with minimum version 1.2.3: -//! -//! ```no_run -//! extern crate pkg_config; -//! -//! fn main() { -//! pkg_config::Config::new().atleast_version("1.2.3").probe("foo").unwrap(); -//! } -//! ``` -//! -//! Find the system library named `foo`, with no version requirement (not -//! recommended): -//! -//! ```no_run -//! extern crate pkg_config; -//! -//! fn main() { -//! pkg_config::probe_library("foo").unwrap(); -//! } -//! ``` -//! -//! Configure how library `foo` is linked to. -//! -//! ```no_run -//! extern crate pkg_config; -//! -//! fn main() { -//! pkg_config::Config::new().atleast_version("1.2.3").statik(true).probe("foo").unwrap(); -//! } -//! ``` - -#![doc(html_root_url = "https://docs.rs/pkg-config/0.3")] - -#[allow(unused_imports)] // Required for Rust <1.23 -use std::ascii::AsciiExt; -use std::collections::HashMap; -use std::env; -use std::error; -use std::ffi::{OsStr, OsString}; -use std::fmt; -use std::io; -use std::path::{PathBuf, Path}; -use std::process::{Command, Output}; -use std::str; - -pub fn target_supported() -> bool { - let target = env::var("TARGET").unwrap_or_else(|_| String::new()); - let host = env::var("HOST").unwrap_or_else(|_| String::new()); - - // Only use pkg-config in host == target situations by default (allowing an - // override). - (host == target || env::var_os("PKG_CONFIG_ALLOW_CROSS").is_some()) -} - -#[derive(Clone, Default)] -pub struct Config { - statik: Option<bool>, - atleast_version: Option<String>, - extra_args: Vec<OsString>, - cargo_metadata: bool, - env_metadata: bool, - print_system_libs: bool, -} - -#[derive(Debug)] -pub struct Library { - pub libs: Vec<String>, - pub link_paths: Vec<PathBuf>, - pub frameworks: Vec<String>, - pub framework_paths: Vec<PathBuf>, - pub include_paths: Vec<PathBuf>, - pub defines: HashMap<String, Option<String>>, - pub version: String, - _priv: (), -} - -/// Represents all reasons `pkg-config` might not succeed or be run at all. -pub enum Error { - /// Aborted because of `*_NO_PKG_CONFIG` environment variable. - /// - /// Contains the name of the responsible environment variable. - EnvNoPkgConfig(String), - - /// Cross compilation detected. - /// - /// Override with `PKG_CONFIG_ALLOW_CROSS=1`. - CrossCompilation, - - /// Failed to run `pkg-config`. - /// - /// Contains the command and the cause. - Command { command: String, cause: io::Error }, - - /// `pkg-config` did not exit sucessfully. - /// - /// Contains the command and output. - Failure { command: String, output: Output }, - - #[doc(hidden)] - // please don't match on this, we're likely to add more variants over time - __Nonexhaustive, -} - -impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::EnvNoPkgConfig(_) => "pkg-config requested to be aborted", - Error::CrossCompilation => { - "pkg-config doesn't handle cross compilation. \ - Use PKG_CONFIG_ALLOW_CROSS=1 to override" - } - Error::Command { .. } => "failed to run pkg-config", - Error::Failure { .. } => "pkg-config did not exit sucessfully", - Error::__Nonexhaustive => panic!(), - } - } - - fn cause(&self) -> Option<&error::Error> { - match *self { - Error::Command { ref cause, .. } => Some(cause), - _ => None, - } - } -} - -// Workaround for temporary lack of impl Debug for Output in stable std -struct OutputDebugger<'a>(&'a Output); - -// Lifted from 1.7 std -impl<'a> fmt::Debug for OutputDebugger<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let stdout_utf8 = str::from_utf8(&self.0.stdout); - let stdout_debug: &fmt::Debug = match stdout_utf8 { - Ok(ref str) => str, - Err(_) => &self.0.stdout - }; - - let stderr_utf8 = str::from_utf8(&self.0.stderr); - let stderr_debug: &fmt::Debug = match stderr_utf8 { - Ok(ref str) => str, - Err(_) => &self.0.stderr - }; - - fmt.debug_struct("Output") - .field("status", &self.0.status) - .field("stdout", stdout_debug) - .field("stderr", stderr_debug) - .finish() - } -} - -// Workaround for temporary lack of impl Debug for Output in stable std, continued -impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - Error::EnvNoPkgConfig(ref name) => { - f.debug_tuple("EnvNoPkgConfig") - .field(name) - .finish() - } - Error::CrossCompilation => write!(f, "CrossCompilation"), - Error::Command { ref command, ref cause } => { - f.debug_struct("Command") - .field("command", command) - .field("cause", cause) - .finish() - } - Error::Failure { ref command, ref output } => { - f.debug_struct("Failure") - .field("command", command) - .field("output", &OutputDebugger(output)) - .finish() - } - Error::__Nonexhaustive => panic!(), - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - Error::EnvNoPkgConfig(ref name) => { - write!(f, "Aborted because {} is set", name) - } - Error::CrossCompilation => { - write!(f, "Cross compilation detected. \ - Use PKG_CONFIG_ALLOW_CROSS=1 to override") - } - Error::Command { ref command, ref cause } => { - write!(f, "Failed to run `{}`: {}", command, cause) - } - Error::Failure { ref command, ref output } => { - let stdout = str::from_utf8(&output.stdout).unwrap(); - let stderr = str::from_utf8(&output.stderr).unwrap(); - write!(f, "`{}` did not exit successfully: {}", command, output.status)?; - if !stdout.is_empty() { - write!(f, "\n--- stdout\n{}", stdout)?; - } - if !stderr.is_empty() { - write!(f, "\n--- stderr\n{}", stderr)?; - } - Ok(()) - } - Error::__Nonexhaustive => panic!(), - } - } -} - -/// Deprecated in favor of the probe_library function -#[doc(hidden)] -pub fn find_library(name: &str) -> Result<Library, String> { - probe_library(name).map_err(|e| e.to_string()) -} - -/// Simple shortcut for using all default options for finding a library. -pub fn probe_library(name: &str) -> Result<Library, Error> { - Config::new().probe(name) -} - -/// Run `pkg-config` to get the value of a variable from a package using -/// --variable. -pub fn get_variable(package: &str, variable: &str) -> Result<String, Error> { - let arg = format!("--variable={}", variable); - let cfg = Config::new(); - let out = run(cfg.command(package, &[&arg]))?; - Ok(str::from_utf8(&out).unwrap().trim_right().to_owned()) -} - -impl Config { - /// Creates a new set of configuration options which are all initially set - /// to "blank". - pub fn new() -> Config { - Config { - statik: None, - atleast_version: None, - extra_args: vec![], - print_system_libs: true, - cargo_metadata: true, - env_metadata: false, - } - } - - /// Indicate whether the `--static` flag should be passed. - /// - /// This will override the inference from environment variables described in - /// the crate documentation. - pub fn statik(&mut self, statik: bool) -> &mut Config { - self.statik = Some(statik); - self - } - - /// Indicate that the library must be at least version `vers`. - pub fn atleast_version(&mut self, vers: &str) -> &mut Config { - self.atleast_version = Some(vers.to_string()); - self - } - - /// Add an argument to pass to pkg-config. - /// - /// It's placed after all of the arguments generated by this library. - pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Config { - self.extra_args.push(arg.as_ref().to_os_string()); - self - } - - /// Define whether metadata should be emitted for cargo allowing it to - /// automatically link the binary. Defaults to `true`. - pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Config { - self.cargo_metadata = cargo_metadata; - self - } - - /// Define whether metadata should be emitted for cargo allowing to - /// automatically rebuild when environment variables change. Defaults to - /// `false`. - pub fn env_metadata(&mut self, env_metadata: bool) -> &mut Config { - self.env_metadata = env_metadata; - self - } - - /// Enable or disable the `PKG_CONFIG_ALLOW_SYSTEM_LIBS` environment - /// variable. - /// - /// This env var is enabled by default. - pub fn print_system_libs(&mut self, print: bool) -> &mut Config { - self.print_system_libs = print; - self - } - - /// Deprecated in favor fo the `probe` function - #[doc(hidden)] - pub fn find(&self, name: &str) -> Result<Library, String> { - self.probe(name).map_err(|e| e.to_string()) - } - - /// Run `pkg-config` to find the library `name`. - /// - /// This will use all configuration previously set to specify how - /// `pkg-config` is run. - pub fn probe(&self, name: &str) -> Result<Library, Error> { - let abort_var_name = format!("{}_NO_PKG_CONFIG", envify(name)); - if self.env_var_os(&abort_var_name).is_some() { - return Err(Error::EnvNoPkgConfig(abort_var_name)) - } else if !target_supported() { - return Err(Error::CrossCompilation); - } - - let mut library = Library::new(); - - let output = run(self.command(name, &["--libs", "--cflags"]))?; - library.parse_libs_cflags(name, &output, self); - - let output = run(self.command(name, &["--modversion"]))?; - library.parse_modversion(str::from_utf8(&output).unwrap()); - - Ok(library) - } - - /// Deprecated in favor of the top level `get_variable` function - #[doc(hidden)] - pub fn get_variable(package: &str, variable: &str) -> Result<String, String> { - get_variable(package, variable).map_err(|e| e.to_string()) - } - - fn targetted_env_var(&self, var_base: &str) -> Result<String, env::VarError> { - if let Ok(target) = env::var("TARGET") { - let host = env::var("HOST")?; - let kind = if host == target { "HOST" } else { "TARGET" }; - let target_u = target.replace("-", "_"); - - self.env_var(&format!("{}_{}", var_base, target)) - .or_else(|_| self.env_var(&format!("{}_{}", var_base, target_u))) - .or_else(|_| self.env_var(&format!("{}_{}", kind, var_base))) - .or_else(|_| self.env_var(var_base)) - } else { - self.env_var(var_base) - } - } - - fn env_var(&self, name: &str) -> Result<String, env::VarError> { - if self.env_metadata { - println!("cargo:rerun-if-env-changed={}", name); - } - env::var(name) - } - - fn env_var_os(&self, name: &str) -> Option<OsString> { - if self.env_metadata { - println!("cargo:rerun-if-env-changed={}", name); - } - env::var_os(name) - } - - fn is_static(&self, name: &str) -> bool { - self.statik.unwrap_or_else(|| self.infer_static(name)) - } - - fn command(&self, name: &str, args: &[&str]) -> Command { - let exe = self.env_var("PKG_CONFIG").unwrap_or_else(|_| String::from("pkg-config")); - let mut cmd = Command::new(exe); - if self.is_static(name) { - cmd.arg("--static"); - } - cmd.args(args) - .args(&self.extra_args); - - if let Ok(value) = self.targetted_env_var("PKG_CONFIG_PATH") { - cmd.env("PKG_CONFIG_PATH", value); - } - if let Ok(value) = self.targetted_env_var("PKG_CONFIG_LIBDIR") { - cmd.env("PKG_CONFIG_LIBDIR", value); - } - if let Ok(value) = self.targetted_env_var("PKG_CONFIG_SYSROOT_DIR") { - cmd.env("PKG_CONFIG_SYSROOT_DIR", value); - } - if self.print_system_libs { - cmd.env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1"); - } - if let Some(ref version) = self.atleast_version { - cmd.arg(&format!("{} >= {}", name, version)); - } else { - cmd.arg(name); - } - cmd - } - - fn print_metadata(&self, s: &str) { - if self.cargo_metadata { - println!("cargo:{}", s); - } - } - - fn infer_static(&self, name: &str) -> bool { - let name = envify(name); - if self.env_var_os(&format!("{}_STATIC", name)).is_some() { - true - } else if self.env_var_os(&format!("{}_DYNAMIC", name)).is_some() { - false - } else if self.env_var_os("PKG_CONFIG_ALL_STATIC").is_some() { - true - } else if self.env_var_os("PKG_CONFIG_ALL_DYNAMIC").is_some() { - false - } else { - false - } - } -} - -impl Library { - fn new() -> Library { - Library { - libs: Vec::new(), - link_paths: Vec::new(), - include_paths: Vec::new(), - frameworks: Vec::new(), - framework_paths: Vec::new(), - defines: HashMap::new(), - version: String::new(), - _priv: (), - } - } - - fn parse_libs_cflags(&mut self, name: &str, output: &[u8], config: &Config) { - let mut is_msvc = false; - if let Ok(target) = env::var("TARGET") { - if target.contains("msvc") { - is_msvc = true; - } - } - - let words = split_flags(output); - let parts = words.iter() - .filter(|l| l.len() > 2) - .map(|arg| (&arg[0..2], &arg[2..])) - .collect::<Vec<_>>(); - - let mut dirs = Vec::new(); - let statik = config.is_static(name); - for &(flag, val) in &parts { - match flag { - "-L" => { - let meta = format!("rustc-link-search=native={}", val); - config.print_metadata(&meta); - dirs.push(PathBuf::from(val)); - self.link_paths.push(PathBuf::from(val)); - } - "-F" => { - let meta = format!("rustc-link-search=framework={}", val); - config.print_metadata(&meta); - self.framework_paths.push(PathBuf::from(val)); - } - "-I" => { - self.include_paths.push(PathBuf::from(val)); - } - "-l" => { - // These are provided by the CRT with MSVC - if is_msvc && ["m", "c", "pthread"].contains(&val) { - continue; - } - - if statik && is_static_available(val, &dirs) { - let meta = format!("rustc-link-lib=static={}", val); - config.print_metadata(&meta); - } else { - let meta = format!("rustc-link-lib={}", val); - config.print_metadata(&meta); - } - - self.libs.push(val.to_string()); - } - "-D" => { - let mut iter = val.split("="); - self.defines.insert(iter.next().unwrap().to_owned(), iter.next().map(|s| s.to_owned())); - } - _ => {} - } - } - - let mut iter = words.iter() - .flat_map(|arg| if arg.starts_with("-Wl,") { - arg[4..].split(',').collect() - } else { - vec![arg.as_ref()] - }); - while let Some(part) = iter.next() { - if part != "-framework" { - continue - } - if let Some(lib) = iter.next() { - let meta = format!("rustc-link-lib=framework={}", lib); - config.print_metadata(&meta); - self.frameworks.push(lib.to_string()); - } - } - } - - fn parse_modversion(&mut self, output: &str) { - self.version.push_str(output.trim()); - } -} - -fn envify(name: &str) -> String { - name.chars().map(|c| c.to_ascii_uppercase()).map(|c| { - if c == '-' {'_'} else {c} - }).collect() -} - -/// System libraries should only be linked dynamically -fn is_static_available(name: &str, 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() - }) -} - -fn run(mut cmd: Command) -> Result<Vec<u8>, Error> { - match cmd.output() { - Ok(output) => { - if output.status.success() { - Ok(output.stdout) - } else { - Err(Error::Failure { - command: format!("{:?}", cmd), - output: output, - }) - } - } - Err(cause) => Err(Error::Command { - command: format!("{:?}", cmd), - cause: cause, - }), - } -} - -/// Split output produced by pkg-config --cflags and / or --libs into separate flags. -/// -/// Backslash in output is used to preserve literal meaning of following byte. Different words are -/// separated by unescaped space. Other whitespace characters generally should not occur unescaped -/// at all, apart from the newline at the end of output. For compatibility with what others -/// consumers of pkg-config output would do in this scenario, they are used here for splitting as -/// well. -fn split_flags(output: &[u8]) -> Vec<String> { - let mut word = Vec::new(); - let mut words = Vec::new(); - let mut escaped = false; - - for &b in output { - match b { - _ if escaped => { - escaped = false; - word.push(b); - } - b'\\' => { - escaped = true - } - b'\t' | b'\n' | b'\r' | b' ' => { - if !word.is_empty() { - words.push(String::from_utf8(word).unwrap()); - word = Vec::new(); - } - } - _ => word.push(b), - } - } - - if !word.is_empty() { - words.push(String::from_utf8(word).unwrap()); - } - - words -} - -#[test] -#[cfg(target_os = "macos")] -fn system_library_mac_test() { - assert!(!is_static_available("PluginManager", &[PathBuf::from("/Library/Frameworks")])); - assert!(!is_static_available("python2.7", &[PathBuf::from("/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config")])); - assert!(!is_static_available("ffi_convenience", &[PathBuf::from("/Library/Ruby/Gems/2.0.0/gems/ffi-1.9.10/ext/ffi_c/libffi-x86_64/.libs")])); - - // Homebrew is in /usr/local, and it's not a part of the OS - if Path::new("/usr/local/lib/libpng16.a").exists() { - assert!(is_static_available("png16", &[PathBuf::from("/usr/local/lib")])); - } -} - -#[test] -#[cfg(target_os = "linux")] -fn system_library_linux_test() { - assert!(!is_static_available("util", &[PathBuf::from("/usr/lib/x86_64-linux-gnu")])); - assert!(!is_static_available("dialog", &[PathBuf::from("/usr/lib")])); -} diff --git a/pkg-config/tests/escape.pc b/pkg-config/tests/escape.pc deleted file mode 100644 index 701c4bf..0000000 --- a/pkg-config/tests/escape.pc +++ /dev/null @@ -1,5 +0,0 @@ -Name: Escape -Version: 4.2.0 -Description: Escape utility library -Libs: -Llink\ path\ with\ spaces -Cflags: -Iinclude\ path\ with\ spaces -DA=\"escaped\ string\'\ literal\" -DB=ESCAPED\ IDENTIFIER -DFOX=🦊 diff --git a/pkg-config/tests/foo.pc b/pkg-config/tests/foo.pc deleted file mode 100644 index b1ae3d8..0000000 --- a/pkg-config/tests/foo.pc +++ /dev/null @@ -1,16 +0,0 @@ -prefix=/usr -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include/valgrind -arch=amd64 -os=linux -platform=amd64-linux -valt_load_address=0x38000000 - -Name: Valgrind -Description: A dynamic binary instrumentation framework -Version: 3.10.0.SVN -Requires: -Libs: -L${libdir}/valgrind -lcoregrind-amd64-linux -lvex-amd64-linux -lgcc -Cflags: -I${includedir} - diff --git a/pkg-config/tests/framework.pc b/pkg-config/tests/framework.pc deleted file mode 100644 index fec17f4..0000000 --- a/pkg-config/tests/framework.pc +++ /dev/null @@ -1,16 +0,0 @@ -prefix=/usr -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include/valgrind -arch=amd64 -os=linux -platform=amd64-linux -valt_load_address=0x38000000 - -Name: Valgrind -Description: A dynamic binary instrumentation framework -Version: 3.10.0.SVN -Requires: -Libs: -F${libdir} -framework foo -Wl,-framework,bar -Wl,-framework -Wl,baz -Wl,-framework,foobar,-framework,foobaz -Cflags: -I${includedir} - diff --git a/pkg-config/tests/test.rs b/pkg-config/tests/test.rs deleted file mode 100644 index fad0fcf..0000000 --- a/pkg-config/tests/test.rs +++ /dev/null @@ -1,118 +0,0 @@ -extern crate pkg_config; -#[macro_use] -extern crate lazy_static; - -use pkg_config::Error; -use std::env; -use std::sync::Mutex; -use std::path::PathBuf; - -lazy_static! { - static ref LOCK: Mutex<()> = Mutex::new(()); -} - -fn reset() { - for (k, _) in env::vars() { - if k.contains("DYNAMIC") || - k.contains("STATIC") || - k.contains("PKG_CONFIG_ALLOW_CROSS") || - k.contains("FOO_NO_PKG_CONFIG") { - env::remove_var(&k); - } - } - env::remove_var("TARGET"); - env::remove_var("HOST"); - env::set_var("PKG_CONFIG_PATH", &env::current_dir().unwrap().join("tests")); -} - -fn find(name: &str) -> Result<pkg_config::Library, Error> { - pkg_config::probe_library(name) -} - -#[test] -fn cross_disabled() { - let _g = LOCK.lock(); - reset(); - env::set_var("TARGET", "foo"); - env::set_var("HOST", "bar"); - match find("foo") { - Err(Error::CrossCompilation) => {}, - x => panic!("Error::CrossCompilation expected, found `{:?}`", x), - } -} - -#[test] -fn cross_enabled() { - let _g = LOCK.lock(); - reset(); - env::set_var("TARGET", "foo"); - env::set_var("HOST", "bar"); - env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); - find("foo").unwrap(); -} - -#[test] -fn package_disabled() { - let _g = LOCK.lock(); - reset(); - env::set_var("FOO_NO_PKG_CONFIG", "1"); - match find("foo") { - Err(Error::EnvNoPkgConfig(name)) => { - assert_eq!(name, "FOO_NO_PKG_CONFIG") - } - x => panic!("Error::EnvNoPkgConfig expected, found `{:?}`", x), - } -} - -#[test] -fn output_ok() { - let _g = LOCK.lock(); - reset(); - let lib = find("foo").unwrap(); - assert!(lib.libs.contains(&"gcc".to_string())); - assert!(lib.libs.contains(&"coregrind-amd64-linux".to_string())); - assert!(lib.link_paths.contains(&PathBuf::from("/usr/lib/valgrind"))); -} - -#[test] -fn escapes() { - let _g = LOCK.lock(); - reset(); - let lib = find("escape").unwrap(); - assert!(lib.include_paths.contains(&PathBuf::from("include path with spaces"))); - assert!(lib.link_paths.contains(&PathBuf::from("link path with spaces"))); - assert_eq!(lib.defines.get("A"), - Some(&Some("\"escaped string' literal\"".to_owned()))); - assert_eq!(lib.defines.get("B"), - Some(&Some("ESCAPED IDENTIFIER".to_owned()))); - assert_eq!(lib.defines.get("FOX"), - Some(&Some("🦊".to_owned()))); -} - -#[test] -fn framework() { - let _g = LOCK.lock(); - reset(); - let lib = find("framework").unwrap(); - assert!(lib.frameworks.contains(&"foo".to_string())); - assert!(lib.frameworks.contains(&"bar".to_string())); - assert!(lib.frameworks.contains(&"baz".to_string())); - assert!(lib.frameworks.contains(&"foobar".to_string())); - assert!(lib.frameworks.contains(&"foobaz".to_string())); - assert!(lib.framework_paths.contains(&PathBuf::from("/usr/lib"))); -} - -#[test] -fn get_variable() { - let _g = LOCK.lock(); - reset(); - let prefix = pkg_config::get_variable("foo", "prefix").unwrap(); - assert_eq!(prefix, "/usr"); -} - -#[test] -fn version() { - let _g = LOCK.lock(); - reset(); - assert_eq!(&find("foo").unwrap().version[..], "3.10.0.SVN"); -} |