| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- use std::{
- env,
- path::PathBuf,
- process::{
- Command,
- Stdio,
- },
- };
- fn main() {
- let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
- let out_var = env::var("OUT_DIR").unwrap();
- // Download the Wormhole repository at a certain tag, which we need to access the protobuf definitions
- // for Wormhole P2P message types.
- //
- // TODO: This is ugly. Instead of this we should have our own tool
- // build process that can generate protobuf definitions for this and other user cases. For now
- // this is easy and works and matches upstream Wormhole's `Makefile`.
- const WORMHOLE_VERSION: &str = "2.18.1";
- let wh_curl = Command::new("curl")
- .args([
- "-s",
- "-L",
- format!("https://github.com/wormhole-foundation/wormhole/archive/refs/tags/v{WORMHOLE_VERSION}.tar.gz").as_str(),
- ])
- .stdout(Stdio::piped())
- .spawn()
- .expect("failed to download wormhole archive");
- let _ = Command::new("tar")
- .args(["xvz"])
- .stdin(Stdio::from(wh_curl.stdout.unwrap()))
- .output()
- .expect("failed to extract wormhole archive");
- // Move the tools directory to the root of the repo because that's where the build script
- // expects it to be, paths get hardcoded into the binaries.
- let _ = Command::new("mv")
- .args([
- format!("wormhole-{WORMHOLE_VERSION}/tools").as_str(),
- "tools",
- ])
- .output()
- .expect("failed to move wormhole tools directory");
- // Move the protobuf definitions to the src/network directory, we don't have to do this
- // but it is more intuitive when debugging.
- let _ = Command::new("mv")
- .args([
- format!("wormhole-{WORMHOLE_VERSION}/proto/gossip/v1/gossip.proto").as_str(),
- "src/network/p2p.proto",
- ])
- .output()
- .expect("failed to move wormhole protobuf definitions");
- // Build the protobuf compiler.
- let _ = Command::new("./build.sh")
- .current_dir("tools")
- .output()
- .expect("failed to run protobuf compiler build script");
- // Make the protobuf compiler executable.
- let _ = Command::new("chmod")
- .args(["+x", "tools/bin/*"])
- .output()
- .expect("failed to make protofuf compiler executable");
- // Generate the protobuf definitions. See buf.gen.yaml to see how we rename the module for our
- // particular use case.
- let _ = Command::new("./tools/bin/buf")
- .args(["generate", "--path", "src"])
- .output()
- .expect("failed to generate protobuf definitions");
- let rust_target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
- // Build the Go library.
- let mut cmd = Command::new("go");
- cmd.arg("build")
- .arg("-buildmode=c-archive")
- .arg("-o")
- .arg(out_dir.join("libpythnet.a"))
- .arg("src/network/p2p.go")
- .arg("src/network/p2p.pb.go");
- // Cross-compile the Go binary based on the Rust target architecture
- match &*rust_target_arch {
- "x86_64" => {
- // CGO_ENABLED required for building amd64 on mac os
- cmd.env("GOARCH", "amd64").env("CGO_ENABLED", "1");
- }
- "aarch64" => {
- cmd.env("GOARCH", "arm64");
- }
- // Add other target architectures as needed.
- _ => {}
- }
- // Tell Rust to link our Go library at compile time.
- println!("cargo:rustc-link-search=native={out_var}");
- println!("cargo:rustc-link-lib=static=pythnet");
- println!("cargo:rustc-link-lib=resolv");
- let go_build_output = cmd.output().expect("Failed to execute Go build command");
- if !go_build_output.status.success() {
- let error_message = String::from_utf8_lossy(&go_build_output.stderr);
- panic!("Go build failed:\n{}", error_message);
- }
- }
|