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.
|
|
|
|
|
2017-08-27 11:43:09 -10:00
|
|
|
//! Build the non-Rust components.
|
|
|
|
|
2017-08-27 11:50:07 -10:00
|
|
|
#![deny(
|
2017-08-27 11:43:09 -10:00
|
|
|
box_pointers,
|
|
|
|
)]
|
|
|
|
|
|
|
|
#![forbid(
|
|
|
|
anonymous_parameters,
|
|
|
|
legacy_directory_ownership,
|
2016-02-04 14:40:20 -10:00
|
|
|
missing_copy_implementations,
|
|
|
|
missing_debug_implementations,
|
2017-08-27 11:43:09 -10:00
|
|
|
missing_docs,
|
2016-02-04 14:40:20 -10:00
|
|
|
trivial_casts,
|
|
|
|
trivial_numeric_casts,
|
|
|
|
unsafe_code,
|
|
|
|
unstable_features,
|
|
|
|
unused_extern_crates,
|
|
|
|
unused_import_braces,
|
2017-05-17 21:47:52 -10:00
|
|
|
unused_qualifications,
|
2016-02-04 14:40:20 -10:00
|
|
|
unused_results,
|
|
|
|
variant_size_differences,
|
|
|
|
warnings,
|
|
|
|
)]
|
|
|
|
|
2017-09-19 18:31:26 -10:00
|
|
|
extern crate cc;
|
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;
|
2015-11-11 12:28:43 -10:00
|
|
|
|
2018-11-03 13:32:36 -10:00
|
|
|
const X86: &str = "x86";
|
|
|
|
const X86_64: &str = "x86_64";
|
|
|
|
const AARCH64: &str = "aarch64";
|
|
|
|
const ARM: &str = "arm";
|
|
|
|
const NEVER: &str = "Don't ever build this file.";
|
2015-07-30 19:48:38 -04:00
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
2018-11-03 13:32:36 -10:00
|
|
|
const RING_SRCS: &[(&[&str], &str)] = &[
|
2018-01-09 12:34:53 -10:00
|
|
|
(&[], "crypto/fipsmodule/aes/aes.c"),
|
2018-04-27 15:12:08 -10:00
|
|
|
(&[], "crypto/fipsmodule/bn/exponentiation.c"),
|
|
|
|
(&[], "crypto/fipsmodule/bn/generic.c"),
|
|
|
|
(&[], "crypto/fipsmodule/bn/montgomery.c"),
|
|
|
|
(&[], "crypto/fipsmodule/bn/montgomery_inv.c"),
|
|
|
|
(&[], "crypto/fipsmodule/bn/shift.c"),
|
2018-04-28 15:48:38 -10:00
|
|
|
(&[], "crypto/fipsmodule/cipher/e_aes.c"),
|
|
|
|
(&[NEVER], "crypto/cipher_extra/e_aesgcmsiv.c"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[], "crypto/crypto.c"),
|
2018-04-27 16:30:52 -10:00
|
|
|
(&[], "crypto/fipsmodule/ec/ecp_nistz.c"),
|
|
|
|
(&[], "crypto/fipsmodule/ec/ecp_nistz256.c"),
|
|
|
|
(&[], "crypto/fipsmodule/ec/gfp_p256.c"),
|
|
|
|
(&[], "crypto/fipsmodule/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"),
|
2018-01-09 16:55:20 -10:00
|
|
|
(&[], "crypto/fipsmodule/modes/gcm.c"),
|
2018-04-28 16:44:03 -10:00
|
|
|
(&[NEVER], "crypto/fipsmodule/modes/polyval.c"),
|
2018-04-30 13:37:38 -10:00
|
|
|
(&[], "third_party/fiat/curve25519.c"),
|
2017-03-17 10:28:50 -10:00
|
|
|
|
|
|
|
(&[X86_64, X86], "crypto/cpu-intel.c"),
|
|
|
|
|
2018-01-09 12:34:53 -10:00
|
|
|
(&[X86], "crypto/fipsmodule/aes/asm/aes-586.pl"),
|
|
|
|
(&[X86], "crypto/fipsmodule/aes/asm/aesni-x86.pl"),
|
|
|
|
(&[X86], "crypto/fipsmodule/aes/asm/vpaes-x86.pl"),
|
2018-04-27 15:12:08 -10:00
|
|
|
(&[X86], "crypto/fipsmodule/bn/asm/x86-mont.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[X86], "crypto/chacha/asm/chacha-x86.pl"),
|
2018-04-27 16:30:52 -10:00
|
|
|
(&[X86], "crypto/fipsmodule/ec/asm/ecp_nistz256-x86.pl"),
|
2018-01-09 16:55:20 -10:00
|
|
|
(&[X86], "crypto/fipsmodule/modes/asm/ghash-x86.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[X86], "crypto/poly1305/asm/poly1305-x86.pl"),
|
2017-12-29 13:22:56 -10:00
|
|
|
(&[X86], "crypto/fipsmodule/sha/asm/sha256-586.pl"),
|
|
|
|
(&[X86], "crypto/fipsmodule/sha/asm/sha512-586.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
|
2018-01-09 12:34:53 -10:00
|
|
|
(&[X86_64], "crypto/fipsmodule/aes/asm/aes-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/fipsmodule/aes/asm/aesni-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/fipsmodule/aes/asm/vpaes-x86_64.pl"),
|
2018-04-27 15:12:08 -10:00
|
|
|
(&[X86_64], "crypto/fipsmodule/bn/asm/x86_64-mont.pl"),
|
|
|
|
(&[X86_64], "crypto/fipsmodule/bn/asm/x86_64-mont5.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[X86_64], "crypto/chacha/asm/chacha-x86_64.pl"),
|
2018-04-28 15:48:38 -10:00
|
|
|
(&[NEVER], "crypto/cipher_extra/asm/aes128gcmsiv-x86_64.pl"),
|
2018-04-27 16:30:52 -10:00
|
|
|
(&[X86_64], "crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl"),
|
2018-01-09 16:55:20 -10:00
|
|
|
(&[X86_64], "crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl"),
|
|
|
|
(&[X86_64], "crypto/fipsmodule/modes/asm/ghash-x86_64.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[X86_64], "crypto/poly1305/asm/poly1305-x86_64.pl"),
|
2017-03-18 13:26:00 -10:00
|
|
|
(&[X86_64], SHA512_X86_64),
|
2017-03-17 10:28:50 -10:00
|
|
|
|
2018-01-09 12:34:53 -10:00
|
|
|
(&[AARCH64, ARM], "crypto/fipsmodule/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"),
|
2018-01-09 16:55:20 -10:00
|
|
|
(&[AARCH64, ARM], "crypto/fipsmodule/modes/asm/ghashv8-armx.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
|
2018-01-09 12:34:53 -10:00
|
|
|
(&[ARM], "crypto/fipsmodule/aes/asm/aes-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/fipsmodule/aes/asm/bsaes-armv7.pl"),
|
2018-04-27 15:12:08 -10:00
|
|
|
(&[ARM], "crypto/fipsmodule/bn/asm/armv4-mont.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[ARM], "crypto/chacha/asm/chacha-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/curve25519/asm/x25519-asm-arm.S"),
|
2018-04-27 16:30:52 -10:00
|
|
|
(&[ARM], "crypto/fipsmodule/ec/asm/ecp_nistz256-armv4.pl"),
|
2018-01-09 16:55:20 -10:00
|
|
|
(&[ARM], "crypto/fipsmodule/modes/asm/ghash-armv4.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[ARM], "crypto/poly1305/asm/poly1305-armv4.pl"),
|
2017-12-29 13:22:56 -10:00
|
|
|
(&[ARM], "crypto/fipsmodule/sha/asm/sha256-armv4.pl"),
|
|
|
|
(&[ARM], "crypto/fipsmodule/sha/asm/sha512-armv4.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
|
2018-04-27 15:12:08 -10:00
|
|
|
(&[AARCH64], "crypto/fipsmodule/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"),
|
2018-04-27 16:30:52 -10:00
|
|
|
(&[AARCH64], "crypto/fipsmodule/ec/asm/ecp_nistz256-armv8.pl"),
|
2017-03-17 10:28:50 -10:00
|
|
|
(&[AARCH64], "crypto/poly1305/asm/poly1305-armv8.pl"),
|
2017-03-18 13:26:00 -10:00
|
|
|
(&[AARCH64], SHA512_ARMV8),
|
2017-03-17 10:28:50 -10:00
|
|
|
];
|
|
|
|
|
2018-11-03 13:32:36 -10:00
|
|
|
const SHA256_X86_64: &str = "crypto/fipsmodule/sha/asm/sha256-x86_64.pl";
|
|
|
|
const SHA512_X86_64: &str = "crypto/fipsmodule/sha/asm/sha512-x86_64.pl";
|
2017-03-18 13:26:00 -10:00
|
|
|
|
2018-11-03 13:32:36 -10:00
|
|
|
const SHA256_ARMV8: &str = "crypto/fipsmodule/sha/asm/sha256-armv8.pl";
|
|
|
|
const SHA512_ARMV8: &str = "crypto/fipsmodule/sha/asm/sha512-armv8.pl";
|
2017-03-18 13:26:00 -10:00
|
|
|
|
2018-11-03 13:32:36 -10:00
|
|
|
const RING_TEST_SRCS: &[&str] = &[
|
2017-03-17 10:28:50 -10:00
|
|
|
("crypto/constant_time_test.c"),
|
|
|
|
];
|
2015-07-30 19:48:38 -04:00
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
2018-11-03 13:32:36 -10:00
|
|
|
const RING_INCLUDES: &[&str] =
|
2018-04-28 15:48:38 -10:00
|
|
|
&["crypto/fipsmodule/aes/internal.h",
|
|
|
|
"crypto/fipsmodule/bn/internal.h",
|
|
|
|
"crypto/fipsmodule/cipher/internal.h",
|
2018-04-27 16:30:52 -10:00
|
|
|
"crypto/fipsmodule/ec/ecp_nistz256_table.inl",
|
|
|
|
"crypto/fipsmodule/ec/ecp_nistz384.inl",
|
|
|
|
"crypto/fipsmodule/ec/ecp_nistz.h",
|
|
|
|
"crypto/fipsmodule/ec/ecp_nistz384.h",
|
|
|
|
"crypto/fipsmodule/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",
|
2018-01-09 16:55:20 -10:00
|
|
|
"crypto/fipsmodule/modes/internal.h",
|
2017-04-19 14:56:44 -10:00
|
|
|
"include/GFp/aes.h",
|
|
|
|
"include/GFp/arm_arch.h",
|
|
|
|
"include/GFp/base.h",
|
|
|
|
"include/GFp/cpu.h",
|
|
|
|
"include/GFp/mem.h",
|
2018-04-30 13:37:38 -10:00
|
|
|
"include/GFp/type_check.h",
|
2018-05-01 11:11:55 -10:00
|
|
|
"third_party/fiat/curve25519_tables.h",
|
2018-04-30 13:37:38 -10:00
|
|
|
"third_party/fiat/internal.h",
|
|
|
|
];
|
2016-08-15 13:34:13 -10:00
|
|
|
|
2017-02-07 23:19:36 +01:00
|
|
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
2018-11-03 13:32:36 -10:00
|
|
|
const RING_PERL_INCLUDES: &[&str] =
|
2017-03-17 11:36:03 -10:00
|
|
|
&["crypto/perlasm/arm-xlate.pl",
|
2017-02-07 23:19:36 +01:00
|
|
|
"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
|
|
|
|
2018-11-03 13:32:36 -10:00
|
|
|
const RING_BUILD_FILE: &[&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] {
|
2017-03-18 10:16:16 -10:00
|
|
|
if target.env != MSVC {
|
2018-11-03 13:32:36 -10:00
|
|
|
static NON_MSVC_FLAGS: &[&str] = &[
|
2017-02-19 23:22:21 -10:00
|
|
|
"-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 cpp_flags(target: &Target) -> &'static [&'static str] {
|
2017-03-18 10:16:16 -10:00
|
|
|
if target.env != MSVC {
|
2018-11-03 13:32:36 -10:00
|
|
|
static NON_MSVC_FLAGS: &[&str] = &[
|
2017-02-19 23:22:21 -10:00
|
|
|
"-pedantic",
|
|
|
|
"-pedantic-errors",
|
|
|
|
"-Wall",
|
|
|
|
"-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 {
|
2018-11-03 13:32:36 -10:00
|
|
|
static MSVC_FLAGS: &[&str] = &[
|
2017-02-19 23:22:21 -10:00
|
|
|
"/GS", // Buffer security checks.
|
2017-03-18 16:58:14 -10:00
|
|
|
"/Gy", // Enable function-level linking.
|
|
|
|
|
|
|
|
"/EHsc", // C++ exceptions only, only in C++.
|
|
|
|
"/GR-", // Disable RTTI.
|
2017-02-19 23:22:21 -10:00
|
|
|
|
|
|
|
"/Zc:wchar_t",
|
|
|
|
"/Zc:forScope",
|
|
|
|
"/Zc:inline",
|
|
|
|
"/Zc:rvalueCast",
|
|
|
|
|
|
|
|
// Warnings.
|
|
|
|
"/sdl",
|
|
|
|
"/Wall",
|
|
|
|
"/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>
|
2018-05-09 13:09:35 +02:00
|
|
|
"/wd5045", // C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
|
2017-02-19 23:22:21 -10:00
|
|
|
];
|
|
|
|
MSVC_FLAGS
|
|
|
|
}
|
|
|
|
}
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2018-11-03 13:32:36 -10:00
|
|
|
const LD_FLAGS: &[&str] = &[];
|
2017-02-07 23:19:36 +01:00
|
|
|
|
2017-03-15 20:47:06 -10:00
|
|
|
// None means "any OS" or "any target". The first match in sequence order is
|
|
|
|
// taken.
|
2018-11-03 13:32:36 -10:00
|
|
|
const ASM_TARGETS: &[(&str, Option<&str>, &str)] = &[
|
2017-10-18 17:06:11 -07:00
|
|
|
("x86_64", Some("ios"), "macosx"),
|
2017-03-15 20:47:06 -10:00
|
|
|
("x86_64", Some("macos"), "macosx"),
|
2017-03-18 10:16:16 -10:00
|
|
|
("x86_64", Some(WINDOWS), "nasm"),
|
2017-03-15 20:47:06 -10:00
|
|
|
("x86_64", None, "elf"),
|
|
|
|
("aarch64", Some("ios"), "ios64"),
|
|
|
|
("aarch64", None, "linux64"),
|
2017-03-18 10:16:16 -10:00
|
|
|
("x86", Some(WINDOWS), "win32n"),
|
2017-10-27 10:41:35 -07:00
|
|
|
("x86", Some("ios"), "macosx"),
|
2017-03-15 20:47:06 -10:00
|
|
|
("x86", None, "elf"),
|
|
|
|
("arm", Some("ios"), "ios32"),
|
|
|
|
("arm", None, "linux32"),
|
|
|
|
];
|
|
|
|
|
2017-03-18 10:16:16 -10:00
|
|
|
const WINDOWS: &'static str = "windows";
|
|
|
|
const MSVC: &'static str = "msvc";
|
|
|
|
const MSVC_OBJ_OPT: &'static str = "/Fo";
|
|
|
|
const MSVC_OBJ_EXT: &'static str = "obj";
|
|
|
|
|
|
|
|
|
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-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();
|
2017-04-11 18:12:13 -10:00
|
|
|
let (obj_ext, obj_opt) = if env == MSVC {
|
2017-03-18 10:16:16 -10:00
|
|
|
(MSVC_OBJ_EXT, MSVC_OBJ_OPT)
|
2017-03-16 12:43:18 -10:00
|
|
|
} else {
|
|
|
|
("o", "-o")
|
|
|
|
};
|
|
|
|
|
2017-04-27 11:58:20 -10:00
|
|
|
let is_debug = env::var("DEBUG").unwrap() != "false";
|
|
|
|
let target = Target { arch, os, env, obj_ext, obj_opt, is_debug };
|
2017-04-11 17:55:39 -10:00
|
|
|
let pregenerated =
|
|
|
|
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
|
|
|
|
.join(PREGENERATED);
|
|
|
|
|
2018-05-14 18:18:32 -10:00
|
|
|
build_c_code(&target, pregenerated, &out_dir);
|
|
|
|
check_all_files_tracked()
|
2017-03-16 12:43:18 -10:00
|
|
|
}
|
|
|
|
|
|
|
|
fn pregenerate_asm_main() {
|
|
|
|
let pregenerated = PathBuf::from(PREGENERATED);
|
|
|
|
std::fs::create_dir(&pregenerated).unwrap();
|
2017-03-18 10:16:16 -10:00
|
|
|
let pregenerated_tmp = pregenerated.join("tmp");
|
|
|
|
std::fs::create_dir(&pregenerated_tmp).unwrap();
|
2017-03-16 12:43:18 -10:00
|
|
|
|
|
|
|
for &(target_arch, target_os, perlasm_format) in ASM_TARGETS {
|
2017-03-18 10:16:16 -10:00
|
|
|
// For Windows, package pregenerated object files instead of
|
|
|
|
// pregenerated assembly language source files, so that the user
|
|
|
|
// doesn't need to install the assembler.
|
|
|
|
let asm_dir = if target_os == Some(WINDOWS) {
|
|
|
|
&pregenerated_tmp
|
|
|
|
} else {
|
|
|
|
&pregenerated
|
|
|
|
};
|
|
|
|
|
2017-03-16 12:43:18 -10:00
|
|
|
let perlasm_src_dsts =
|
2017-03-18 10:16:16 -10:00
|
|
|
perlasm_src_dsts(&asm_dir, target_arch, target_os, perlasm_format);
|
2017-03-16 12:43:18 -10:00
|
|
|
perlasm(&perlasm_src_dsts, target_arch, perlasm_format, None);
|
2017-03-18 10:16:16 -10:00
|
|
|
|
|
|
|
if target_os == Some(WINDOWS) {
|
|
|
|
//let lib_name = ring_asm_name(target_arch);
|
|
|
|
let srcs = asm_srcs(perlasm_src_dsts);
|
|
|
|
for src in srcs {
|
|
|
|
let src_path = PathBuf::from(src);
|
|
|
|
let obj_path =
|
|
|
|
obj_path(&pregenerated, &src_path, MSVC_OBJ_EXT);
|
|
|
|
run_command(yasm(&src_path, target_arch, &obj_path));
|
|
|
|
}
|
|
|
|
}
|
2017-03-16 12:43:18 -10:00
|
|
|
}
|
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-04-11 17:55:39 -10:00
|
|
|
fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) {
|
2018-05-14 18:18:32 -10:00
|
|
|
let includes_modified = RING_INCLUDES.iter()
|
|
|
|
.chain(RING_BUILD_FILE.iter())
|
|
|
|
.chain(RING_PERL_INCLUDES.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
|
|
|
.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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-10 13:38:03 -10:00
|
|
|
let (_, _, perlasm_format) = ASM_TARGETS.iter().find(|entry| {
|
2017-03-15 20:47:06 -10:00
|
|
|
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
|
|
|
|
2017-04-25 10:44:53 -10:00
|
|
|
let is_git = std::fs::metadata(".git").is_ok();
|
|
|
|
|
|
|
|
let use_pregenerated = !is_git;
|
|
|
|
let warnings_are_errors = is_git;
|
2017-03-16 12:43:18 -10:00
|
|
|
|
2017-03-18 10:54:33 -10:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2017-03-18 10:16:16 -10:00
|
|
|
let mut asm_srcs = asm_srcs(perlasm_src_dsts);
|
|
|
|
|
|
|
|
// For Windows we also pregenerate the object files for non-Git builds so
|
|
|
|
// the user doesn't need to install the assembler. On other platforms we
|
|
|
|
// assume the C compiler also assembles.
|
|
|
|
if use_pregenerated && target.os() == WINDOWS {
|
2017-04-11 18:16:23 -10:00
|
|
|
// The pregenerated object files always use ".obj" as the extension,
|
|
|
|
// even when the C/C++ compiler outputs files with the ".o" extension.
|
2017-03-18 10:16:16 -10:00
|
|
|
asm_srcs = asm_srcs.iter()
|
2017-04-11 18:16:23 -10:00
|
|
|
.map(|src| obj_path(&pregenerated, src.as_path(), "obj"))
|
2017-03-18 10:16:16 -10:00
|
|
|
.collect::<Vec<_>>();
|
|
|
|
}
|
2017-03-16 12:43:18 -10:00
|
|
|
|
2017-03-18 10:31:13 -10:00
|
|
|
let core_srcs = sources_for_arch(target.arch()).into_iter()
|
2017-03-16 12:43:18 -10:00
|
|
|
.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-18 10:31:13 -10:00
|
|
|
let libs = [
|
|
|
|
("ring-core", &core_srcs[..], &asm_srcs[..]),
|
|
|
|
("ring-test", &test_srcs[..], &[]),
|
|
|
|
];
|
|
|
|
|
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.
|
2018-05-14 18:18:32 -10:00
|
|
|
libs.into_iter()
|
2017-03-18 10:31:13 -10:00
|
|
|
.for_each(|&(lib_name, srcs, additional_srcs)|
|
|
|
|
build_library(&target, &out_dir, lib_name, srcs, additional_srcs,
|
2017-04-25 10:44:53 -10:00
|
|
|
warnings_are_errors, includes_modified));
|
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-18 10:31:13 -10:00
|
|
|
fn build_library(target: &Target, out_dir: &Path, lib_name: &str,
|
|
|
|
srcs: &[PathBuf], additional_srcs: &[PathBuf],
|
2017-04-25 10:44:53 -10:00
|
|
|
warnings_are_errors: bool, includes_modified: SystemTime) {
|
2017-02-07 23:29:00 +01:00
|
|
|
// Compile all the (dirty) source files into object files.
|
2017-08-27 11:50:07 -10:00
|
|
|
#[allow(box_pointers)] // XXX
|
2018-05-14 18:18:32 -10:00
|
|
|
let objs = additional_srcs.into_iter().chain(srcs.into_iter())
|
2017-03-17 10:28:50 -10:00
|
|
|
.filter(|f|
|
|
|
|
target.env() != "msvc" ||
|
|
|
|
f.extension().unwrap().to_str().unwrap() != "S")
|
2017-04-25 10:44:53 -10:00
|
|
|
.map(|f| compile(f, target, warnings_are_errors, out_dir,
|
|
|
|
includes_modified))
|
2018-05-14 18:18:32 -10:00
|
|
|
.collect::<Vec<_>>();
|
2017-02-07 23:29:00 +01:00
|
|
|
|
2017-03-18 10:54:33 -10:00
|
|
|
// Rebuild the library if necessary.
|
2017-03-18 10:31:13 -10:00
|
|
|
let lib_path = PathBuf::from(out_dir).join(format!("lib{}.a", lib_name));
|
|
|
|
|
2018-05-14 18:18:32 -10:00
|
|
|
if objs.iter()
|
|
|
|
.map(Path::new)
|
2017-03-18 10:31:13 -10:00
|
|
|
.any(|p| need_run(&p, &lib_path, includes_modified)) {
|
2017-09-19 18:31:26 -10:00
|
|
|
let mut c = cc::Build::new();
|
2017-02-07 23:19:36 +01:00
|
|
|
|
|
|
|
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-18 10:31:13 -10:00
|
|
|
c.compile(lib_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-04-25 10:44:53 -10:00
|
|
|
fn compile(p: &Path, target: &Target, warnings_are_errors: bool, 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:16:16 -10:00
|
|
|
let ext = p.extension().unwrap().to_str().unwrap();
|
|
|
|
if ext == "obj" {
|
|
|
|
p.to_str().expect("Invalid path").into()
|
|
|
|
} else {
|
|
|
|
let mut out_path = out_dir.clone().join(p.file_name().unwrap());
|
2017-08-27 14:56:23 -10:00
|
|
|
assert!(out_path.set_extension(target.obj_ext));
|
2017-03-18 10:16:16 -10:00
|
|
|
if need_run(&p, &out_path, includes_modified) {
|
2017-04-01 23:14:37 +08:00
|
|
|
let cmd = if target.os() != WINDOWS || ext != "asm" {
|
2017-04-25 10:44:53 -10:00
|
|
|
cc(p, ext, target, warnings_are_errors, &out_path)
|
2017-03-18 10:16:16 -10:00
|
|
|
} else {
|
|
|
|
yasm(p, target.arch(), &out_path)
|
|
|
|
};
|
|
|
|
|
|
|
|
run_command(cmd);
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
2017-03-18 10:16:16 -10:00
|
|
|
out_path.to_str().expect("Invalid path").into()
|
2017-02-07 23:19:36 +01:00
|
|
|
}
|
2017-03-18 10:16:16 -10:00
|
|
|
}
|
|
|
|
|
|
|
|
fn obj_path(out_dir: &Path, src: &Path, obj_ext: &str) -> PathBuf {
|
|
|
|
let mut out_path = out_dir.clone().join(src.file_name().unwrap());
|
2017-08-27 14:56:23 -10:00
|
|
|
assert!(out_path.set_extension(obj_ext));
|
2017-03-18 10:16:16 -10:00
|
|
|
out_path
|
2016-10-26 11:44:22 +02:00
|
|
|
}
|
|
|
|
|
2017-04-25 10:44:53 -10:00
|
|
|
fn cc(file: &Path, ext: &str, target: &Target, warnings_are_errors: bool,
|
|
|
|
out_dir: &Path)
|
|
|
|
-> Command {
|
2017-09-19 18:31:26 -10:00
|
|
|
let mut c = cc::Build::new();
|
2017-02-19 23:22:21 -10:00
|
|
|
let _ = c.include("include");
|
|
|
|
match ext {
|
|
|
|
"c" => {
|
|
|
|
for f in c_flags(target) {
|
|
|
|
let _ = c.flag(f);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"S" => {},
|
|
|
|
e => panic!("Unsupported file extension: {:?}", e),
|
|
|
|
};
|
|
|
|
for f in cpp_flags(target) {
|
|
|
|
let _ = c.flag(&f);
|
|
|
|
}
|
|
|
|
if target.os() != "none" &&
|
|
|
|
target.os() != "redox" &&
|
2017-04-01 23:14:37 +08:00
|
|
|
target.os() != "windows" {
|
2017-02-19 23:22:21 -10:00
|
|
|
let _ = c.flag("-fstack-protector");
|
|
|
|
}
|
2017-03-18 16:58:14 -10:00
|
|
|
|
2017-02-19 23:22:21 -10:00
|
|
|
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);
|
2017-03-18 16:58:14 -10:00
|
|
|
}
|
|
|
|
|
|
|
|
if target.env() == "msvc" {
|
|
|
|
if std::env::var("OPT_LEVEL").unwrap() == "0" {
|
|
|
|
let _ = c.flag("/Od"); // Disable optimization for debug builds.
|
2017-02-19 23:22:21 -10:00
|
|
|
// run-time checking: (s)tack frame, (u)ninitialized variables
|
|
|
|
let _ = c.flag("/RTCsu");
|
2017-03-18 16:58:14 -10:00
|
|
|
} else {
|
|
|
|
let _ = c.flag("/Ox"); // Enable full optimization.
|
2017-02-19 23:22:21 -10:00
|
|
|
}
|
|
|
|
}
|
2017-03-18 16:58:14 -10:00
|
|
|
|
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"));
|
2018-05-14 17:52:01 -10:00
|
|
|
}
|
|
|
|
|
|
|
|
if warnings_are_errors {
|
|
|
|
let flag = if target.env() != "msvc" {
|
|
|
|
"-Werror"
|
|
|
|
} else {
|
|
|
|
"/WX"
|
|
|
|
};
|
|
|
|
let _ = c.flag(flag);
|
2017-02-19 23:22:21 -10:00
|
|
|
}
|
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-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-18 10:16:16 -10:00
|
|
|
fn yasm(file: &Path, arch: &str, out_file: &Path) -> Command {
|
|
|
|
let (oformat, machine) = match arch {
|
|
|
|
"x86_64" => ("--oformat=win64", "--machine=amd64"),
|
|
|
|
"x86" => ("--oformat=win32", "--machine=x86"),
|
|
|
|
_ => panic!("unsupported arch: {}", arch),
|
2017-02-19 23:22:21 -10:00
|
|
|
};
|
|
|
|
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-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);
|
2017-03-18 10:16:16 -10:00
|
|
|
run_command(cmd)
|
|
|
|
}
|
2017-02-19 20:26:19 -10:00
|
|
|
|
2017-03-18 10:16:16 -10:00
|
|
|
fn run_command(mut cmd: Command) {
|
|
|
|
println!("running {:?}", cmd);
|
2017-02-19 20:26:19 -10:00
|
|
|
let status = cmd.status().unwrap_or_else(|e| {
|
2017-04-11 15:18:02 -10:00
|
|
|
panic!("failed to execute [{:?}]: {}", cmd, e);
|
2017-02-19 20:26:19 -10:00
|
|
|
});
|
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()
|
2018-05-10 12:24:19 -10:00
|
|
|
.filter(|&&(archs, _)| archs.is_empty() || archs.contains(&arch))
|
|
|
|
.map(|&(_, p)| PathBuf::from(p))
|
2017-03-16 12:43:18 -10:00
|
|
|
.collect::<Vec<_>>()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perlasm_src_dsts(out_dir: &Path, arch: &str, os: Option<&str>,
|
|
|
|
perlasm_format: &str) -> Vec<(PathBuf, PathBuf)> {
|
2017-03-18 13:26:00 -10:00
|
|
|
let srcs = sources_for_arch(arch);
|
|
|
|
let mut src_dsts = srcs.iter()
|
2017-03-16 12:43:18 -10:00
|
|
|
.filter(|p| is_perlasm(p))
|
|
|
|
.map(|src| (src.clone(), asm_path(out_dir, src, os, perlasm_format)))
|
2017-03-18 13:26:00 -10:00
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
// Some PerlAsm source files need to be run multiple times with different
|
|
|
|
// output paths.
|
|
|
|
{ // Appease the borrow checker.
|
|
|
|
let mut maybe_synthesize = |concrete, synthesized| {
|
|
|
|
let concrete_path = PathBuf::from(concrete);
|
|
|
|
if srcs.contains(&concrete_path) {
|
|
|
|
let synthesized_path = PathBuf::from(synthesized);
|
|
|
|
src_dsts.push((concrete_path,
|
|
|
|
asm_path(out_dir, &synthesized_path, os,
|
|
|
|
perlasm_format)))
|
|
|
|
}
|
|
|
|
};
|
|
|
|
maybe_synthesize(SHA512_X86_64, SHA256_X86_64);
|
|
|
|
maybe_synthesize(SHA512_ARMV8, SHA256_ARMV8);
|
|
|
|
}
|
|
|
|
|
|
|
|
src_dsts
|
2017-03-16 12:43:18 -10:00
|
|
|
}
|
|
|
|
|
2017-03-18 10:16:16 -10:00
|
|
|
fn asm_srcs(perlasm_src_dsts: Vec<(PathBuf, PathBuf)>) -> Vec<PathBuf> {
|
|
|
|
perlasm_src_dsts.into_iter()
|
|
|
|
.map(|(_src, dst)| dst)
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
}
|
|
|
|
|
2017-03-16 12:43:18 -10:00
|
|
|
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
|
|
|
|
|
|
|
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);
|
2017-03-18 10:16:46 -10:00
|
|
|
out_dir.join(dst_filename)
|
2017-03-16 12:43:18 -10:00
|
|
|
}
|
|
|
|
|
|
|
|
fn perlasm(src_dst: &[(PathBuf, PathBuf)], arch: &str,
|
|
|
|
perlasm_format: &str, includes_modified: Option<SystemTime>) {
|
2018-05-10 12:24:19 -10:00
|
|
|
for (src, dst) in src_dst {
|
2017-03-16 12:43:18 -10:00
|
|
|
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() {
|
2018-05-03 12:44:11 -10:00
|
|
|
for path in &["crypto", "include", "third_party/fiat"] {
|
|
|
|
walk_dir(&PathBuf::from(path), &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") |
|
2017-02-19 23:22:21 -10:00
|
|
|
Some("S") |
|
|
|
|
Some("asm") => {
|
2018-05-10 12:24:19 -10:00
|
|
|
RING_SRCS.iter().any(|(_, f)| cmp(f)) ||
|
2017-03-17 10:28:50 -10:00
|
|
|
RING_TEST_SRCS.iter().any(cmp)
|
2017-02-07 23:19:36 +01:00
|
|
|
},
|
|
|
|
Some("pl") => {
|
2018-05-10 12:24:19 -10:00
|
|
|
RING_SRCS.iter().any(|(_, f)| cmp(f)) ||
|
2017-03-17 10:28:50 -10:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|