extern crate gcc;
use std::env;
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::path::Path;
#[derive(PartialEq,Debug)]
enum Context {
None,
Asm,
Crypto,
Ssl,
Ignore,
}
#[allow(non_camel_case_types)]
#[derive(PartialEq,Debug)]
enum CryptoTarget {
LinuxAarch64,
LinuxArm,
LinuxX86,
LinuxX86_64,
MacX86,
MacX86_64,
WinX86,
WinX86_64,
}
fn check_env(src: CryptoTarget) -> Context {
let target = env::var("TARGET").unwrap();
let t: Vec<&str> = target.split('-').collect();
assert!(t.len() >= 3);
let src_target = match t[0] {
"x86" => {
match t[2] {
"darwin" => CryptoTarget::MacX86,
"linux" => CryptoTarget::LinuxX86,
"win32" => CryptoTarget::WinX86,
_ => panic!("unimplemented target {:?}", target),
}
}
"x86_64" => {
match t[2] {
"darwin" => CryptoTarget::MacX86_64,
"linux" => CryptoTarget::LinuxX86_64,
"win32" => CryptoTarget::WinX86_64,
_ => panic!("unimplemented target {:?}", target),
}
}
_ => panic!("unimplemented target {:?}", target),
};
if src == src_target {
return Context::Asm;
}
Context::Ignore
}
fn get_filename(s: &mut String) -> String {
let i = s.len() - 2;
s.truncate(i);
String::from("third_party/boringssl/") + &s[5..]
}
fn main() {
let mut asm_src: Vec<String> = Vec::new();
let mut crypto_src: Vec<String> = Vec::new();
let mut ssl_src: Vec<String> = Vec::new();
let build_path = Path::new("third_party/boringssl/BUILD.generated.bzl");
let build_file = match File::open(&build_path) {
Err(why) => panic!("couldn't open BUILD file: {}", why.description()),
Ok(file) => file,
};
let reader = BufReader::new(build_file);
let mut ctx = Context::None;
for l in reader.lines() {
let mut line = l.unwrap();
if line.is_empty() {
continue;
}
if line.starts_with("#") {
continue;
}
if ctx == Context::None {
if !line.ends_with(" = [") {
panic!("invalid line {:?}", line);
}
let i = line.len() - 4;
line.truncate(i);
ctx = match line.as_ref() {
"crypto_headers" => Context::Ignore,
"crypto_internal_headers" => Context::Ignore,
"crypto_sources" => Context::Crypto,
"crypto_sources_linux_aarch64" => check_env(CryptoTarget::LinuxAarch64),
"crypto_sources_linux_arm" => check_env(CryptoTarget::LinuxArm),
"crypto_sources_linux_ppc64le" => Context::Ignore,
"crypto_sources_linux_x86" => check_env(CryptoTarget::LinuxX86),
"crypto_sources_linux_x86_64" => check_env(CryptoTarget::LinuxX86_64),
"crypto_sources_mac_x86" => check_env(CryptoTarget::MacX86),
"crypto_sources_mac_x86_64" => check_env(CryptoTarget::MacX86_64),
"crypto_sources_win_x86" => check_env(CryptoTarget::WinX86),
"crypto_sources_win_x86_64" => check_env(CryptoTarget::WinX86_64),
"ssl_c_sources" => Context::Ssl,
"ssl_cc_sources" => Context::Ignore, "ssl_headers" => Context::Ignore,
"ssl_internal_headers" => Context::Ignore,
"ssl_sources" => Context::Ignore,
"tool_sources" => Context::Ignore,
"tool_headers" => Context::Ignore,
s => panic!("unknown source file context {:?}", s),
};
} else {
if line.starts_with(" \"") {
match ctx {
Context::Ignore => continue,
Context::Asm => asm_src.push(get_filename(&mut line)),
Context::Crypto => crypto_src.push(get_filename(&mut line)),
Context::Ssl => ssl_src.push(get_filename(&mut line)),
_ => panic!("how did that happen?! {:?}", ctx),
};
} else if line == "]" {
ctx = Context::None;
} else {
panic!("unable to parse line: {:?}", line);
}
}
}
let mut boringssl = gcc::Config::new();
boringssl.include("third_party/boringssl/src/include")
.define("BORINGSSL_IMPLEMENTATION", None)
.define("OPENSSL_SMALL", None)
.define("_XOPEN_SOURCE", Some("700"))
.flag("-std=c11");
for src in &asm_src {
boringssl.file(src);
}
for src in &crypto_src {
boringssl.file(src);
}
for src in &ssl_src {
boringssl.file(src);
}
boringssl.compile("libboringssl.a");
}