extern crate cc;
extern crate pkg_config;
#[cfg(target_os = "windows")]
extern crate libflate;
#[cfg(target_os = "windows")]
extern crate reqwest;
#[cfg(target_os = "windows")]
extern crate tar;
use std::env;
use std::path::PathBuf;
#[cfg(feature = "libsodium-bundled")]
use std::process::Command;
#[cfg(all(feature = "libsodium-bundled", not(target_os = "windows")))]
const LIBSODIUM_NAME: &'static str = "libsodium-1.0.17";
#[cfg(all(feature = "libsodium-bundled", not(target_os = "windows")))]
const LIBSODIUM_URL: &'static str =
"https://download.libsodium.org/libsodium/releases/libsodium-1.0.17.tar.gz";
#[cfg(feature = "docs-rs")]
fn main() {}
#[cfg(not(feature = "docs-rs"))]
fn main() {
#[cfg(feature = "libsodium-bundled")]
download_and_install_libsodium();
#[cfg(not(feature = "libsodium-bundled"))]
{
println!("cargo:rerun-if-env-changed=SODIUM_LIB_DIR");
println!("cargo:rerun-if-env-changed=SODIUM_STATIC");
}
if let Ok(lib_dir) = env::var("SODIUM_LIB_DIR") {
println!("cargo:rustc-link-search=native={}", lib_dir);
let mode = match env::var_os("SODIUM_STATIC") {
Some(_) => "static",
None => "dylib",
};
if cfg!(target_os = "windows") {
println!("cargo:rustc-link-lib={0}=libsodium", mode);
} else {
println!("cargo:rustc-link-lib={0}=sodium", mode);
}
} else {
pkg_config::Config::new()
.atleast_version("1.0.17")
.statik(true)
.probe("libsodium")
.unwrap();
}
if let Ok(lib_dir) = env::var("LZ4_LIB_DIR") {
println!("cargo:rustc-link-search=native={}", lib_dir);
if cfg!(target_os = "windows") {
println!("cargo:rustc-link-lib=static=liblz4");
} else {
println!("cargo:rustc-link-lib=static=lz4");
}
} else {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
if !out_dir.join("liblz4.a").exists() {
let mut compiler = cc::Build::new();
compiler
.file("vendor/lz4/lz4.c")
.file("vendor/lz4/lz4frame.c")
.file("vendor/lz4/lz4hc.c")
.file("vendor/lz4/xxhash.c")
.define("XXH_NAMESPACE", "LZ4_")
.opt_level(3)
.debug(false)
.pic(true)
.shared_flag(false);
if !cfg!(windows) {
compiler.static_flag(true);
}
compiler.compile("liblz4.a");
}
}
}
#[cfg(all(feature = "libsodium-bundled", not(target_os = "windows")))]
fn download_and_install_libsodium() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let source_dir = out_dir.join(LIBSODIUM_NAME);
let prefix_dir = out_dir.join("libsodium");
let sodium_lib_dir = prefix_dir.join("lib");
let src_file_name = format!("{}.tar.gz", LIBSODIUM_NAME);
Command::new("curl")
.arg("--version")
.output()
.expect("curl not found");
Command::new("tar")
.arg("--version")
.output()
.expect("tar not found");
Command::new("gpg")
.arg("--version")
.output()
.expect("gpg not found");
Command::new("make")
.arg("--version")
.output()
.expect("make not found");
if !source_dir.exists() {
let output = Command::new("curl")
.current_dir(&out_dir)
.args(&[LIBSODIUM_URL, "-sSfL", "-o", &src_file_name])
.output()
.expect("failed to download libsodium");
assert!(output.status.success());
let sig_file_name = format!("{}.sig", src_file_name);
let sig_url = format!("{}.sig", LIBSODIUM_URL);
let output = Command::new("curl")
.current_dir(&out_dir)
.args(&[&sig_url, "-sSfL", "-o", &sig_file_name])
.output()
.expect("failed to download libsodium signature file");
assert!(output.status.success());
let output = Command::new("gpg")
.arg("--import")
.arg("libsodium.gpg.key")
.output()
.expect("failed to import libsodium author's gpg key");
assert!(output.status.success());
let output = Command::new("gpg")
.current_dir(&out_dir)
.arg("--verify")
.arg(&sig_file_name)
.output()
.expect("failed to verify libsodium file");
assert!(output.status.success());
let output = Command::new("tar")
.current_dir(&out_dir)
.args(&["zxf", &src_file_name])
.output()
.expect("failed to unpack libsodium");
assert!(output.status.success());
}
if !sodium_lib_dir.exists() {
let configure = source_dir.join("./configure");
let output = Command::new(&configure)
.current_dir(&source_dir)
.args(&[std::path::Path::new("--prefix"), &prefix_dir])
.output()
.expect("failed to execute configure");
assert!(output.status.success());
let output = Command::new("make")
.current_dir(&source_dir)
.output()
.expect("failed to execute make");
assert!(output.status.success());
let output = Command::new("make")
.current_dir(&source_dir)
.arg("install")
.output()
.expect("failed to execute make install");
assert!(output.status.success());
}
assert!(
&sodium_lib_dir.exists(),
"libsodium lib directory was not created."
);
env::set_var("SODIUM_LIB_DIR", &sodium_lib_dir);
env::set_var("SODIUM_STATIC", "true");
}
#[cfg(all(
feature = "libsodium-bundled",
target_os = "windows",
target_env = "msvc"
))]
fn download_and_install_libsodium() {
use std::fs;
use std::fs::OpenOptions;
use std::io;
use std::path::PathBuf;
#[cfg(target_env = "msvc")]
static LIBSODIUM_ZIP: &'static str = "https://download.libsodium.org/libsodium/releases/libsodium-1.0.17-msvc.zip";
#[cfg(target_env = "mingw")]
static LIBSODIUM_ZIP: &'static str = "https://download.libsodium.org/libsodium/releases/libsodium-1.0.17-mingw.tar.gz";
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let sodium_lib_dir = out_dir.join("libsodium");
if !sodium_lib_dir.exists() {
fs::create_dir(&sodium_lib_dir).unwrap();
}
let sodium_lib_file_path = sodium_lib_dir.join("libsodium.lib");
if !sodium_lib_file_path.exists() {
let mut tmpfile = tempfile::tempfile().unwrap();
reqwest::get(LIBSODIUM_ZIP)
.unwrap()
.copy_to(&mut tmpfile)
.unwrap();
let mut zip = zip::ZipArchive::new(tmpfile).unwrap();
#[cfg(target_arch = "x86_64")]
let mut lib = zip
.by_name("x64/Release/v141/static/libsodium.lib")
.unwrap();
#[cfg(target_arch = "x86")]
let mut lib = zip
.by_name("Win32/Release/v141/static/libsodium.lib")
.unwrap();
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
compile_error!("Bundled libsodium is only supported on x86 or x86_64 target architecture.");
let mut libsodium_file = OpenOptions::new()
.create(true)
.write(true)
.open(&sodium_lib_file_path)
.unwrap();
io::copy(&mut lib, &mut libsodium_file).unwrap();
}
assert!(
&sodium_lib_dir.exists(),
"libsodium lib directory was not created."
);
env::set_var("SODIUM_LIB_DIR", &sodium_lib_dir);
env::set_var("SODIUM_STATIC", "true");
}
#[cfg(all(
feature = "libsodium-bundled",
target_os = "windows",
target_env = "gnu"
))]
fn download_and_install_libsodium() {
use libflate::non_blocking::gzip::Decoder;
use std::fs;
use std::fs::OpenOptions;
use std::io;
use std::path::PathBuf;
use tar::Archive;
static LIBSODIUM_ZIP: &'static str = "https://download.libsodium.org/libsodium/releases/libsodium-1.0.17-mingw.tar.gz";
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let sodium_lib_dir = out_dir.join("libsodium");
if !sodium_lib_dir.exists() {
fs::create_dir(&sodium_lib_dir).unwrap();
}
let sodium_lib_file_path = sodium_lib_dir.join("libsodium.lib");
if !sodium_lib_file_path.exists() {
let response = reqwest::get(LIBSODIUM_ZIP).unwrap();
let decoder = Decoder::new(response);
let mut ar = Archive::new(decoder);
#[cfg(target_arch = "x86_64")]
let filename = PathBuf::from("libsodium-win64/lib/libsodium.a");
#[cfg(target_arch = "x86")]
let filename = PathBuf::from("libsodium-win32/lib/libsodium.a");
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
compile_error!("Bundled libsodium is only supported on x86 or x86_64 target architecture.");
for file in ar.entries().unwrap() {
let mut f = file.unwrap();
if f.path().unwrap() == *filename {
let mut libsodium_file = OpenOptions::new()
.create(true)
.write(true)
.open(&sodium_lib_file_path)
.unwrap();
io::copy(&mut f, &mut libsodium_file).unwrap();
break;
}
}
}
assert!(
&sodium_lib_dir.exists(),
"libsodium lib directory was not created."
);
env::set_var("SODIUM_LIB_DIR", &sodium_lib_dir);
env::set_var("SODIUM_STATIC", "true");
}