In case this is useful to someone else, here is the build script that I’m adding to rust-url:
use std::process::{Command, Stdio};
use std::io::Write;
fn main() {
let mut child = Command::new(option_env!("RUSTC").unwrap_or("rustc"))
.args(&["-", "--crate-type", "lib", "-Z", "no-trans"])
.stdin(Stdio::piped())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.unwrap();
child.stdin.as_mut().unwrap().write_all(b"use std::net::IpAddr;").unwrap();
if child.wait().unwrap().success() {
// We can use `IpAddr` as it is `#[stable]` in this version of Rust.
println!("cargo:rustc-cfg=has_ipaddr")
}
}
It compiles a small program (here just use std::net::IpAddr;
) silently. If that succeeds, it enables a cfg
flag that is used in the library like this:
#[cfg(has_ipaddr)] use std::net::IpAddr;
// ...
impl Url {
#[cfg(has_ipaddr)]
pub fn ip(&self) -> Option<IpAddr> { /* ... */ }
}
It’s like an optional Cargo feature with [features]
in Cargo.toml
, except it’s always enabled when possible. Users don’t need to enable it explicitly. It’s also more robust than testing rustc --version
since you don’t have to figure out relevant versions numbers.