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:
- Flag reordering — It doesn't preserve the ordering of
-Wl,--whole-archiveand-lflags, breaking linking for libraries with constructor functions (like DPDK'sRTE_INITmacros) - Static detection — It doesn't properly distinguish between static and dynamic libraries based on
.afile availability
Solution
This crate parses pkg-config output directly and:
- Tracks
--whole-archiveregions from the pkg-config output - Auto-detects static library availability by checking if
lib<name>.aexists - Excludes system directories (default:
/usr) so system libs link dynamically - Emits correct cargo link directives with proper modifiers (
static:,+whole-archive,-bundle)
Usage
use PkgConfigParser;
// In build.rs
Force Whole-Archive
For libraries with constructor functions that need --whole-archive:
use PkgConfigParser;
new
.force_whole_archive
.probe_and_emit
.expect;
Custom System Roots
Libraries under system roots link dynamically (even if .a exists):
use PkgConfigParser;
new
.system_roots
.probe_and_emit
.expect;
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