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::fs::File;
use std::io::{BufWriter, Write}; use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::panic::{self, AssertUnwindSafe};
use std::process::Command; use std::process::Command;
// The set of `OPENSSL_NO_<FOO>`s that we care about. // The set of `OPENSSL_NO_<FOO>`s that we care about.
@ -133,7 +132,7 @@ Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
compilation process. compilation process.
Make sure you also have the development packages of openssl installed. Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.
@ -326,42 +325,13 @@ fn validate_headers(include_dirs: &[PathBuf]) -> Version {
#include <openssl/opensslv.h> #include <openssl/opensslv.h>
#include <openssl/opensslconf.h> #include <openssl/opensslconf.h>
#if LIBRESSL_VERSION_NUMBER >= 0x20800000 #define VERSION2(n, v) RUST_VERSION_ ## n ## _ ## v
RUST_LIBRESSL_NEW #define VERSION(n, v) VERSION2(n, v)
#elif LIBRESSL_VERSION_NUMBER >= 0x20700000
RUST_LIBRESSL_27X VERSION(OPENSSL, OPENSSL_VERSION_NUMBER)
#elif LIBRESSL_VERSION_NUMBER >= 0x20603000
RUST_LIBRESSL_26X #ifdef LIBRESSL_VERSION_NUMBER
#elif LIBRESSL_VERSION_NUMBER >= 0x20602000 VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER)
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
#endif #endif
" "
).unwrap(); ).unwrap();
@ -371,7 +341,7 @@ RUST_OPENSSL_OLD
file, file,
"\ "\
#ifdef {define} #ifdef {define}
RUST_{define}_RUST RUST_CONF_{define}
#endif #endif
", ",
define = define define = define
@ -386,11 +356,14 @@ RUST_{define}_RUST
gcc.include(include_dir); gcc.include(include_dir);
} }
// https://github.com/alexcrichton/gcc-rs/issues/133 // 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, Ok(expanded) => expanded,
Err(_) => { Err(e) => {
panic!( panic!(
" "
Header expansion error:
{:?}
Failed to find OpenSSL development headers. Failed to find OpenSSL development headers.
You can try fixing this setting the `OPENSSL_DIR` environment variable You can try fixing this setting the `OPENSSL_DIR` environment variable
@ -407,118 +380,122 @@ specific to your distribution:
See rust-openssl README for more information: See rust-openssl README for more information:
https://github.com/sfackler/rust-openssl#linux https://github.com/sfackler/rust-openssl#linux
" ",
e
); );
} }
}; };
let expanded = String::from_utf8(expanded).unwrap(); let expanded = String::from_utf8(expanded).unwrap();
let mut enabled = vec![]; let mut enabled = vec![];
for &define in DEFINES { let mut openssl_version = None;
if expanded.contains(&format!("RUST_{}_RUST", define)) { let mut libressl_version = None;
println!("cargo:rustc-cfg=osslconf=\"{}\"", define); for line in expanded.lines() {
enabled.push(define); 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(",")); 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=libressl");
println!("cargo:rustc-cfg=libressl250"); println!("cargo:rustc-cfg=libressl2{}{}", minor, fix);
println!("cargo:libressl=true"); println!("cargo:libressl=true");
println!("cargo:libressl_version=250"); println!("cargo:libressl_version=2{}{}", minor, fix);
println!("cargo:version=101"); println!("cargo:version=101");
Version::Libressl 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") {
println!("cargo:rustc-cfg=ossl111");
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=111");
Version::Openssl110
} else if expanded.contains("RUST_OPENSSL_110F") {
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") {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=110");
Version::Openssl110
} else if expanded.contains("RUST_OPENSSL_102") {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:version=102");
Version::Openssl102
} else if expanded.contains("RUST_OPENSSL_101") {
println!("cargo:rustc-cfg=ossl101");
println!("cargo:version=101");
Version::Openssl101
} else { } else {
panic!( 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 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 openssl_version >= 0x1_01_00_00_0 {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=110");
Version::Openssl110
} else if openssl_version >= 0x1_00_02_00_0 {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:version=102");
Version::Openssl102
} 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!(
"
This crate is only compatible with OpenSSL 1.0.1 through 1.1.1, or LibreSSL 2.5 This crate is only compatible with OpenSSL 1.0.1 through 1.1.1, or LibreSSL 2.5
through 2.7, but a different version of OpenSSL was found. The build is now aborting through 2.7, but a different version of OpenSSL was found. The build is now aborting
due to this version mismatch. 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 /// Given a libdir for OpenSSL (where artifacts are located) as well as the name

View File

@ -5,8 +5,8 @@
extern crate libc; extern crate libc;
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t, FILE}; 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::mem;
use std::ptr;
#[cfg(any(ossl101, ossl102))] #[cfg(any(ossl101, ossl102))]
mod ossl10x; 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_PEER: c_int = 1;
pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2; 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; 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_TLSEXT_PADDING: c_ulong = 0x0;
pub const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: c_ulong = 0x00000800; 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; 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_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x0;
pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004; pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004;
#[cfg(not(libressl))] #[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::mem;
use std::ptr; use std::ptr;
use std::sync::{Mutex, MutexGuard};
use std::sync::{Once, ONCE_INIT};
#[cfg(libressl250)] #[cfg(libressl250)]
pub use libressl::v250::*; 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_CLEAR_OPTIONS: c_int = 77;
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94; 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; 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_ALL: c_ulong = 0x80000014;
pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0; pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0;
pub const SSL_OP_NO_COMPRESSION: 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_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x0;
pub const SSL_OP_TLS_D5_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; 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; 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_ECDH_USE: c_ulong = 0x00080000;
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000; pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
pub const SSL_OP_NO_SSLv2: c_ulong = 0x0; pub const SSL_OP_NO_SSLv2: c_ulong = 0x0;