#link #native #pkg-config #linker #directive #execution #detect

yanked link-config

Compile-time execution of pkg-config to detect what #[link] directives should be inserted for linking to a native library

Uses old Rust 2015

0.1.1 Dec 16, 2014
0.1.0 Dec 8, 2014
0.0.2 Nov 23, 2014
0.0.1 Nov 23, 2014

#22 in #directive


Used in libnanomsg

MIT/Apache

13KB
259 lines

link-config

A syntax extension for Rust that runs pkg-config at build-time to figure how how to link native dependencies.

#![feature(phase)]

#[phase(plugin)]
extern crate link_config = "link-config";

link_config!("libcurl")

extern {
    fn curl_easy_init() -> *mut ();
}

fn main() {
    let handle = unsafe { curl_easy_init() };
    // ...
}

Dynamic vs Static linking

An invocation of the link_config! macro will generate two extern blocks that look like:

// foo.rs
link_config!("mylib")

// foo-expanded.rs
#[cfg(statik = "mylib")]
#[link(..., kind = "static")]
extern {}

#[cfg(not(statik = "mylib"))]
#[link(...)]
extern {}

This means that a dynamic dependency is the default, but a static dependency can be specified via:

$ rustc foo.rs --cfg 'statik="mylib"'

Configuring emission

The full syntax for an invocation is currently:

link_config!("foo", ["bar", "baz"])

The library being linked is called foo and both bar/baz are options to the link_config! macro itself. The currently known options are:

  • only_static - Only emit a block for a static linkage, and enable it by default.
  • only_dylib - Only emit a block for a dynamic linkage, and enable it by default.
  • favor_static - Instead of emiting not(statik = "mylib"), emit not(dylib = "mylib"), favoring the static block by default.
  • system_static - Allow system dependencies to be statically linked. This is not allowed by default.

How does it work?

When linking native libraries, this syntax extension is interested in answering three questions:

  • What is the local name of the native library?
  • What are the dependencies of the native library?
  • Where is everything located?

This library is not interested in various platform-specific flags to the linker and other various configuration options that are not always necessary.

To answer these questions, this library currently shells out to pkg-config at build time with the --libs option and filters the return value to answer the questions above. For static linking the tool is invoked with --static

The syntax extension then generates an extern block with appropriate #[link] and #[cfg] attributes.

TODO list

  • Custom rust script to have platform-specific logic for determining libraries and dependencies. This will also be useful for tools that don't necessarily use pkg-config like LLVM or postgres.
  • Integrate pkgconf as a fallback if pkg-config is not available.

License

link-config is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses.

See LICENSE-APACHE, and LICENSE-MIT for details.

No runtime deps