Files
grim/build.rs
T
2ro 6621dc6aaa Build 54: Windows single-file + silent, logged sidecar
Address Windows feedback (visible console window; no diagnostics when the
mixnet stalled):
- Hide the sidecar console: spawn nym-socks5-client.exe with CREATE_NO_WINDOW
  so launching it no longer flashes a terminal.
- All-in-one: embed the Windows sidecar into goblin.exe (build.rs, gated on
  GOBLIN_NYM_WIN_BIN) and extract it to %LOCALAPPDATA%\Goblin at first run, so
  the release is a single self-contained .exe with no loose helper to misplace.
- Log the sidecar to ~/.goblin/nym-sidecar.log (all platforms) instead of a
  null sink, so a stalled bootstrap is diagnosable.

Verified under wine: goblin.exe extracts the embedded sidecar, launches it,
and it opens the SOCKS5 proxy on 127.0.0.1:1080.
2026-06-13 20:30:33 -04:00

81 lines
2.8 KiB
Rust

use std::env;
use std::path::PathBuf;
use std::process::Command;
/// The GRIM commit Goblin forked from; builds count commits on top of it.
const GOBLIN_FORK_BASE: &str = "b51a46b";
fn main() {
built::write_built_file().expect("Failed to acquire build-time information");
// Goblin versioning is build-based: Build N = commits since the fork.
// An explicit GOBLIN_BUILD env wins (CI builds from the public single-commit
// squash where the fork base isn't an ancestor, so the git count can't run);
// otherwise count commits since the fork; "dev" only as a last resort.
let build = env::var("GOBLIN_BUILD")
.ok()
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.or_else(|| {
Command::new("git")
.args([
"rev-list",
"--count",
&format!("{}..HEAD", GOBLIN_FORK_BASE),
])
.output()
.ok()
.filter(|o| o.status.success())
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
})
.unwrap_or_else(|| "dev".to_string());
println!("cargo:rustc-env=GOBLIN_BUILD={}", build);
// .git/HEAD only changes on branch switches; the reflog is appended on
// every commit, so the build number stays current.
println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=.git/logs/HEAD");
println!("cargo:rerun-if-env-changed=GOBLIN_BUILD");
// Setting up git hooks in the project: rustfmt and so on.
let git_hooks = format!(
"git config core.hooksPath {}",
PathBuf::from("./.hooks").to_str().unwrap()
);
if cfg!(target_os = "windows") {
Command::new("cmd")
.args(&["/C", &git_hooks])
.output()
.expect("failed to execute git config for hooks");
} else {
Command::new("sh")
.args(&["-c", &git_hooks])
.output()
.expect("failed to execute git config for hooks");
}
// Goblin routes all traffic over the Nym mixnet via a bundled
// `nym-socks5-client` sidecar (see src/nym/); there is no embedded Tor and
// thus no webtunnel pluggable-transport binary to build here anymore.
// Single-file Windows: when GOBLIN_NYM_WIN_BIN points at the Windows
// nym-socks5-client.exe, embed it into goblin.exe. At startup the app
// extracts it to %LOCALAPPDATA%\Goblin and runs it hidden (src/nym/sidecar.rs),
// so the release ships as one self-contained .exe with no loose sidecar file.
println!("cargo:rerun-if-env-changed=GOBLIN_NYM_WIN_BIN");
println!("cargo:rustc-check-cfg=cfg(goblin_embed_nym)");
if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("windows") {
if let Ok(src) = env::var("GOBLIN_NYM_WIN_BIN") {
if !src.is_empty() {
let out = PathBuf::from(env::var("OUT_DIR").unwrap()).join("nym-socks5-client.exe");
std::fs::copy(&src, &out)
.expect("copy GOBLIN_NYM_WIN_BIN into OUT_DIR for embedding");
println!("cargo:rustc-cfg=goblin_embed_nym");
println!("cargo:rerun-if-changed={}", src);
}
}
}
}