1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// The build for pcre2-sys currently does roughly the following:
//
// 1. Use the PCRE2 system library as reported by pkg-config if it exists
// and only if we don't explicitly want a static build.
// 2. Otherwise, statically build PCRE2 by hand.
//
// For step 1, we permit opting out of using the system library via either
// explicitly setting the PCRE2_SYS_STATIC environment variable or if we
// otherwise believe we want a static build (e.g., when building with MUSL).
//
// For step 2, we roughly follow the directions as laid out in
// pcre2/NON-AUTOTOOLS-BUILD. It's pretty straight-forward: copy a few files,
// set a few defines and then build it. We can get away with a pretty stripped
// down setup here since the PCRE2 build setup also handles various command
// line tools (like pcre2grep) and its test infrastructure, and we needn't
// concern ourselves with that.
//
// It is plausible that this build script will need to evolve to do better
// platform detection for the various PCRE2 settings, but this should work
// as-is on Windows, Linux and macOS.
use std::path::PathBuf;
fn main() {
println!("cargo:rerun-if-env-changed=PCRE2_SYS_STATIC");
let target = std::env::var("TARGET").unwrap();
// let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
let upstream = PathBuf::from("upstream");
// Don't link to a system library if we want a static build.
let want_static = pcre2_sys_static().unwrap_or(target.contains("musl"));
if !want_static && pkg_config::probe_library("libpcre2-8").is_ok() {
return;
}
// Set some config options. We mostly just use the default values. We do
// this in lieu of patching config.h since it's easier.
let mut builder = cc::Build::new();
builder
.define("PCRE2_CODE_UNIT_WIDTH", "8")
.define("HAVE_STDLIB_H", "1")
.define("HAVE_MEMMOVE", "1")
.define("HAVE_CONFIG_H", "1")
.define("PCRE2_STATIC", "1")
.define("STDC_HEADERS", "1")
.define("SUPPORT_PCRE2_8", "1")
.define("SUPPORT_UNICODE", "1");
if target.contains("windows") {
builder.define("HAVE_WINDOWS_H", "1");
}
enable_jit(&target, &mut builder);
builder.include(upstream.join("src")).include(upstream.join("include"));
for result in std::fs::read_dir(upstream.join("src")).unwrap() {
let dent = result.unwrap();
let path = dent.path();
if path.extension().map_or(true, |ext| ext != "c") {
continue;
}
// Apparently PCRE2 doesn't want to compile these directly, but only as
// included from pcre2_jit_compile.c.
//
// ... and also pcre2_ucptables.c, which is included by pcre2_tables.c.
// This is despite NON-AUTOTOOLS-BUILD instructions saying that
// pcre2_ucptables.c should be compiled directly.
if path.ends_with("pcre2_jit_match.c")
|| path.ends_with("pcre2_jit_misc.c")
|| path.ends_with("pcre2_ucptables.c")
{
continue;
}
builder.file(path);
}
if std::env::var("PCRE2_SYS_DEBUG").unwrap_or(String::new()) == "1"
|| std::env::var("DEBUG").unwrap_or(String::new()) == "1"
{
builder.debug(true);
}
builder.compile("libpcre2.a");
}
fn pcre2_sys_static() -> Option<bool> {
match std::env::var("PCRE2_SYS_STATIC") {
Err(_) => None,
Ok(s) => {
if s == "1" {
Some(true)
} else if s == "0" {
Some(false)
} else {
None
}
}
}
}
// On `aarch64-apple-ios` clang fails with the following error.
//
// Undefined symbols for architecture arm64:
// "___clear_cache", referenced from:
// _sljit_generate_code in libforeign.a(pcre2_jit_compile.o)
// ld: symbol(s) not found for architecture arm64
//
// aarch64-apple-tvos https://bugreports.qt.io/browse/QTBUG-62993?gerritReviewStatus=All
// aarch64-apple-darwin https://github.com/Homebrew/homebrew-core/pull/57419
// x86_64-apple-ios disabled for device–simulator consistency (not tested)
// x86_64-apple-tvos disabled for device–simulator consistency (not tested)
// armv7-apple-ios assumed equivalent to aarch64-apple-ios (not tested)
// armv7s-apple-ios assumed equivalent to aarch64-apple-ios (not tested)
// i386-apple-ios assumed equivalent to aarch64-apple-ios (not tested)
// x86_64-apple-ios-macabi disabled out of caution (not tested) (needs attention)
// aarch64-linux-android does not build
// armv7-linux-androideabi does not build
// aarch64-unknown-linux-musl does not build
// *-*-*-musleabi* does not build
//
// We may want to monitor developments on the `aarch64-apple-darwin` front as
// they may end up propagating to all `aarch64`-based targets and the `x86_64`
// equivalents.
fn enable_jit(target: &str, builder: &mut cc::Build) {
if target.starts_with("aarch64-apple") {
return;
}
if target == "aarch64-linux-android" {
return;
}
if target == "armv7-linux-androideabi" {
return;
}
if target == "aarch64-unknown-linux-musl" {
return;
}
if target.contains("musleabi") {
return;
}
if target.contains("apple-ios") || target.contains("apple-tvos") {
return;
}
builder.define("SUPPORT_JIT", "1");
}
|