2016-02-04 14:40:20 -10:00
|
|
|
// Copyright 2015-2016 Brian Smith.
|
2015-07-30 19:48:38 -04:00
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice appear in all copies.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
|
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
|
|
|
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
|
|
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
2016-10-26 09:02:30 -10:00
|
|
|
// TODO: Deny `unused_qualifications` after
|
|
|
|
// https://github.com/rust-lang/rust/issues/37345 is fixed.
|
2016-02-04 14:40:20 -10:00
|
|
|
#![deny(
|
|
|
|
const_err,
|
|
|
|
dead_code,
|
|
|
|
deprecated,
|
|
|
|
exceeding_bitshifts,
|
|
|
|
fat_ptr_transmutes,
|
|
|
|
improper_ctypes,
|
|
|
|
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_results,
|
|
|
|
unused_unsafe,
|
|
|
|
unused_variables,
|
|
|
|
variant_size_differences,
|
|
|
|
warnings,
|
|
|
|
while_true,
|
|
|
|
)]
|
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
extern crate gcc;
|
2017-02-07 23:29:00 +01:00
|
|
|
extern crate rayon;
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-03-16 12:43:18 -10:00
|
|
|
// In the `pregenerate_asm_main()` case we don't want to access (Cargo)
|
|
|
|
// environment variables at all, so avoid `use std::env` here.
|
|
|
|
|
2016-10-26 09:58:25 -10:00
|
|
|
use std::path::{Path, PathBuf};
|
2017-02-19 23:22:21 -10:00
|
|
|
use std::process::Command;
|
2017-02-07 23:19:36 +01:00
|
|
|
use std::fs::{self, DirEntry};
|
Improve include file modification checks.
Treat a missing source file as an error, whereas before we were
treating it as indicating that the target needs to be rebuilt. Because
we do dependency checking bottom-up, not top-down, the source file
always exists. If it doesn't, then that's an error. In particular, it
probably means that build.rs lists some source files that have been
removed. (See the previous commit.)
Also, the original purpose of this commit is to memoize the
modification time of the most recently modified include file, instead
of `stat()`ing each include file over and over again for each source
file. So do that too.
Finally, in the name of simplicity, don't bother tracking test vs.
non-test includes separately. It's rare when any include file changes,
and we don't save much by separating things, so K.I.S.S. to reduce the
chance that things get screwed up.
2017-03-15 23:37:40 -10:00
|
|
|
use std::time::SystemTime;
|
2017-02-07 23:29:00 +01:00
|
|
|
use rayon::par_iter::{ParallelIterator, IntoParallelIterator,
|
|
|
|
IntoParallelRefIterator};
|
2015-11-11 12:28:43 -10:00
|
|
|
|
2017-03-17 10:28:50 -10:00
|
|
|
const X86: &'static str = "x86";
|
|
|
|
const X86_64: &'static str = "x86_64";
|
|
|
|
const AARCH64: &'static str = "aarch64";
|
|
|
|
const ARM: &'static str = "arm";
|
2015-07-30 19:48:38 -04:00
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
2017-03-17 10:28:50 -10:00
|
|
|
const RING_SRCS: &'static [(&'static [&'static str], &'static str)] = &[
|
|
|
|
(&[], "crypto/aes/aes.c"),
|
|
|
|
(&[], "crypto/bn/add.c"),
|
|
|
|
(&[], "crypto/bn/bn.c"),
|
|
|
|
(&[], "crypto/bn/cmp.c"),
|
|
|
|
(&[], "crypto/bn/convert.c"),
|
|
|
|
(&[], "crypto/bn/div.c"),
|
|
|
|
(&[], "crypto/bn/exponentiation.c"),
|
|
|
|
(&[], "crypto/bn/gcd.c"),
|
|
|
|
(&[], "crypto/bn/generic.c"),
|
|
|
|
(&[], "crypto/bn/montgomery.c"),
|
|
|
|
(&[], "crypto/bn/montgomery_inv.c"),
|
|
|
|
(&[], "crypto/bn/mul.c"),
|
|
|
|
(&[], "crypto/bn/random.c"),
|
|
|
|
(&[], "crypto/bn/shift.c"),
|
|
|
|
(&[], "crypto/cipher/e_aes.c"),
|
|
|
|
(&[], "crypto/crypto.c"),
|
|
|
|
(&[], "crypto/curve25519/curve25519.c"),
|
|
|
|
(&[], "crypto/ec/ecp_nistz.c"),
|
|
|
|
(&[], "crypto/ec/ecp_nistz256.c"),
|
|
|
|
(&[], "crypto/ec/gfp_p256.c"),
|
|
|
|
(&[], "crypto/ec/gfp_p384.c"),
|
2017-03-17 11:36:03 -10:00
|
|
|
(&[], "crypto/limbs/limbs.c"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[], "crypto/mem.c"),
|
|
|
|
(&[], "crypto/modes/gcm.c"),
|
|
|
|
(&[], "crypto/rand/sysrand.c"),
|
|
|
|
|
|
|
|
(&[X86_64, X86], "crypto/cpu-intel.c"),
|
|
|
|
|
|
|
|
(&[X86], "crypto/aes/asm/aes-586.pl"),
|
|
|
|
(&[X86], "crypto/aes/asm/aesni-x86.pl"),
|
|
|
|
(&[X86], "crypto/aes/asm/vpaes-x86.pl"),
|
|
|
|
(&[X86], "crypto/bn/asm/x86-mont.pl"),
|
|
|
|
(&[X86], "crypto/chacha/asm/chacha-x86.pl"),
|
|
|
|
(&[X86], "crypto/ec/asm/ecp_nistz256-x86.pl"),
|
|
|
|
(&[X86], "crypto/modes/asm/ghash-x86.pl"),
|
|
|
|
(&[X86], "crypto/poly1305/asm/poly1305-x86.pl"),
|
|
|
|
(&[X86], "crypto/sha/asm/sha256-586.pl"),
|
|
|
|
(&[X86], "crypto/sha/asm/sha512-586.pl"),
|
|
|
|
|
|
|
|
(&[X86_64], "crypto/curve25519/x25519-x86_64.c"),
|
|
|
|
|
|
|
|
(&[X86_64], "crypto/aes/asm/aes-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/aes/asm/aesni-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/aes/asm/bsaes-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/aes/asm/vpaes-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/bn/asm/x86_64-mont.pl"),
|
|
|
|
(&[X86_64], "crypto/bn/asm/x86_64-mont5.pl"),
|
|
|
|
(&[X86_64], "crypto/chacha/asm/chacha-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/curve25519/asm/x25519-asm-x86_64.S"),
|
|
|
|
(&[X86_64], "crypto/ec/asm/ecp_nistz256-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/ec/asm/p256-x86_64-asm.pl"),
|
|
|
|
(&[X86_64], "crypto/modes/asm/aesni-gcm-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/modes/asm/ghash-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/poly1305/asm/poly1305-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/sha/asm/sha256-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/sha/asm/sha512-x86_64.pl"),
|
|
|
|
|
2017-03-17 11:36:03 -10:00
|
|
|
(&[AARCH64, ARM], "crypto/aes/asm/aesv8-armx.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[AARCH64, ARM], "crypto/cpu-arm-linux.c"),
|
|
|
|
(&[AARCH64, ARM], "crypto/cpu-arm.c"),
|
|
|
|
(&[AARCH64, ARM], "crypto/modes/asm/ghashv8-armx.pl"),
|
|
|
|
|
|
|
|
(&[ARM], "crypto/aes/asm/aes-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/aes/asm/bsaes-armv7.pl"),
|
|
|
|
(&[ARM], "crypto/bn/asm/armv4-mont.pl"),
|
|
|
|
(&[ARM], "crypto/chacha/asm/chacha-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/curve25519/asm/x25519-asm-arm.S"),
|
|
|
|
(&[ARM], "crypto/ec/asm/ecp_nistz256-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/modes/asm/ghash-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/poly1305/asm/poly1305-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/sha/asm/sha256-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/sha/asm/sha512-armv4.pl"),
|
|
|
|
|
|
|
|
(&[AARCH64], "crypto/bn/asm/armv8-mont.pl"),
|
2017-03-17 11:36:03 -10:00
|
|
|
(&[AARCH64], "crypto/cpu-aarch64-linux.c"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[AARCH64], "crypto/chacha/asm/chacha-armv8.pl"),
|
|
|
|
(&[AARCH64], "crypto/ec/asm/ecp_nistz256-armv8.pl"),
|
|
|
|
(&[AARCH64], "crypto/poly1305/asm/poly1305-armv8.pl"),
|
|
|
|
(&[AARCH64], "crypto/sha/asm/sha256-armv8.pl"),
|
|
|
|
(&[AARCH64], "crypto/sha/asm/sha512-armv8.pl"),
|
|
|
|
];
|
|
|
|
|
|
|
|
const RING_TEST_SRCS: &'static [&'static str] = &[
|
|
|
|
("crypto/bn/bn_test.cc"),
|
|
|
|
("crypto/constant_time_test.c"),
|
|
|
|
("crypto/test/bn_test_convert.c"),
|
|
|
|
("crypto/test/bn_test_lib.c"),
|
|
|
|
("crypto/test/bn_test_new.c"),
|
|
|
|
("crypto/test/file_test.cc"),
|
|
|
|
];
|
2015-07-30 19:48:38 -04:00
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
2017-03-17 11:28:43 -10:00
|
|
|
const RING_INCLUDES: &'static [&'static str] =
|
2017-03-17 11:36:03 -10:00
|
|
|
&["crypto/bn/internal.h",
|
2017-02-07 23:19:36 +01:00
|
|
|
"crypto/cipher/internal.h",
|
2017-03-17 11:36:03 -10:00
|
|
|
"crypto/curve25519/internal.h",
|
2017-03-17 11:28:43 -10:00
|
|
|
"crypto/ec/ecp_nistz256_table.inl",
|
|
|
|
"crypto/ec/ecp_nistz384.inl",
|
2017-02-07 23:19:36 +01:00
|
|
|
"crypto/ec/ecp_nistz.h",
|
|
|
|
"crypto/ec/ecp_nistz384.h",
|
|
|
|
"crypto/ec/ecp_nistz256.h",
|
2017-03-17 11:36:03 -10:00
|
|
|
"crypto/internal.h",
|
2017-02-07 23:19:36 +01:00
|
|
|
"crypto/limbs/limbs.h",
|
2017-03-17 11:28:43 -10:00
|
|
|
"crypto/limbs/limbs.inl",
|
2017-03-17 11:36:03 -10:00
|
|
|
"crypto/modes/internal.h",
|
2017-03-17 11:28:43 -10:00
|
|
|
"crypto/test/bn_test_lib.h",
|
|
|
|
"crypto/test/bn_test_util.h",
|
2017-03-17 11:36:03 -10:00
|
|
|
"crypto/test/file_test.h",
|
|
|
|
"crypto/test/rand.h",
|
|
|
|
"crypto/test/scoped_types.h",
|
|
|
|
"include/openssl/aes.h",
|
2017-02-07 23:19:36 +01:00
|
|
|
"include/openssl/arm_arch.h",
|
2017-03-17 11:36:03 -10:00
|
|
|
"include/openssl/base.h",
|
|
|
|
"include/openssl/bn.h",
|
2017-02-07 23:19:36 +01:00
|
|
|
"include/openssl/cpu.h",
|
2017-03-17 11:36:03 -10:00
|
|
|
"include/openssl/err.h",
|
|
|
|
"include/openssl/mem.h",
|
|
|
|
"include/openssl/opensslconf.h",
|
2017-02-07 23:19:36 +01:00
|
|
|
"include/openssl/rsa.h",
|
2017-03-17 11:36:03 -10:00
|
|
|
"include/openssl/type_check.h"];
|
2016-08-15 13:34:13 -10:00
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
|
|
|
const RING_PERL_INCLUDES: &'static [&'static str] =
|
2017-03-17 11:36:03 -10:00
|
|
|
&["crypto/perlasm/arm-xlate.pl",
|
|
|
|
"crypto/sha/asm/sha-x86_64.pl",
|
2017-02-07 23:19:36 +01:00
|
|
|
"crypto/sha/asm/sha-armv8.pl",
|
|
|
|
"crypto/perlasm/x86masm.pl",
|
|
|
|
"crypto/perlasm/x86gas.pl",
|
|
|
|
"crypto/perlasm/x86nasm.pl",
|
|
|
|
"crypto/perlasm/x86asm.pl",
|
2017-03-17 11:36:03 -10:00
|
|
|
"crypto/perlasm/x86_64-xlate.pl"];
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-02-07 23:32:13 +01:00
|
|
|
const RING_BUILD_FILE: &'static [&'static str] = &["build.rs"];
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-03-16 12:43:18 -10:00
|
|
|
const PREGENERATED: &'static str = "pregenerated";
|
|
|
|
|
2017-02-19 23:22:21 -10:00
|
|
|
fn c_flags(target: &Target) -> &'static [&'static str] {
|
|
|
|
if target.env != "msvc" {
|
|
|
|
static NON_MSVC_FLAGS: &'static [&'static str] = &[
|
|
|
|
"-std=c1x", // GCC 4.6 requires "c1x" instead of "c11"
|
|
|
|
"-Wbad-function-cast",
|
|
|
|
"-Wmissing-prototypes",
|
|
|
|
"-Wnested-externs",
|
|
|
|
"-Wstrict-prototypes"
|
|
|
|
];
|
|
|
|
NON_MSVC_FLAGS
|
|
|
|
} else {
|
|
|
|
&[]
|
|
|
|
}
|
|
|
|
}
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-02-19 23:22:21 -10:00
|
|
|
fn cxx_flags(target: &Target) -> &'static [&'static str] {
|
|
|
|
if target.env != "msvc" {
|
|
|
|
static NON_MSVC_FLAGS: &'static [&'static str] = &[
|
|
|
|
"-std=c++0x" // GCC 4.6 requires "c++0x" instead of "c++11"
|
|
|
|
];
|
|
|
|
NON_MSVC_FLAGS
|
|
|
|
} else {
|
|
|
|
&[]
|
|
|
|
}
|
|
|
|
}
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-02-19 23:22:21 -10:00
|
|
|
fn cpp_flags(target: &Target) -> &'static [&'static str] {
|
|
|
|
if target.env != "msvc" {
|
|
|
|
static NON_MSVC_FLAGS: &'static [&'static str] = &[
|
|
|
|
"-fdata-sections",
|
|
|
|
"-ffunction-sections",
|
|
|
|
"-pedantic",
|
|
|
|
"-pedantic-errors",
|
|
|
|
"-Wall",
|
|
|
|
"-Werror",
|
|
|
|
"-Wextra",
|
|
|
|
"-Wcast-align",
|
|
|
|
"-Wcast-qual",
|
|
|
|
"-Wenum-compare",
|
|
|
|
"-Wfloat-equal",
|
|
|
|
"-Wformat=2",
|
|
|
|
"-Winline",
|
|
|
|
"-Winvalid-pch",
|
|
|
|
"-Wmissing-declarations",
|
|
|
|
"-Wmissing-field-initializers",
|
|
|
|
"-Wmissing-include-dirs",
|
|
|
|
"-Wredundant-decls",
|
|
|
|
"-Wshadow",
|
|
|
|
"-Wsign-compare",
|
|
|
|
"-Wundef",
|
|
|
|
"-Wuninitialized",
|
|
|
|
"-Wwrite-strings",
|
|
|
|
"-fno-strict-aliasing",
|
|
|
|
"-fvisibility=hidden",
|
|
|
|
"-Wno-cast-align"
|
|
|
|
];
|
|
|
|
NON_MSVC_FLAGS
|
|
|
|
} else {
|
|
|
|
static MSVC_FLAGS: &'static [&'static str] = &[
|
|
|
|
"-EHsc",
|
|
|
|
|
|
|
|
"/GS", // Buffer security checks.
|
|
|
|
|
|
|
|
"/Zc:wchar_t",
|
|
|
|
"/Zc:forScope",
|
|
|
|
"/Zc:inline",
|
|
|
|
"/Zc:rvalueCast",
|
|
|
|
"/utf-8", // Input files are Unicode.
|
|
|
|
|
|
|
|
// Warnings.
|
|
|
|
"/sdl",
|
|
|
|
"/Wall",
|
|
|
|
"/WX",
|
|
|
|
"/wd4127", // C4127: conditional expression is constant
|
|
|
|
"/wd4464", // C4464: relative include path contains '..'
|
|
|
|
"/wd4514", // C4514: <name>: unreferenced inline function has be
|
|
|
|
"/wd4710", // C4710: function not inlined
|
|
|
|
"/wd4711", // C4711: function 'function' selected for inline expansion
|
|
|
|
"/wd4820", // C4820: <struct>: <n> bytes padding added after <name>
|
|
|
|
];
|
|
|
|
MSVC_FLAGS
|
|
|
|
}
|
|
|
|
}
|
2017-02-07 23:19:36 +01:00
|
|
|
|
|
|
|
const LD_FLAGS: &'static [&'static str] = &[];
|
|
|
|
|
2017-03-15 20:47:06 -10:00
|
|
|
// None means "any OS" or "any target". The first match in sequence order is
|
|
|
|
// taken.
|
|
|
|
const ASM_TARGETS:
|
|
|
|
&'static [(&'static str, Option<&'static str>, &'static str)] =
|
|
|
|
&[
|
|
|
|
("x86_64", Some("macos"), "macosx"),
|
|
|
|
("x86_64", Some("windows"), "nasm"),
|
|
|
|
("x86_64", None, "elf"),
|
|
|
|
("aarch64", Some("ios"), "ios64"),
|
|
|
|
("aarch64", None, "linux64"),
|
|
|
|
("x86", Some("windows"), "win32n"),
|
|
|
|
("x86", None, "elf"),
|
|
|
|
("arm", Some("ios"), "ios32"),
|
|
|
|
("arm", None, "linux32"),
|
|
|
|
];
|
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
fn main() {
|
2017-03-16 12:43:18 -10:00
|
|
|
if let Ok(package_name) = std::env::var("CARGO_PKG_NAME") {
|
|
|
|
if package_name == "ring" {
|
|
|
|
ring_build_rs_main();
|
|
|
|
return;
|
|
|
|
}
|
2016-04-16 17:11:20 -10:00
|
|
|
}
|
|
|
|
|
2017-03-16 12:43:18 -10:00
|
|
|
pregenerate_asm_main();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ring_build_rs_main() {
|
|
|
|
use std::env;
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-02-07 23:29:00 +01:00
|
|
|
let mut cfg = rayon::Configuration::new();
|
2017-03-16 12:43:18 -10:00
|
|
|
if let Ok(amt) = std::env::var("NUM_JOBS") {
|
2017-02-07 23:29:00 +01:00
|
|
|
if let Ok(amt) = amt.parse() {
|
|
|
|
cfg = cfg.set_num_threads(amt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rayon::initialize(cfg).unwrap();
|
|
|
|
|
2017-03-16 12:43:18 -10:00
|
|
|
for (key, value) in env::vars() {
|
|
|
|
println!("{}: {}", key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
let out_dir = env::var("OUT_DIR").unwrap();
|
|
|
|
let out_dir = PathBuf::from(out_dir);
|
|
|
|
|
|
|
|
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
|
|
|
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
|
|
|
let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
|
|
|
let (obj_ext, obj_opt) = if env == "msvc" {
|
|
|
|
("obj", "/Fo")
|
|
|
|
} else {
|
|
|
|
("o", "-o")
|
|
|
|
};
|
|
|
|
|
|
|
|
let target = Target {
|
|
|
|
arch: arch,
|
|
|
|
os: os,
|
|
|
|
env: env,
|
|
|
|
obj_ext: obj_ext,
|
|
|
|
obj_opt: obj_opt,
|
|
|
|
is_debug: env::var("PROFILE").unwrap() == "debug",
|
|
|
|
};
|
|
|
|
|
|
|
|
let _ = rayon::join(check_all_files_tracked,
|
2017-03-18 10:54:33 -10:00
|
|
|
|| build_c_code(&target, &out_dir));
|
2017-03-16 12:43:18 -10:00
|
|
|
}
|
|
|
|
|
|
|
|
fn pregenerate_asm_main() {
|
|
|
|
let pregenerated = PathBuf::from(PREGENERATED);
|
|
|
|
std::fs::create_dir(&pregenerated).unwrap();
|
|
|
|
|
|
|
|
for &(target_arch, target_os, perlasm_format) in ASM_TARGETS {
|
|
|
|
let perlasm_src_dsts =
|
|
|
|
perlasm_src_dsts(&pregenerated, target_arch, target_os,
|
|
|
|
perlasm_format);
|
|
|
|
perlasm(&perlasm_src_dsts, target_arch, perlasm_format, None);
|
|
|
|
}
|
2015-07-30 19:48:38 -04:00
|
|
|
}
|
2016-08-14 20:39:12 -10:00
|
|
|
|
2017-03-04 12:46:36 -10:00
|
|
|
struct Target {
|
|
|
|
arch: String,
|
|
|
|
os: String,
|
|
|
|
env: String,
|
2017-02-19 23:22:21 -10:00
|
|
|
obj_ext: &'static str,
|
|
|
|
obj_opt: &'static str,
|
2017-03-16 12:43:18 -10:00
|
|
|
is_debug: bool,
|
2017-03-04 12:46:36 -10:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Target {
|
|
|
|
pub fn arch(&self) -> &str { &self.arch }
|
|
|
|
pub fn os(&self) -> &str { &self.os }
|
|
|
|
pub fn env(&self) -> &str { &self.env }
|
2017-03-16 12:43:18 -10:00
|
|
|
pub fn is_debug(&self) -> bool { self.is_debug }
|
2017-03-04 12:46:36 -10:00
|
|
|
}
|
|
|
|
|
2017-03-18 10:54:33 -10:00
|
|
|
fn build_c_code(target: &Target, out_dir: &Path) {
|
|
|
|
let lib_target = out_dir.join("libring-core.a");
|
|
|
|
let test_target = out_dir.join("libring-test.a");
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-03-17 11:28:43 -10:00
|
|
|
let includes_modified = RING_INCLUDES.par_iter()
|
2017-03-16 11:22:08 -10:00
|
|
|
.weight_max()
|
2017-02-07 23:29:00 +01:00
|
|
|
.chain(RING_BUILD_FILE.par_iter())
|
Improve include file modification checks.
Treat a missing source file as an error, whereas before we were
treating it as indicating that the target needs to be rebuilt. Because
we do dependency checking bottom-up, not top-down, the source file
always exists. If it doesn't, then that's an error. In particular, it
probably means that build.rs lists some source files that have been
removed. (See the previous commit.)
Also, the original purpose of this commit is to memoize the
modification time of the most recently modified include file, instead
of `stat()`ing each include file over and over again for each source
file. So do that too.
Finally, in the name of simplicity, don't bother tracking test vs.
non-test includes separately. It's rare when any include file changes,
and we don't save much by separating things, so K.I.S.S. to reduce the
chance that things get screwed up.
2017-03-15 23:37:40 -10:00
|
|
|
.chain(RING_PERL_INCLUDES.par_iter())
|
|
|
|
.map(|f| file_modified(Path::new(*f)))
|
|
|
|
.max()
|
|
|
|
.unwrap();
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-03-15 20:47:06 -10:00
|
|
|
fn is_none_or_equals<T>(opt: Option<T>, other: T)
|
|
|
|
-> bool where T: PartialEq {
|
|
|
|
if let Some(value) = opt {
|
|
|
|
value == other
|
|
|
|
} else {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let &(_, _, perlasm_format) = ASM_TARGETS.iter().find(|entry| {
|
|
|
|
let &(entry_arch, entry_os, _) = *entry;
|
|
|
|
entry_arch == target.arch() && is_none_or_equals(entry_os, target.os())
|
|
|
|
}).unwrap();
|
2017-03-16 12:43:18 -10:00
|
|
|
|
|
|
|
let use_pregenerated = std::fs::metadata(".git").is_err();
|
|
|
|
|
2017-03-18 10:54:33 -10:00
|
|
|
let pregenerated = PathBuf::from(PREGENERATED);
|
|
|
|
let asm_dir = if use_pregenerated { &pregenerated } else { out_dir };
|
2017-03-16 12:43:18 -10:00
|
|
|
|
|
|
|
let perlasm_src_dsts =
|
2017-03-18 10:54:33 -10:00
|
|
|
perlasm_src_dsts(asm_dir, target.arch(), Some(target.os()),
|
2017-03-16 12:43:18 -10:00
|
|
|
perlasm_format);
|
|
|
|
|
|
|
|
if !use_pregenerated {
|
|
|
|
perlasm(&perlasm_src_dsts[..], target.arch(), perlasm_format,
|
|
|
|
Some(includes_modified));
|
|
|
|
}
|
|
|
|
|
|
|
|
let asm_srcs = perlasm_src_dsts.into_iter()
|
|
|
|
.map(|(_src, dst)| dst)
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
let srcs = sources_for_arch(target.arch()).into_iter()
|
|
|
|
.filter(|p| !is_perlasm(&p))
|
2017-03-17 10:28:50 -10:00
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
let test_srcs = RING_TEST_SRCS.iter()
|
|
|
|
.map(PathBuf::from)
|
|
|
|
.collect::<Vec<_>>();
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-03-16 11:22:45 -10:00
|
|
|
// XXX: Ideally, ring-test would only be built for `cargo test`, but Cargo
|
|
|
|
// can't do that yet.
|
|
|
|
let ((), ()) = rayon::join(
|
2017-03-18 10:54:33 -10:00
|
|
|
|| build_library("ring-core", &lib_target, &asm_srcs[..], &srcs[..],
|
|
|
|
&target, out_dir, includes_modified),
|
|
|
|
|| build_library("ring-test", &test_target, &[], &test_srcs[..],
|
|
|
|
&target, out_dir, includes_modified));
|
2017-03-16 01:00:15 -10:00
|
|
|
|
2017-02-19 23:22:21 -10:00
|
|
|
if target.env() != "msvc" {
|
2017-03-16 12:43:18 -10:00
|
|
|
let libcxx = if use_libcxx(target) {
|
2017-02-19 23:22:21 -10:00
|
|
|
"c++"
|
|
|
|
} else {
|
|
|
|
"stdc++"
|
|
|
|
};
|
|
|
|
println!("cargo:rustc-flags=-l dylib={}", libcxx);
|
|
|
|
}
|
|
|
|
|
2017-03-16 01:00:15 -10:00
|
|
|
println!("cargo:rustc-link-search=native={}",
|
|
|
|
out_dir.to_str().expect("Invalid path"));
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
|
|
|
|
2017-02-07 23:29:00 +01:00
|
|
|
|
2017-03-17 10:28:50 -10:00
|
|
|
fn build_library(lib_name: &str, out_path: &Path, additional: &[PathBuf],
|
2017-03-18 10:54:33 -10:00
|
|
|
lib_src: &[PathBuf], target: &Target, out_dir: &Path,
|
|
|
|
includes_modified: SystemTime) {
|
2017-02-07 23:29:00 +01:00
|
|
|
// Compile all the (dirty) source files into object files.
|
2017-03-17 10:28:50 -10:00
|
|
|
let objs = additional.into_par_iter().chain(lib_src.into_par_iter())
|
2017-02-07 23:29:00 +01:00
|
|
|
.weight_max()
|
2017-03-17 10:28:50 -10:00
|
|
|
.filter(|f|
|
|
|
|
target.env() != "msvc" ||
|
|
|
|
f.extension().unwrap().to_str().unwrap() != "S")
|
2017-03-18 10:54:33 -10:00
|
|
|
.map(|f| compile(f, target, out_dir, includes_modified))
|
2017-02-07 23:29:00 +01:00
|
|
|
.map(|v| vec![v])
|
|
|
|
.reduce(Vec::new,
|
|
|
|
&|mut a: Vec<String>, b: Vec<String>| -> Vec<String> {
|
|
|
|
a.extend(b.into_iter());
|
|
|
|
a
|
|
|
|
});
|
|
|
|
|
2017-03-18 10:54:33 -10:00
|
|
|
// Rebuild the library if necessary.
|
2017-02-07 23:29:00 +01:00
|
|
|
if objs.par_iter()
|
2017-03-18 10:54:33 -10:00
|
|
|
.weight_max()
|
2017-02-07 23:19:36 +01:00
|
|
|
.map(|f| Path::new(f))
|
Improve include file modification checks.
Treat a missing source file as an error, whereas before we were
treating it as indicating that the target needs to be rebuilt. Because
we do dependency checking bottom-up, not top-down, the source file
always exists. If it doesn't, then that's an error. In particular, it
probably means that build.rs lists some source files that have been
removed. (See the previous commit.)
Also, the original purpose of this commit is to memoize the
modification time of the most recently modified include file, instead
of `stat()`ing each include file over and over again for each source
file. So do that too.
Finally, in the name of simplicity, don't bother tracking test vs.
non-test includes separately. It's rare when any include file changes,
and we don't save much by separating things, so K.I.S.S. to reduce the
chance that things get screwed up.
2017-03-15 23:37:40 -10:00
|
|
|
.any(|p| need_run(&p, out_path, includes_modified)) {
|
2017-02-07 23:19:36 +01:00
|
|
|
let mut c = gcc::Config::new();
|
|
|
|
|
|
|
|
for f in LD_FLAGS {
|
|
|
|
let _ = c.flag(&f);
|
|
|
|
}
|
2017-03-04 12:46:36 -10:00
|
|
|
match target.os() {
|
2017-02-07 23:19:36 +01:00
|
|
|
"macos" => {
|
|
|
|
let _ = c.flag("-fPIC");
|
|
|
|
let _ = c.flag("-Wl,-dead_strip");
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
let _ = c.flag("-Wl,--gc-sections".into());
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for o in objs {
|
|
|
|
let _ = c.object(o);
|
|
|
|
}
|
2017-03-16 01:00:15 -10:00
|
|
|
|
|
|
|
// Handled below.
|
|
|
|
let _ = c.cargo_metadata(false);
|
|
|
|
|
2017-03-04 12:46:36 -10:00
|
|
|
c.compile(out_path.file_name()
|
2017-02-07 23:19:36 +01:00
|
|
|
.and_then(|f| f.to_str())
|
|
|
|
.expect("No filename"));
|
|
|
|
}
|
2017-03-16 01:00:15 -10:00
|
|
|
|
|
|
|
// Link the library. This works even when the library doesn't need to be
|
|
|
|
// rebuilt.
|
|
|
|
println!("cargo:rustc-link-lib=static={}", lib_name);
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
|
|
|
|
2017-03-18 10:54:33 -10:00
|
|
|
fn compile(p: &Path, target: &Target, out_dir: &Path,
|
Improve include file modification checks.
Treat a missing source file as an error, whereas before we were
treating it as indicating that the target needs to be rebuilt. Because
we do dependency checking bottom-up, not top-down, the source file
always exists. If it doesn't, then that's an error. In particular, it
probably means that build.rs lists some source files that have been
removed. (See the previous commit.)
Also, the original purpose of this commit is to memoize the
modification time of the most recently modified include file, instead
of `stat()`ing each include file over and over again for each source
file. So do that too.
Finally, in the name of simplicity, don't bother tracking test vs.
non-test includes separately. It's rare when any include file changes,
and we don't save much by separating things, so K.I.S.S. to reduce the
chance that things get screwed up.
2017-03-15 23:37:40 -10:00
|
|
|
includes_modified: SystemTime) -> String {
|
2017-03-18 10:54:33 -10:00
|
|
|
let mut out_path = out_dir.clone().join(p.file_name().unwrap());
|
|
|
|
out_path.set_extension(target.obj_ext);
|
|
|
|
if need_run(&p, &out_path, includes_modified) {
|
2017-02-19 23:22:21 -10:00
|
|
|
let ext = p.extension().unwrap().to_str().unwrap();
|
|
|
|
let mut c = if target.env() != "msvc" || ext != "asm" {
|
2017-03-18 10:54:33 -10:00
|
|
|
cc(p, ext, target, &out_path)
|
2017-02-19 23:22:21 -10:00
|
|
|
} else {
|
2017-03-18 10:54:33 -10:00
|
|
|
yasm(p, target, &out_path)
|
2017-02-07 23:19:36 +01:00
|
|
|
};
|
2017-02-19 23:22:21 -10:00
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
println!("{:?}", c);
|
|
|
|
if !c.status()
|
2017-03-17 10:28:50 -10:00
|
|
|
.expect(&format!("Failed to compile {:?}", p))
|
2017-02-07 23:19:36 +01:00
|
|
|
.success() {
|
2017-03-17 10:28:50 -10:00
|
|
|
panic!("Failed to compile {:?}", p)
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
|
|
|
}
|
2017-03-18 10:54:33 -10:00
|
|
|
out_path.to_str().expect("Invalid path").into()
|
2016-10-26 11:44:22 +02:00
|
|
|
}
|
|
|
|
|
2017-03-17 10:28:50 -10:00
|
|
|
fn cc(file: &Path, ext: &str, target: &Target, out_dir: &Path) -> Command {
|
2017-02-19 23:22:21 -10:00
|
|
|
let mut c = gcc::Config::new();
|
|
|
|
let _ = c.include("include");
|
|
|
|
match ext {
|
|
|
|
"c" => {
|
|
|
|
for f in c_flags(target) {
|
|
|
|
let _ = c.flag(f);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"cc" => {
|
|
|
|
for f in cxx_flags(target) {
|
|
|
|
let _ = c.flag(f);
|
|
|
|
}
|
|
|
|
let _ = c.cpp(true);
|
|
|
|
if use_libcxx(target) {
|
|
|
|
let _ = c.cpp_set_stdlib(Some("c++"));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"S" => {},
|
|
|
|
e => panic!("Unsupported file extension: {:?}", e),
|
|
|
|
};
|
|
|
|
for f in cpp_flags(target) {
|
|
|
|
let _ = c.flag(&f);
|
|
|
|
}
|
|
|
|
if target.os() != "none" &&
|
|
|
|
target.os() != "redox" &&
|
|
|
|
target.env() != "msvc" {
|
|
|
|
let _ = c.flag("-fstack-protector");
|
|
|
|
}
|
|
|
|
match (target.os(), target.env()) {
|
|
|
|
// ``-gfull`` is required for Darwin's |-dead_strip|.
|
|
|
|
("macos", _) => { let _ = c.flag("-gfull"); },
|
|
|
|
(_, "msvc") => {},
|
|
|
|
_ => { let _ = c.flag("-g3"); },
|
|
|
|
};
|
2017-03-16 12:43:18 -10:00
|
|
|
if !target.is_debug() {
|
2017-02-19 23:22:21 -10:00
|
|
|
let _ = c.define("NDEBUG", None);
|
|
|
|
if target.env() == "msvc" {
|
|
|
|
let _ = c.flag("/Oi"); // Generate intrinsic functions.
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if target.env() == "msvc" {
|
|
|
|
let _ = c.flag("/Oy-"); // Don't omit frame pointers.
|
|
|
|
// run-time checking: (s)tack frame, (u)ninitialized variables
|
|
|
|
let _ = c.flag("/RTCsu");
|
|
|
|
let _ = c.flag("/Od"); // Disable optimization for debug builds.
|
|
|
|
}
|
|
|
|
}
|
2017-03-05 19:49:44 -10:00
|
|
|
if target.env() != "msvc" {
|
2017-02-19 23:22:21 -10:00
|
|
|
let _ = c.define("_XOPEN_SOURCE", Some("700"));
|
|
|
|
}
|
2017-03-05 19:49:48 -10:00
|
|
|
if target.env() == "musl" {
|
|
|
|
// Some platforms enable _FORTIFY_SOURCE by default, but musl
|
|
|
|
// libc doesn't support it yet. See
|
|
|
|
// http://wiki.musl-libc.org/wiki/Future_Ideas#Fortify
|
|
|
|
// http://www.openwall.com/lists/musl/2015/02/04/3
|
|
|
|
// http://www.openwall.com/lists/musl/2015/06/17/1
|
|
|
|
let _ = c.flag("-U_FORTIFY_SOURCE");
|
|
|
|
}
|
2017-03-14 09:36:15 -10:00
|
|
|
if target.os() == "android" {
|
|
|
|
// Define __ANDROID_API__ to the Android API level we want.
|
|
|
|
// Needed for Android NDK Unified Headers, see:
|
|
|
|
// https://android.googlesource.com/platform/ndk/+/master/docs/UnifiedHeaders.md#Supporting-Unified-Headers-in-Your-Build-System
|
|
|
|
let _ = c.define("__ANDROID_API__", Some("18"));
|
2017-03-06 17:33:40 -08:00
|
|
|
}
|
|
|
|
|
2017-02-19 23:22:21 -10:00
|
|
|
let mut c = c.get_compiler().to_command();
|
|
|
|
let _ = c.arg("-c")
|
|
|
|
.arg(format!("{}{}", target.obj_opt,
|
|
|
|
out_dir.to_str().expect("Invalid path")))
|
|
|
|
.arg(file);
|
|
|
|
c
|
|
|
|
}
|
|
|
|
|
2017-03-17 10:28:50 -10:00
|
|
|
fn yasm(file: &Path, target: &Target, out_file: &Path) -> Command {
|
2017-02-19 23:22:21 -10:00
|
|
|
let (oformat, machine) = if target.arch() == "x86_64" {
|
|
|
|
("--oformat=win64", "--machine=amd64")
|
|
|
|
} else {
|
|
|
|
("--oformat=win32", "--machine=x86")
|
|
|
|
};
|
|
|
|
let mut c = Command::new("yasm.exe");
|
|
|
|
let _ = c.arg("-X").arg("vc")
|
|
|
|
.arg("--dformat=cv8")
|
|
|
|
.arg(oformat)
|
|
|
|
.arg(machine)
|
|
|
|
.arg("-o").arg(out_file.to_str().expect("Invalid path"))
|
|
|
|
.arg(file);
|
|
|
|
c
|
|
|
|
}
|
|
|
|
|
2017-03-04 12:46:36 -10:00
|
|
|
fn use_libcxx(target: &Target) -> bool {
|
|
|
|
target.os() == "macos" ||
|
|
|
|
target.os() == "ios" ||
|
|
|
|
target.os() == "freebsd"
|
2017-03-03 15:25:34 -10:00
|
|
|
}
|
|
|
|
|
2017-01-26 18:07:26 +01:00
|
|
|
fn run_command_with_args<S>(command_name: S, args: &[String])
|
2016-10-26 09:02:30 -10:00
|
|
|
where S: AsRef<std::ffi::OsStr> + Copy
|
|
|
|
{
|
2017-02-19 23:22:21 -10:00
|
|
|
let mut cmd = Command::new(command_name);
|
2017-02-19 20:26:19 -10:00
|
|
|
let _ = cmd.args(args);
|
|
|
|
|
|
|
|
println!("running: {:?}", cmd);
|
|
|
|
|
|
|
|
let status = cmd.status().unwrap_or_else(|e| {
|
|
|
|
panic!("failed to execute {}: {}",
|
|
|
|
command_name.as_ref().to_str().unwrap(), e);
|
|
|
|
});
|
2016-10-26 09:02:30 -10:00
|
|
|
|
|
|
|
if !status.success() {
|
2017-02-19 20:26:19 -10:00
|
|
|
panic!("execution failed");
|
2016-08-14 20:39:12 -10:00
|
|
|
}
|
|
|
|
}
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-03-16 12:43:18 -10:00
|
|
|
fn sources_for_arch(arch: &str) -> Vec<PathBuf> {
|
|
|
|
RING_SRCS.iter()
|
|
|
|
.filter(|&&(ref archs, _)| archs.is_empty() || archs.contains(&arch))
|
|
|
|
.map(|&(_, ref p)| PathBuf::from(p))
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perlasm_src_dsts(out_dir: &Path, arch: &str, os: Option<&str>,
|
|
|
|
perlasm_format: &str) -> Vec<(PathBuf, PathBuf)> {
|
|
|
|
sources_for_arch(arch).iter()
|
|
|
|
.filter(|p| is_perlasm(p))
|
|
|
|
.map(|src| (src.clone(), asm_path(out_dir, src, os, perlasm_format)))
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_perlasm(path: &PathBuf) -> bool {
|
|
|
|
path.extension().unwrap().to_str().unwrap() == "pl"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn asm_path(out_dir: &Path, src: &Path, os: Option<&str>, perlasm_format: &str)
|
|
|
|
-> PathBuf {
|
|
|
|
let src_stem = src.file_stem().expect("source file without basename");
|
2017-03-15 21:22:39 -10:00
|
|
|
|
2017-03-15 20:47:06 -10:00
|
|
|
let mut dst = PathBuf::from(out_dir);
|
2017-03-15 21:22:39 -10:00
|
|
|
let dst_stem = src_stem.to_str().unwrap();
|
2017-03-16 12:43:18 -10:00
|
|
|
let dst_extension = if os == Some("windows") { "asm" } else { "S" };
|
2017-03-15 21:22:39 -10:00
|
|
|
let dst_filename =
|
|
|
|
format!("{}-{}.{}", dst_stem, perlasm_format, dst_extension);
|
|
|
|
dst.push(dst_filename);
|
2017-03-16 12:43:18 -10:00
|
|
|
dst
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perlasm(src_dst: &[(PathBuf, PathBuf)], arch: &str,
|
|
|
|
perlasm_format: &str, includes_modified: Option<SystemTime>) {
|
|
|
|
for &(ref src, ref dst) in src_dst {
|
|
|
|
if let Some(includes_modified) = includes_modified {
|
|
|
|
if !need_run(src, dst, includes_modified) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2017-03-15 21:22:39 -10:00
|
|
|
|
2017-03-17 10:28:50 -10:00
|
|
|
let mut args = Vec::<String>::new();
|
2017-03-16 12:43:18 -10:00
|
|
|
args.push(src.to_string_lossy().into_owned());
|
2017-03-15 20:47:06 -10:00
|
|
|
args.push(perlasm_format.to_owned());
|
|
|
|
if arch == "x86" {
|
2017-03-17 10:28:50 -10:00
|
|
|
args.push("-fPIC".into());
|
|
|
|
args.push("-DOPENSSL_IA32_SSE2".into());
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
2017-03-16 12:43:18 -10:00
|
|
|
// Work around PerlAsm issue for ARM and AAarch64 targets by replacing
|
|
|
|
// back slashes with forward slashes.
|
|
|
|
let dst =
|
|
|
|
dst.to_str().expect("Could not convert path").replace("\\", "/");
|
|
|
|
args.push(dst);
|
2017-03-17 10:28:50 -10:00
|
|
|
run_command_with_args(&get_command("PERL_EXECUTABLE", "perl"), &args);
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Improve include file modification checks.
Treat a missing source file as an error, whereas before we were
treating it as indicating that the target needs to be rebuilt. Because
we do dependency checking bottom-up, not top-down, the source file
always exists. If it doesn't, then that's an error. In particular, it
probably means that build.rs lists some source files that have been
removed. (See the previous commit.)
Also, the original purpose of this commit is to memoize the
modification time of the most recently modified include file, instead
of `stat()`ing each include file over and over again for each source
file. So do that too.
Finally, in the name of simplicity, don't bother tracking test vs.
non-test includes separately. It's rare when any include file changes,
and we don't save much by separating things, so K.I.S.S. to reduce the
chance that things get screwed up.
2017-03-15 23:37:40 -10:00
|
|
|
fn need_run(source: &Path, target: &Path, includes_modified: SystemTime)
|
|
|
|
-> bool {
|
|
|
|
let s_modified = file_modified(source);
|
|
|
|
if let Ok(target_metadata) = std::fs::metadata(target) {
|
|
|
|
let target_modified = target_metadata.modified().unwrap();
|
|
|
|
s_modified >= target_modified || includes_modified >= target_modified
|
2017-02-07 23:19:36 +01:00
|
|
|
} else {
|
Improve include file modification checks.
Treat a missing source file as an error, whereas before we were
treating it as indicating that the target needs to be rebuilt. Because
we do dependency checking bottom-up, not top-down, the source file
always exists. If it doesn't, then that's an error. In particular, it
probably means that build.rs lists some source files that have been
removed. (See the previous commit.)
Also, the original purpose of this commit is to memoize the
modification time of the most recently modified include file, instead
of `stat()`ing each include file over and over again for each source
file. So do that too.
Finally, in the name of simplicity, don't bother tracking test vs.
non-test includes separately. It's rare when any include file changes,
and we don't save much by separating things, so K.I.S.S. to reduce the
chance that things get screwed up.
2017-03-15 23:37:40 -10:00
|
|
|
// On error fetching metadata for the target file, assume the target
|
|
|
|
// doesn't exist.
|
|
|
|
true
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Improve include file modification checks.
Treat a missing source file as an error, whereas before we were
treating it as indicating that the target needs to be rebuilt. Because
we do dependency checking bottom-up, not top-down, the source file
always exists. If it doesn't, then that's an error. In particular, it
probably means that build.rs lists some source files that have been
removed. (See the previous commit.)
Also, the original purpose of this commit is to memoize the
modification time of the most recently modified include file, instead
of `stat()`ing each include file over and over again for each source
file. So do that too.
Finally, in the name of simplicity, don't bother tracking test vs.
non-test includes separately. It's rare when any include file changes,
and we don't save much by separating things, so K.I.S.S. to reduce the
chance that things get screwed up.
2017-03-15 23:37:40 -10:00
|
|
|
fn file_modified(path: &Path) -> SystemTime {
|
|
|
|
let path = Path::new(path);
|
|
|
|
let path_as_str = format!("{:?}", path);
|
|
|
|
std::fs::metadata(path).expect(&path_as_str).modified().expect("nah")
|
|
|
|
}
|
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
fn get_command(var: &str, default: &str) -> String {
|
2017-03-16 12:43:18 -10:00
|
|
|
std::env::var(var).unwrap_or(default.into())
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn check_all_files_tracked() {
|
2017-02-07 23:32:13 +01:00
|
|
|
let _ = rayon::join(|| walk_dir(&PathBuf::from("crypto"), &is_tracked),
|
|
|
|
|| walk_dir(&PathBuf::from("include"), &is_tracked));
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn is_tracked(file: &DirEntry) {
|
|
|
|
let p = file.path();
|
|
|
|
let cmp = |f| p == PathBuf::from(f);
|
|
|
|
let tracked = match p.extension().and_then(|p| p.to_str()) {
|
2017-03-17 11:28:43 -10:00
|
|
|
Some("h") |
|
|
|
|
Some("inl") => {
|
|
|
|
RING_INCLUDES.iter().any(cmp)
|
2017-02-07 23:19:36 +01:00
|
|
|
},
|
2017-03-17 10:28:50 -10:00
|
|
|
Some("c") |
|
|
|
|
Some("cc") |
|
2017-02-19 23:22:21 -10:00
|
|
|
Some("S") |
|
|
|
|
Some("asm") => {
|
2017-03-17 10:28:50 -10:00
|
|
|
RING_SRCS.iter().any(|&(_, ref f)| cmp(f)) ||
|
|
|
|
RING_TEST_SRCS.iter().any(cmp)
|
2017-02-07 23:19:36 +01:00
|
|
|
},
|
|
|
|
Some("pl") => {
|
2017-03-17 10:28:50 -10:00
|
|
|
RING_SRCS.iter().any(|&(_, ref f)| cmp(f)) ||
|
|
|
|
RING_PERL_INCLUDES.iter().any(cmp)
|
2017-02-07 23:19:36 +01:00
|
|
|
},
|
|
|
|
_ => true,
|
|
|
|
};
|
|
|
|
if !tracked {
|
|
|
|
panic!("{:?} is not tracked in build.rs", p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn walk_dir<F>(dir: &Path, cb: &F)
|
|
|
|
where F: Fn(&DirEntry)
|
|
|
|
{
|
|
|
|
if dir.is_dir() {
|
|
|
|
for entry in fs::read_dir(dir).unwrap() {
|
|
|
|
let entry = entry.unwrap();
|
|
|
|
let path = entry.path();
|
|
|
|
if path.is_dir() {
|
|
|
|
walk_dir(&path, cb);
|
|
|
|
} else {
|
|
|
|
cb(&entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|