summaryrefslogtreecommitdiff
path: root/impls/monero.rs/build.rs
blob: 19a43941147860e4d0479bec3137515a017aaee7 (plain)
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
use std::env;
use std::fs::{self, OpenOptions};
use std::io::Write;
use std::path::PathBuf;
use bindgen::EnumVariation;

#[cfg(unix)]
use std::os::unix::fs as unix_fs;

#[cfg(target_os = "windows")]
use std::fs::copy;

fn main() {
    let header_path = "../../monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.h";
    let lib_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("../../release");

    // Set library names based on target OS.
    //
    // This rigamarole is currently required because the "monero_libwallet2_api_c" library is also
    // required under the names "wallet2_api_c" and "libmonero_libwallet2_api_c" by various parts of
    // the stack.  This is a temporary workaround until the library is refactored to use a single
    // name consistently.
    let original_lib = if cfg!(target_os = "windows") {
        lib_path.join("monero_libwallet2_api_c.dll")
    } else if cfg!(target_os = "macos") {
        lib_path.join("monero_libwallet2_api_c.dylib")
    } else {
        lib_path.join("monero_libwallet2_api_c.so")
    };

    let symlink_1 = if cfg!(target_os = "windows") {
        lib_path.join("wallet2_api_c.dll")
    } else if cfg!(target_os = "macos") {
        lib_path.join("libwallet2_api_c.dylib")
    } else {
        lib_path.join("libwallet2_api_c.so")
    };

    let symlink_2 = if cfg!(target_os = "windows") {
        lib_path.join("monero_wallet2_api_c.dll")
    } else if cfg!(target_os = "macos") {
        lib_path.join("libmonero_libwallet2_api_c.dylib")
    } else {
        lib_path.join("libmonero_libwallet2_api_c.so")
    };

    // On Unix-like systems, create symlinks.
    #[cfg(unix)]
    {
        if original_lib.exists() && !symlink_1.exists() {
            unix_fs::symlink(&original_lib, &symlink_1)
                .expect("Failed to create symbolic link for libwallet2_api_c.so");
        }

        if original_lib.exists() && !symlink_2.exists() {
            unix_fs::symlink(&original_lib, &symlink_2)
                .expect("Failed to create symbolic link for libmonero_libwallet2_api_c.so");
        }
    }

    // On Windows, copy the files instead of symlinking.
    #[cfg(target_os = "windows")]
    {
        if original_lib.exists() && !symlink_1.exists() {
            copy(&original_lib, &symlink_1).expect("Failed to copy DLL file to wallet2_api_c.dll");
        }

        if original_lib.exists() && !symlink_2.exists() {
            copy(&original_lib, &symlink_2)
                .expect("Failed to copy DLL file to monero_wallet2_api_c.dll");
        }
    }

    println!("cargo:rerun-if-changed={}", header_path);
    println!("cargo:rerun-if-changed=build.rs");

    println!("cargo:rustc-link-search=native={}", lib_path.display());
    println!("cargo:rustc-link-lib=dylib=monero_libwallet2_api_c");
    println!("cargo:rustc-link-lib=dylib=stdc++");
    println!("cargo:rustc-link-lib=dylib=hidapi-hidraw");
    println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib_path.display());

    // Generate bindings using bindgen.
    let bindings = bindgen::Builder::default()
        .header(header_path)
        .allowlist_function("MONERO_.*")
        .allowlist_var("MONERO_.*")
        .allowlist_var("NetworkType_.*")
        .allowlist_var("PendingTransactionStatus_.*")
        .allowlist_var("Priority_.*")
        .allowlist_var("UnsignedTransactionStatus_.*")
        .allowlist_var("TransactionInfoDirection_.*")
        .allowlist_var("AddressBookErrorCode.*")
        .allowlist_var("WalletDevice_.*")
        .allowlist_var("WalletStatus_.*")
        .allowlist_var("WalletConnectionStatus_.*")
        .allowlist_var("WalletBackgroundSync_.*")
        .allowlist_var("BackgroundSync_.*")
        .allowlist_var("LogLevel_.*")
        .blocklist_type("__.*")
        .blocklist_type("_.*")
        .blocklist_function("__.*")
        .layout_tests(false)
        .default_enum_style(EnumVariation::Rust { non_exhaustive: false })
        .derive_default(false)
        .conservative_inline_namespaces()
        .generate_comments(false)
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
        .join("src")
        .join("bindings.rs");
    bindings
        .write_to_file(out_path.clone())
        .expect("Couldn't write bindings!");
}