File: build.rs

package info (click to toggle)
rust-pcre2-sys 0.2.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 172 kB
  • sloc: sh: 80; makefile: 4
file content (142 lines) | stat: -rw-r--r-- 5,475 bytes parent folder | download
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");
}