libperl_config/lib.rs
1//! # libperl-config
2//!
3//! Build-time helper for crates that link against `libperl`. Reads the
4//! local Perl installation's `Config.pm` (via `perl -V:...`) and turns
5//! the answers into `cargo:` directives + `cfg(...)` flags.
6//!
7//! Used by [`libperl-sys`](https://docs.rs/libperl-sys) and
8//! [`libperl-rs`](https://docs.rs/libperl-rs) build scripts to:
9//!
10//! - emit `cargo:rustc-link-search` / `rustc-link-lib` / `rustc-link-arg`
11//! from `$Config{ccopts}` and `$Config{ldopts}`,
12//! - expose feature toggles like `cfg(perl_useithreads)` based on
13//! `$Config{useithreads}`,
14//! - emit per-API-version cfgs (`cfg(perlapi_ver26)` ...
15//! `cfg(perlapi_ver42)`) so source can branch on Perl version.
16//!
17//! Typical usage in a downstream `build.rs`:
18//!
19//! ```no_run
20//! use libperl_config::PerlConfig;
21//!
22//! fn main() {
23//! let config = PerlConfig::default();
24//! config.emit_cargo_ldopts();
25//! config.emit_features(&["useithreads"]);
26//! config.emit_all_perlapi_versions(10);
27//! }
28//! ```
29//!
30//! ## Selecting which perl to build against
31//!
32//! By default the `perl` found on `PATH` is used. Set the `PERL`
33//! environment variable to an absolute path to pick a specific
34//! interpreter — e.g. an ExtUtils::MakeMaker postamble runs
35//! `PERL=$(FULLPERL) cargo build ...` so the perl that ran Makefile.PL
36//! and the perl being linked against are the same. Build scripts are
37//! automatically re-run when `PERL` changes.
38//!
39//! See [`PerlConfig`] for the full API.
40
41mod perl_command;
42pub use perl_command::*;
43
44mod perl_config;
45pub use perl_config::*;
46
47pub mod process_util;
48
49#[cfg(test)]
50mod tests {
51 #[test]
52 fn it_works() {
53 let cfg = super::PerlConfig::default();
54 assert!(cfg.read_ccopts().unwrap().len() > 0);
55 assert!(cfg.read_ldopts().unwrap().len() > 0);
56 }
57
58 #[test]
59 fn can_read_config() {
60 let cfg = super::PerlConfig::default();
61 let perl_version = cfg.dict.get("PERL_VERSION");
62 assert_ne!(perl_version, None);
63 if let Some(ver) = perl_version {
64 let script = r#"
65use strict;
66use Config;
67print "PERL_VERSION\t", $Config{PERL_VERSION};
68"#;
69 assert_eq!(super::process_util::process_command_output(
70 cfg.command(&["-e", script]).output().unwrap()
71 ).unwrap(), ["PERL_VERSION", ver].join("\t"))
72 }
73 }
74}