Reform version checking logic

Rather than having an infinitely growing set of things to look for, just
grab the literal version out. We also provide that to downstream crates,
and it should be used rather than the random assortment of other stuff
that's also passed down.
This commit is contained in:
Steven Fackler 2018-04-26 22:45:09 -07:00
parent 24ece94e99
commit 03a4c6bd26
3 changed files with 120 additions and 143 deletions

View File

@ -9,7 +9,6 @@ use std::ffi::OsString;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf};
use std::panic::{self, AssertUnwindSafe};
use std::process::Command;
// The set of `OPENSSL_NO_<FOO>`s that we care about.
@ -326,42 +325,13 @@ fn validate_headers(include_dirs: &[PathBuf]) -> Version {
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
#if LIBRESSL_VERSION_NUMBER >= 0x20800000
RUST_LIBRESSL_NEW
#elif LIBRESSL_VERSION_NUMBER >= 0x20700000
RUST_LIBRESSL_27X
#elif LIBRESSL_VERSION_NUMBER >= 0x20603000
RUST_LIBRESSL_26X
#elif LIBRESSL_VERSION_NUMBER >= 0x20602000
RUST_LIBRESSL_262
#elif LIBRESSL_VERSION_NUMBER >= 0x20601000
RUST_LIBRESSL_261
#elif LIBRESSL_VERSION_NUMBER >= 0x20600000
RUST_LIBRESSL_260
#elif LIBRESSL_VERSION_NUMBER >= 0x20503000
RUST_LIBRESSL_25X
#elif LIBRESSL_VERSION_NUMBER >= 0x20502000
RUST_LIBRESSL_252
#elif LIBRESSL_VERSION_NUMBER >= 0x20501000
RUST_LIBRESSL_251
#elif LIBRESSL_VERSION_NUMBER >= 0x20500000
RUST_LIBRESSL_250
#elif defined (LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20500000
RUST_LIBRESSL_OLD
#elif OPENSSL_VERSION_NUMBER >= 0x10102000
RUST_OPENSSL_NEW
#elif OPENSSL_VERSION_NUMBER >= 0x10101000
RUST_OPENSSL_111
#elif OPENSSL_VERSION_NUMBER >= 0x10100060
RUST_OPENSSL_110F
#elif OPENSSL_VERSION_NUMBER >= 0x10100000
RUST_OPENSSL_110
#elif OPENSSL_VERSION_NUMBER >= 0x10002000
RUST_OPENSSL_102
#elif OPENSSL_VERSION_NUMBER >= 0x10001000
RUST_OPENSSL_101
#else
RUST_OPENSSL_OLD
#define VERSION2(n, v) RUST_VERSION_ ## n ## _ ## v
#define VERSION(n, v) VERSION2(n, v)
VERSION(OPENSSL, OPENSSL_VERSION_NUMBER)
#ifdef LIBRESSL_VERSION_NUMBER
VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER)
#endif
"
).unwrap();
@ -371,7 +341,7 @@ RUST_OPENSSL_OLD
file,
"\
#ifdef {define}
RUST_{define}_RUST
RUST_CONF_{define}
#endif
",
define = define
@ -386,11 +356,14 @@ RUST_{define}_RUST
gcc.include(include_dir);
}
// https://github.com/alexcrichton/gcc-rs/issues/133
let expanded = match panic::catch_unwind(AssertUnwindSafe(|| gcc.file(&path).expand())) {
let expanded = match gcc.file(&path).try_expand() {
Ok(expanded) => expanded,
Err(_) => {
Err(e) => {
panic!(
"
Header expansion error:
{:?}
Failed to find OpenSSL development headers.
You can try fixing this setting the `OPENSSL_DIR` environment variable
@ -407,108 +380,98 @@ specific to your distribution:
See rust-openssl README for more information:
https://github.com/sfackler/rust-openssl#linux
"
",
e
);
}
};
let expanded = String::from_utf8(expanded).unwrap();
let mut enabled = vec![];
for &define in DEFINES {
if expanded.contains(&format!("RUST_{}_RUST", define)) {
println!("cargo:rustc-cfg=osslconf=\"{}\"", define);
enabled.push(define);
let mut openssl_version = None;
let mut libressl_version = None;
for line in expanded.lines() {
let line = line.trim();
let openssl_prefix = "RUST_VERSION_OPENSSL_";
let libressl_prefix = "RUST_VERSION_LIBRESSL_";
let conf_prefix = "RUST_CONF_";
if line.starts_with(openssl_prefix) {
let version = &line[openssl_prefix.len()..];
openssl_version = Some(parse_version(version));
} else if line.starts_with(libressl_prefix) {
let version = &line[libressl_prefix.len()..];
libressl_version = Some(parse_version(version));
} else if line.starts_with(conf_prefix) {
enabled.push(&line[conf_prefix.len()..]);
}
}
for enabled in &enabled {
println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled);
}
println!("cargo:conf={}", enabled.join(","));
if expanded.contains("RUST_LIBRESSL_250") {
if let Some(libressl_version) = libressl_version {
println!("cargo:libressl_version_number={:x}", libressl_version);
let minor = (libressl_version >> 20) as u8;
let fix = (libressl_version >> 12) as u8;
let (minor, fix) = match (minor, fix) {
(5, 0) => ('5', '0'),
(5, 1) => ('5', '1'),
(5, 2) => ('5', '2'),
(5, _) => ('5', 'x'),
(6, 0) => ('6', '0'),
(6, 1) => ('6', '1'),
(6, 2) => ('6', '2'),
(6, _) => ('6', 'x'),
(7, _) => ('7', 'x'),
_ => version_error(),
};
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl250");
println!("cargo:rustc-cfg=libressl2{}{}", minor, fix);
println!("cargo:libressl=true");
println!("cargo:libressl_version=250");
println!("cargo:libressl_version=2{}{}", minor, fix);
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_251") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl251");
println!("cargo:libressl=true");
println!("cargo:libressl_version=251");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_252") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl252");
println!("cargo:libressl=true");
println!("cargo:libressl_version=252");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_25X") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl25x");
println!("cargo:libressl=true");
println!("cargo:libressl_version=25x");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_260") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl260");
println!("cargo:libressl=true");
println!("cargo:libressl_version=260");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_261") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl261");
println!("cargo:libressl=true");
println!("cargo:libressl_version=261");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_262") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl262");
println!("cargo:libressl=true");
println!("cargo:libressl_version=262");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_26X") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl26x");
println!("cargo:libressl=true");
println!("cargo:libressl_version=26x");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_27X") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl27");
println!("cargo:libressl=true");
println!("cargo:libressl_version=27x");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_OPENSSL_111") {
} else {
let openssl_version = openssl_version.unwrap();
println!("cargo:version_number={:x}", openssl_version);
if openssl_version >= 0x1_01_02_00_0 {
version_error()
} else if openssl_version >= 0x1_01_01_00_0 {
println!("cargo:rustc-cfg=ossl111");
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=111");
Version::Openssl110
} else if expanded.contains("RUST_OPENSSL_110F") {
} else if openssl_version >= 0x1_01_00_06_0 {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:rustc-cfg=ossl110f");
println!("cargo:version=110");
println!("cargo:patch=f");
Version::Openssl110
} else if expanded.contains("RUST_OPENSSL_110") {
} else if openssl_version >= 0x1_01_00_00_0 {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=110");
Version::Openssl110
} else if expanded.contains("RUST_OPENSSL_102") {
} else if openssl_version >= 0x1_00_02_00_0 {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:version=102");
Version::Openssl102
} else if expanded.contains("RUST_OPENSSL_101") {
} else if openssl_version >= 0x1_00_01_00_0 {
println!("cargo:rustc-cfg=ossl101");
println!("cargo:version=101");
Version::Openssl101
} else {
version_error()
}
}
}
fn version_error() -> ! {
panic!(
"
@ -518,7 +481,21 @@ due to this version mismatch.
"
);
}
}
// parses a string that looks like "0x100020cfL"
fn parse_version(version: &str) -> u64 {
// cut off the 0x prefix
assert!(version.starts_with("0x"));
let version = &version[2..];
// and the type specifier suffix
let version = version.trim_right_matches(|c: char| match c {
'0'...'9' | 'a'...'f' | 'A'...'F' => false,
_ => true,
});
u64::from_str_radix(version, 16).unwrap()
}
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name

View File

@ -5,8 +5,8 @@
extern crate libc;
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t, FILE};
use std::ptr;
use std::mem;
use std::ptr;
#[cfg(any(ossl101, ossl102))]
mod ossl10x;
@ -1277,14 +1277,14 @@ pub const SSL_VERIFY_NONE: c_int = 0;
pub const SSL_VERIFY_PEER: c_int = 1;
pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27, ossl101)))]
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x, ossl101)))]
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x00000010;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27))]
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x0;
pub const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: c_ulong = 0x00000800;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27)))]
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))]
pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x80000000;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27))]
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x0;
pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004;
#[cfg(not(libressl))]

View File

@ -1,7 +1,7 @@
use std::sync::{Mutex, MutexGuard};
use std::sync::{Once, ONCE_INIT};
use std::mem;
use std::ptr;
use std::sync::{Mutex, MutexGuard};
use std::sync::{Once, ONCE_INIT};
#[cfg(libressl250)]
pub use libressl::v250::*;
@ -337,9 +337,9 @@ pub const SSL_CTRL_OPTIONS: c_int = 32;
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27))]
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
pub const SSL_OP_ALL: c_ulong = 0x4;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27)))]
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))]
pub const SSL_OP_ALL: c_ulong = 0x80000014;
pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0;
pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x0;
@ -352,9 +352,9 @@ pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x0;
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x0;
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x0;
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x0;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27))]
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x0;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27)))]
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))]
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
pub const SSL_OP_NO_SSLv2: c_ulong = 0x0;