Skip to content

Improve docs for cross-compilation #113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main() {

# External configuration via target-scoped environment variables

In cross-compilation context, it is useful to manage separately PKG_CONFIG_PATH
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
Expand All @@ -53,7 +53,13 @@ Each of these variables can also be supplied with certain prefixes and suffixes,
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.
This crate will allow `pkg-config` to be used in cross-compilation
if `PKG_CONFIG_SYSROOT_DIR` or `PKG_CONFIG` is set. You can set `PKG_CONFIG_ALLOW_CROSS=1`
to bypass the compatibility check, but please note that enabling use of `pkg-config` in
cross-compilation without appropriate sysroot and search paths set is likely to break builds.

Some Rust sys crates support building vendored libraries from source, which may be a work
around for lack of cross-compilation support in `pkg-config`.

# License

Expand Down
33 changes: 24 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
//! 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`.
//!
//! * `PKG_CONFIG_ALLOW_CROSS` - The `pkg-config` command usually doesn't
//! support cross-compilation, and this crate prevents it from selecting
//! incompatible versions of libraries.
//! Setting `PKG_CONFIG_ALLOW_CROSS=1` disables this protection, which is
//! likely to cause linking errors, unless `pkg-config` has been configured
//! to use appropriate sysroot and search paths for the target platform.
//!
//! 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
Expand Down Expand Up @@ -106,9 +111,11 @@ pub enum Error {
/// Contains the name of the responsible environment variable.
EnvNoPkgConfig(String),

/// Cross compilation detected.
/// Detected cross compilation without a custom sysroot.
///
/// Override with `PKG_CONFIG_ALLOW_CROSS=1`.
/// Ignore the error with `PKG_CONFIG_ALLOW_CROSS=1`,
/// which may let `pkg-config` select libraries
/// for the host's architecture instead of the target's.
CrossCompilation,

/// Failed to run `pkg-config`.
Expand All @@ -132,10 +139,13 @@ 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::CrossCompilation => f.write_str(
"pkg-config has not been configured to support cross-compilation.

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."
),
Error::Command {
ref command,
Expand Down Expand Up @@ -177,7 +187,12 @@ pub fn probe_library(name: &str) -> Result<Library, Error> {
}

/// Run `pkg-config` to get the value of a variable from a package using
/// --variable.
/// `--variable`.
///
/// The content of `PKG_CONFIG_SYSROOT_DIR` is not injected in paths that are
/// returned by `pkg-config --variable`, which makes them unsuitable to use
/// during cross-compilation unless specifically designed to be used
/// at that time.
pub fn get_variable(package: &str, variable: &str) -> Result<String, Error> {
let arg = format!("--variable={}", variable);
let cfg = Config::new();
Expand Down