-
Notifications
You must be signed in to change notification settings - Fork 2.7k
pkgconfig-dependencies #16281
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
base: master
Are you sure you want to change the base?
pkgconfig-dependencies #16281
Conversation
Add declarative pkg-config dependency support to Cargo.toml with automatic
metadata generation and compile-time constants. This implements the core
foundation for the [pkgconfig-dependencies] table specification.
## Changes
### Schema & Parsing (cargo-util-schemas)
- Add TomlPkgConfigDependency enum supporting simple and detailed forms
- Support version constraints, alternative package names, optional flag
- Integrate into TomlManifest and TomlPlatform for target-specific deps
### TOML Processing (src/cargo/util/toml/mod.rs)
- Implement normalize_pkgconfig_dependencies() with validation
- Validate version constraints at parse time
- Detect unused manifest keys for better error messages
### Manifest Integration (src/cargo/core/manifest.rs)
- Add pkgconfig_dependencies field to Manifest struct
- Extract from normalized TOML during manifest construction
- Expose public accessor for build system integration
### Pkg-Config Module (src/cargo/core/compiler/pkgconfig.rs)
- query_pkg_config(): Query system pkg-config with version constraints
- probe_all_dependencies(): Batch probe for all declared dependencies
- generate_metadata_file(): Generate Rust code with compile-time constants
- sanitize_module_name(): Convert package names to valid Rust identifiers
- probe_and_generate_metadata(): Main entry point for build integration
Generated pkgconfig_meta.rs constants:
- VERSION: Package version from pkg-config
- FOUND: Whether dependency was successfully resolved
- RESOLVED_VIA: Resolution method (pkg-config, fallback, not-found, etc.)
- INCLUDE_PATHS, LIB_PATHS, LIBS: System paths and libraries
- CFLAGS, DEFINES, LDFLAGS: Compiler and linker flags
- RAW_CFLAGS, RAW_LDFLAGS: Raw pkg-config output for debugging
### Feature Gating
- Add pkgconfig_dependencies to -Z unstable options
- Require feature activation when [pkgconfig-dependencies] is used
- Provides clear error message with feature documentation
### Testing
- Unit tests for module name sanitization
- Tests for pkg-config output parsing
- Tests for metadata file generation
- Tests for resolution method conversions
Users can now declare pkg-config dependencies:
[pkgconfig-dependencies]
libfoo = "1.2"
libbar = ">= 2.0, < 3.0"
And access metadata via generated constants:
include!(concat!(env!("OUT_DIR"), "/pkgconfig_meta.rs"));
pub fn get_version() -> &'static str {
pkgconfig::libfoo::VERSION
}
Enabled with: cargo build -Z pkgconfig-dependencies
🤖 Generated with Claude Code
Co-Authored-By: Claude <[email protected]>
…, and fallbacks This adds support for: - Alternative package names (tries multiple pkg-config names in order) - Optional dependencies that don't fail the build if not found - Fallback specifications for manual pkg-config configuration New features: - query_pkg_config() now accepts alternative_names and fallback parameters - apply_fallback() converts fallback specs to PkgConfigLibrary - probe_all_dependencies() handles optional deps by recording NotFound state - Updated tests to verify fallback and metadata generation behavior Also added: - TomlPkgConfigFallback schema struct with libs, lib_paths, include_paths - fallback() accessor on TomlPkgConfigDependency enum - Comprehensive unit tests for fallback scenarios and metadata generation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Enhanced user experience with: - Detailed error messages when pkg-config dependencies fail - Actionable suggestions for fixing missing dependencies - Instructions for using fallbacks and alternative names - Warnings when optional dependencies are not found Documentation improvements: - Module-level documentation with complete usage examples - Detailed docstrings for public functions - Examples of Cargo.toml syntax (simple and detailed forms) - Instructions for accessing generated metadata - Process documentation for probe_and_generate_metadata() Error messages now include: 1. Clear statement of which dependency and version was not found 2. List of pkg-config names that were tried (if multiple) 3. Helpful suggestions: - How to install the library for different distros - Using PKG_CONFIG_PATH environment variable - Adding fallback specifications in Cargo.toml - Using alternative names for packages with multiple names Optional dependencies now log warnings when not found, so users are aware of what's being skipped. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Bug fixes: - Remove unused PathBuf import from pkgconfig.rs - Remove unused parse_pkg_config_output function (we use pkg-config crate's parsing) - Remove corresponding unit test for parse_pkg_config_output - Prefix unused _format_str_array closure with underscore - Remove unused Error import in schema deserialization - Add missing pkgconfig_dependencies field to TomlManifest destructuring - Add missing pkgconfig_dependencies field to TomlPlatform and TomlManifest constructors Documentation: - Add comprehensive [pkgconfig-dependencies] section to manifest.md * Simple and detailed TOML syntax examples * Complete field documentation * Generated metadata module structure * Error handling and optional dependency behavior - Add pkgconfig-dependencies to unstable.md feature list * Detailed feature documentation with motivation * Usage examples (command line and config.toml) * Resolution strategy explanation * Error message examples * Optional dependency handling All documentation follows Cargo's existing documentation patterns and includes practical examples for build scripts and manifest configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
The test_generate_metadata_file_module_naming test was expecting 'gtk_plus_3_0' but the sanitize_module_name function correctly converts '+', '-', and '.' to underscores, resulting in 'gtk__3_0'. Updated the test to match the actual correct behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…pendencies
Implements feature gating:
- Dependencies can now be gated by Cargo features via 'feature' field
- Dependencies with unmet features are recorded as NotProbed
- Simplifies conditional compilation of optional system dependencies
Implements link type support:
- Dependencies can specify how to link ('static', 'dynamic', etc.) via 'link' field
- Link type is tracked through resolution and included in generated metadata
- Generated Rust code includes LINK_TYPE constant for each dependency
Improves logging:
- Replace eprintln! with proper tracing::warn! for optional deps
- Integrates with Cargo's logging infrastructure
Changes:
- Add link_type field to PkgConfigLibrary struct
- Update probe_all_dependencies() to accept enabled_features list
- Feature-gated deps are skipped without probing
- Link type passed through query_pkg_config() and apply_fallback()
- Generated metadata includes LINK_TYPE: Option<&str>
- Update all test fixtures to include link_type field
- Update probe_and_generate_metadata() signature to accept enabled_features
Tests updated:
- test_apply_fallback_creates_library - verify link_type=None
- test_apply_fallback_empty_values - verify link_type is preserved
- All test PkgConfigLibrary instances now include link_type field
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Implements version constraint parsing and validation: - Exact version: '= 3.0' - Minimum version: '>= 3.0' or '3.0' (default) - Version range: '3.0 .. 4.0' or '3.0..4.0' Users can now write: [pkgconfig-dependencies] openssl = '= 1.1.1' # Require exact version sqlite3 = '>= 3.0' # At least version 3.0 zlib = '1.2 .. 1.3' # Range between versions Added apply_version_constraint() helper that parses the constraint syntax and applies the appropriate pkg-config configuration method. Constraints are validated with helpful error messages for invalid ranges. Tests added for all constraint types including edge cases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Add examples and documentation for all version constraint types: - Minimum version: '1.1' or '>= 1.1' - Exact version: '= 1.1' - Version range: '3.0 .. 4.0' Updated examples in both manifest.md and unstable.md to show the different constraint syntaxes with helpful comments. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
If you still need to do work in build.rs, you might as well use I'm not sure this is great advertisement for Claude Code... |
I think the idea is that, given how much functional overlap there would be between the code for the case which does need that and the code for the case without, it makes sense to not encourage staying in the direction of "this codebase contains both Better to have a single source of truth for interfacing with pkg-config but, at the same time, not force everyone to "subsidize" the subset of packages which will need EDIT: In essence, it's extending Cargo's existing "Most crates don't need |
The way to go for that would be to stabilize metabuild and have system-deps support it. There's no need to have Cargo do it. |
|
I I'm reading that correctly, having a (eg. distro build tooling extracting dependencies without running third-party code to extend the |
This PR explores a new unstable feature that allows developers to
declaratively specify system library dependencies in Cargo.toml, eliminating
the need for custom build scripts to probe pkg-config.
With
pkgconfig-dependencies, you can declare system libraries just likeregular Rust dependencies, with support for version constraints, alternative
names, fallback specifications, feature gating, and link type control.
The Problem
Currently, using system libraries in Rust requires manual
build.rsscripts:This is repetitive boilerplate that every project needs to write and maintain.
pkgconfig-dependencies
Simply declare your system dependencies in Cargo.toml:
Enable the feature and build:
Cargo automatically probes pkg-config, generates metadata, and makes it
available to your code.
Usage
Simple Dependencies
Just specify version constraints:
Advanced Configuration
For more control, use the detailed form:
Feature-Gated Dependencies
Build with or without system libraries:
Accessing Library Information
Cargo generates a Rust module with compile-time constants:
Example: Portable OpenSSL
Works everywhere:
Unstable Feature Flag
This feature is behind -Z pkgconfig-dependencies and requires nightly: