pkgconf 0.1.0

Parse pkg-config output with proper --whole-archive and static library support
Documentation
  • Coverage
  • 100%
    21 out of 21 items documented6 out of 13 items with examples
  • Size
  • Source code size: 41.43 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.33 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 15s Average build duration of successful builds.
  • all releases: 15s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Documentation
  • youyuanwu/rust-spdk-io
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • youyuanwu

pkgconf

A Rust build helper for parsing pkg-config output with proper --whole-archive and static library support.

Problem

The standard pkg-config crate has limitations:

  1. Flag reordering — It doesn't preserve the ordering of -Wl,--whole-archive and -l flags, breaking linking for libraries with constructor functions (like DPDK's RTE_INIT macros)
  2. Static detection — It doesn't properly distinguish between static and dynamic libraries based on .a file availability

Solution

This crate parses pkg-config output directly and:

  • Tracks --whole-archive regions from the pkg-config output
  • Auto-detects static library availability by checking if lib<name>.a exists
  • Excludes system directories (default: /usr) so system libs link dynamically
  • Emits correct cargo link directives with proper modifiers (static:, +whole-archive, -bundle)

Usage

use pkgconf::PkgConfigParser;

// In build.rs
fn main() {
    PkgConfigParser::new()
        .probe_and_emit(
            ["openssl", "libfoo"],
            None,  // or Some("/custom/pkgconfig/path")
        )
        .expect("pkg-config failed");
}

Force Whole-Archive

For libraries with constructor functions that need --whole-archive:

use pkgconf::PkgConfigParser;

PkgConfigParser::new()
    .force_whole_archive([
        "mylib_with_constructors",
    ])
    .probe_and_emit(["mylib"], None)
    .expect("pkg-config failed");

Custom System Roots

Libraries under system roots link dynamically (even if .a exists):

use pkgconf::PkgConfigParser;

PkgConfigParser::new()
    .system_roots(["/usr", "/usr/local", "/opt/homebrew"])
    .probe_and_emit(["openssl"], None)
    .expect("pkg-config failed");

Link Kinds

Libraries are emitted with one of three link kinds:

Condition Link Kind Cargo Directive
No .a found (or in system dir) Default rustc-link-lib=name
.a exists, outside whole-archive region Static rustc-link-lib=static:-bundle=name
.a exists, inside whole-archive region WholeArchive rustc-link-lib=static:+whole-archive,-bundle=name

Why Constructor Functions Need Whole-Archive

Libraries using __attribute__((constructor)) or macros like DPDK's RTE_INIT register functionality at load time. Without --whole-archive, the linker discards these "unused" symbols, causing registration to fail silently.

License

MIT