From 420d7f978810fb967c616365eb4eddd9f1502c9f Mon Sep 17 00:00:00 2001 From: core Date: Sat, 16 Dec 2023 11:53:06 -0500 Subject: [PATCH] update the windows buildscript to produce static nebula-ffi builds, massively increase nebula-ffi platform support --- .idea/dataSources.xml | 2 +- Cargo.lock | 6 +-- build_windows.sh | 4 +- nebula-ffi/Cargo.toml | 4 +- nebula-ffi/build.rs | 112 ++++++++++++++++++++++++------------------ 5 files changed, 72 insertions(+), 56 deletions(-) diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml index 7074b84..1fec8e5 100644 --- a/.idea/dataSources.xml +++ b/.idea/dataSources.xml @@ -1,7 +1,7 @@ - + postgresql true org.postgresql.Driver diff --git a/Cargo.lock b/Cargo.lock index 37a0d0d..79cdf22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -419,9 +419,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.68.1" +version = "0.69.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" dependencies = [ "bitflags 2.4.1", "cexpr", @@ -1833,7 +1833,7 @@ dependencies = [ [[package]] name = "nebula-ffi" -version = "1.7.2" +version = "1.7.3" dependencies = [ "bindgen", "cc", diff --git a/build_windows.sh b/build_windows.sh index 2aef7c0..3669150 100755 --- a/build_windows.sh +++ b/build_windows.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e -cargo build --target x86_64-pc-windows-gnu --release --bin tfclient +cargo build --target x86_64-pc-windows-gnu --profile release-ci --bin tfclient rm -rf target/x86_64-pc-windows-gnu/release-ci/tfclient_dist/ mkdir -p target/x86_64-pc-windows-gnu/release-ci/tfclient_dist/ cp target/x86_64-pc-windows-gnu/release-ci/tfclient.exe target/x86_64-pc-windows-gnu/release-ci/tfclient_dist/tfclient.exe @@ -9,8 +9,6 @@ mkdir -p target/x86_64-pc-windows-gnu/release-ci/tfclient_dist/dist/windows/ wget https://www.wintun.net/builds/wintun-0.14.1.zip -O /tmp/wintun.zip echo "[*] Unzipping WinTun" unzip -d target/x86_64-pc-windows-gnu/release-ci/tfclient_dist/dist/windows/ /tmp/wintun.zip -echo "[*] Copying nebula.dll" -cp target/x86_64-pc-windows-gnu/release-ci/nebula.dll target/x86_64-pc-windows-gnu/release-ci/tfclient_dist/nebula.dll echo "[*] Building zip bundle" cd target/x86_64-pc-windows-gnu/release-ci zip -r tfclient.zip tfclient_dist/* diff --git a/nebula-ffi/Cargo.toml b/nebula-ffi/Cargo.toml index 789274c..4b0767c 100644 --- a/nebula-ffi/Cargo.toml +++ b/nebula-ffi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula-ffi" -version = "1.7.2" +version = "1.7.3" edition = "2021" description = "A Rust wrapper crate for communicating with Nebula via a CGO FFI." license = "GPL-3.0-or-later" @@ -12,5 +12,5 @@ repository = "https://git.e3t.cc/~core/trifid" [build-dependencies] -bindgen = "0.68.1" +bindgen = "0.69" cc = "1" \ No newline at end of file diff --git a/nebula-ffi/build.rs b/nebula-ffi/build.rs index 4923ce3..84f4b7d 100644 --- a/nebula-ffi/build.rs +++ b/nebula-ffi/build.rs @@ -1,7 +1,7 @@ -use bindgen::CargoCallbacks; use std::path::Path; use std::path::PathBuf; use std::{env, process}; +use bindgen::CargoCallbacks; fn get_cargo_target_dir() -> Result> { let skip_triple = std::env::var("TARGET")? == std::env::var("HOST")?; @@ -35,28 +35,28 @@ fn main() { println!("using go compiler {}", compiler); - //gobuild::Build::new().compiler(compiler).buildmode(BuildMode::CArchive).file("main.go").compile("nebulaffi"); - let c_compiler = cc::Build::new().try_get_compiler().unwrap(); + let compile_config = get_compile_config(); + let out_dir = env::var("OUT_DIR").unwrap(); let out_path = PathBuf::from(out_dir); - let out_file = lib_name(); + let out_file = compile_config.lib_filename.clone(); let out = out_path.join(out_file); let mut command = process::Command::new(compiler); command.args([ "build", "-buildmode", - link_type().as_str(), + compile_config.link_type.as_str(), "-o", out.display().to_string().as_str(), "main.go", ]); command.env("CGO_ENABLED", "1"); command.env("CC", c_compiler.path()); - command.env("GOARCH", goarch()); - command.env("GOOS", goos()); + command.env("GOARCH", compile_config.goarch.clone()); + command.env("GOOS", compile_config.goos.clone()); println!("running go compile command: {:?}", command); let mut child = command.spawn().unwrap(); @@ -68,14 +68,19 @@ fn main() { } println!("Go compile success"); - copy_if_windows(); - print_link(); println!( - "cargo:rustc-link-search=native={}", + "cargo:rustc-link-search={}", env::var("OUT_DIR").unwrap() ); + if compile_config.link_type == "c-shared" { + copy_shared_lib(&compile_config); + println!("cargo:rustc-link-lib=dylib=nebula"); + } else { + println!("cargo:rustc-link-lib=static=nebula"); + } + //let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); //println!("cargo:rustc-link-search={}", out_path.display()); @@ -86,8 +91,8 @@ fn main() { println!("Generating bindings"); let bindings = bindgen::Builder::default() - .header(out_path.join(header_name()).display().to_string()) - .parse_callbacks(Box::new(CargoCallbacks)) + .header(out_path.join(compile_config.header_filename).display().to_string()) + .parse_callbacks(Box::new(CargoCallbacks::new())) .generate() .expect("Error generating CFFI bindings"); @@ -96,31 +101,60 @@ fn main() { .expect("Couldn't write bindings!"); } -fn lib_name() -> String { - if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "windows" { - "nebula.dll".to_string() - } else { - "libnebula.a".to_string() - } -} -fn header_name() -> String { - if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "windows" { - "nebula.h".to_string() - } else { - "libnebula.h".to_string() - } -} - -fn copy_if_windows() { +fn copy_shared_lib(go_compile_config: &GoCompileConfig) { let target_dir = get_cargo_target_dir().unwrap(); - let target_file = target_dir.join(lib_name()); + let target_file = target_dir.join(go_compile_config.lib_filename.clone()); let out_dir = env::var("OUT_DIR").unwrap(); let out_path = PathBuf::from(out_dir); - let out_file = lib_name(); + let out_file = go_compile_config.lib_filename.clone(); let out = out_path.join(out_file); std::fs::copy(out, target_file).unwrap(); } +// Go build supported modes. +// Pulled from golang/go/src/internal/platform/supported.go +// c-archive: +// aix, darwin, ios, windows +// linux/386, linux/amd64, linux/arm, linux/armbe, linux/arm64, linux/arm64be, linux/loong64, linux/ppc64le, linux/riscv64, linux/s390x +// freebsd/amd64 + +// c-shared: +// linux/amd64, linux/arm, linux/arm64, linux/loong64, linux/386, linux/ppc64le, linux/riscv64, linux/s390x +// android/amd64, android/arm, android/arm64, android/386 +// freebsd/amd64 +// darwin/amd64, darwin/arm64 +// windows/amd64, windows/386, windows/arm64 + +struct GoCompileConfig { + goarch: String, + goos: String, + link_type: String, + lib_filename: String, + header_filename: String +} + +fn get_compile_config() -> GoCompileConfig { + let goarch = goarch(); + let goos = goos(); + let platform_value = format!("{}/{}", goos, goarch); + let (preferred_link_type, lib_filename, header_filename) = match (goos.as_str(), goarch.as_str()) { + ("darwin", _) => ("c-archive", "libnebula.a", "libnebula.h"), + ("windows", _) => ("c-archive", "libnebula.a", "libnebula.h"), + ("linux", "386") | ("linux", "amd64") | ("linux", "arm") | ("linux", "armbe") | ("linux", "arm64") | ("linux", "arm64be") | ("linux", "loong64") | ("linux", "ppc64le") | ("linux", "riscv64") | ("linux", "s390x") => ("c-archive", "libnebula.a", "libnebula.h"), + ("freebsd", "amd64") => ("c-archive", "libnebula.a", "libnebula.h"), + _ => panic!("unsupported platform {} / {}", env::var("TARGET").unwrap(), platform_value) + }; + + GoCompileConfig { + goarch, + goos, + link_type: preferred_link_type.to_string(), + lib_filename: lib_filename.to_string(), + header_filename: header_filename.to_string() + } +} + + fn goarch() -> String { match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() { "x86" => "386", @@ -148,20 +182,4 @@ fn goos() -> String { os => panic!("unsupported operating system {os}"), } .to_string() -} - -fn print_link() { - if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "windows" { - println!("cargo:rustc-link-lib=dylib=nebula"); - } else { - println!("cargo:rustc-link-lib=static=nebula"); - } -} - -fn link_type() -> String { - if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "windows" { - "c-shared".to_string() - } else { - "c-archive".to_string() - } -} +} \ No newline at end of file