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
// Copyright 2019-2025 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT
use std::io::Write;
fn main() {
// Only needed when profiling Forest with `gperftools`. This might not work on all platforms.
if is_env_truthy("FOREST_PROFILING_GPERFTOOLS_BUILD") {
println!("cargo:rustc-link-lib=tcmalloc");
}
// whitelist the cfg for cargo clippy
println!("cargo::rustc-check-cfg=cfg(f3sidecar)");
// Do not build f3-sidecar on docs.rs publishing
// No proper version of Go compiler is available.
if !is_docs_rs() && !is_env_truthy("FOREST_F3_SIDECAR_FFI_BUILD_OPT_OUT") {
println!("cargo:rustc-cfg=f3sidecar");
println!("cargo::rerun-if-changed=f3-sidecar");
unsafe {
std::env::set_var("GOWORK", "off");
// `Netgo` is enabled for all the platforms to be consistent across different builds. It
// is using pure Go implementation for functionality like name resolution. In the case of
// sidecar it does not make much difference, but it does fix the Apple silicons builds.
// See <https://github.com/status-im/status-mobile/issues/20135#issuecomment-2137400475>
std::env::set_var("GOFLAGS", "-tags=netgo");
}
rust2go::Builder::default()
.with_go_src("./f3-sidecar")
// the generated Go file has been commited to the git repository,
// uncomment to regenerate the code locally
// .with_regen_arg(rust2go::RegenArgs {
// src: "./src/f3/go_ffi.rs".into(),
// dst: "./f3-sidecar/ffi_gen.go".into(),
// without_main: true,
// ..Default::default()
// })
.build();
}
rpc_regression_tests_gen();
}
// See <https://docs.rs/about/builds#detecting-docsrs>
fn is_docs_rs() -> bool {
std::env::var("DOCS_RS").is_ok()
}
fn is_env_truthy(env: &str) -> bool {
std::env::var(env)
.ok()
.map(|var| matches!(var.to_lowercase().as_str(), "1" | "true" | "yes" | "_yes_"))
.unwrap_or_default()
}
fn rpc_regression_tests_gen() {
use std::{fs::File, io::BufWriter, path::PathBuf};
println!("cargo:rerun-if-changed=src/tool/subcommands/api_cmd/test_snapshots.txt");
let tests: Vec<&str> = include_str!("src/tool/subcommands/api_cmd/test_snapshots.txt")
.lines()
.map(str::trim)
.filter(|l| !l.is_empty() && !l.starts_with('#'))
.collect();
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let out_path = out_dir.join("__rpc_regression_tests_gen.rs");
let mut w = BufWriter::new(File::create(&out_path).unwrap());
for test in tests {
// Derive a valid Rust identifier from the snapshot filename.
let ident = test
.strip_suffix(".rpcsnap.json.zst")
.unwrap_or(test)
.chars()
.map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
.collect::<String>();
writeln!(
w,
r#"
#[tokio::test(flavor = "multi_thread")]
async fn rpc_snapshot_test_{ident}() {{
rpc_regression_test_run("{test}").await
}}
"#,
)
.unwrap();
}
}