#![allow(
box_pointers, // TODO
missing_docs)]
#![deny(
const_err,
dead_code,
deprecated,
drop_with_repr_extern,
exceeding_bitshifts,
fat_ptr_transmutes,
improper_ctypes,
match_of_unit_variant_via_paren_dotdot,
missing_copy_implementations,
missing_debug_implementations,
mutable_transmutes,
no_mangle_const_items,
non_camel_case_types,
non_shorthand_field_patterns,
non_snake_case,
non_upper_case_globals,
overflowing_literals,
path_statements,
plugin_as_library,
private_no_mangle_fns,
private_no_mangle_statics,
stable_features,
trivial_casts,
trivial_numeric_casts,
unconditional_recursion,
unknown_crate_types,
unknown_lints,
unreachable_code,
unsafe_code,
unstable_features,
unused_allocation,
unused_assignments,
unused_attributes,
unused_comparisons,
unused_extern_crates,
unused_features,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_parens,
unused_qualifications,
unused_results,
unused_unsafe,
unused_variables,
variant_size_differences,
warnings,
while_true,
)]
use std::env;
use std::path::Path;
const LIB_NAME: &'static str = "ring";
fn main() {
for (key, value) in env::vars() {
println!("{}: {}", key, value);
}
let out_dir = env::var("OUT_DIR").unwrap();
build_c_code(&out_dir).unwrap();
}
fn build_c_code(out_dir: &str) -> Result<(), std::env::VarError> {
let host_str = try!(env::var("HOST"));
let host_triple = host_str.split('-').collect::<Vec<&str>>();
let target_str = try!(env::var("TARGET"));
let target_triple = target_str.split('-').collect::<Vec<&str>>();
let use_msbuild = host_triple.contains(&"msvc") &&
target_triple.contains(&"msvc");
let opt_level = try!(env::var("OPT_LEVEL"));
let disable_opt = opt_level == "0";
let num_jobs = try!(env::var("NUM_JOBS"));
if !use_msbuild {
let cmake_build_type = if disable_opt {
"DEBUG"
} else {
"RELWITHDEBINFO"
};
let args = vec![
format!("-j{}", num_jobs),
format!("TARGET={}", target_str),
format!("CMAKE_BUILD_TYPE={}", cmake_build_type),
format!("BUILD_PREFIX={}/", out_dir),
];
run_command_with_args("make", &args);
} else {
let use_prepackaged_asm = std::fs::metadata(".gitignore").is_err();
let arch = target_triple[0];
let platform = match arch {
"i686" => "Win32",
"x86_64" => "x64",
_ => panic!("unexpected ARCH: {}", arch)
};
let configuration = if disable_opt { "Debug" } else { "Release" };
let args = vec![
format!("/m:{}", num_jobs),
format!("/p:Platform={}", platform),
format!("/p:Configuration={}", configuration),
format!("/p:OutRootDir={}/", out_dir),
];
if !use_prepackaged_asm {
run_command_with_args("msbuild", &args);
println!("cargo:rustc-link-lib=static={}-asm", LIB_NAME);
} else {
let mut core_args = args.clone();
core_args.push(String::from("crypto/libring.Windows.vcxproj"));
run_command_with_args("msbuild", &core_args);
let mut test_args = args.clone();
test_args.push(String::from("crypto/libring-test.Windows.vcxproj"));
run_command_with_args("msbuild", &test_args);
println!("cargo:rustc-link-search=native=pregenerated");
println!("cargo:rustc-link-lib=static=msvc-{}-asm-{}", LIB_NAME,
arch);
}
}
let lib_path = Path::new(out_dir).join("lib");
println!("cargo:rustc-link-search=native={}", lib_path.to_str().unwrap());
println!("cargo:rustc-link-lib=static={}-core", LIB_NAME);
println!("cargo:rustc-link-lib=static={}-test", LIB_NAME);
if !use_msbuild {
println!("cargo:rustc-flags=-l dylib=stdc++");
}
Ok(())
}
fn run_command_with_args(command_name: &str, args: &Vec<String>) {
if !std::process::Command::new(command_name)
.args(&args)
.status()
.unwrap_or_else(|e| { panic!("failed to execute {}: {}",
command_name, e); })
.success() {
panic!("{} execution failed", command_name);
}
}