112 lines
3.4 KiB
Rust
112 lines
3.4 KiB
Rust
use std::{env, process};
|
|
use std::path::PathBuf;
|
|
use bindgen::CargoCallbacks;
|
|
use std::path::Path;
|
|
|
|
fn main() {
|
|
|
|
// Find compiler:
|
|
// 1. GOC
|
|
// 2. /usr/local/go/bin/go
|
|
// 3. system "go"
|
|
|
|
let compiler = match env::var("GOC") {
|
|
Ok(c) => c,
|
|
Err(_) => {
|
|
if Path::new("/usr/local/go/bin/go").exists() {
|
|
"/usr/local/go/bin/go".to_string()
|
|
} else {
|
|
"go".to_string()
|
|
}
|
|
}
|
|
};
|
|
|
|
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 out_dir = env::var("OUT_DIR").unwrap();
|
|
let out_path = PathBuf::from(out_dir);
|
|
let out_file = LIBRARY_PREFIX.to_owned() + "nebula" + LIBRARY_EXTENSION;
|
|
let out = out_path.join(out_file);
|
|
|
|
let mut command = process::Command::new(compiler);
|
|
command.args(["build", "-buildmode", "c-archive", "-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());
|
|
println!("running go compile command: {:?}", command);
|
|
|
|
let mut child = command.spawn().unwrap();
|
|
let status = child.wait().unwrap();
|
|
println!("{}", status);
|
|
|
|
if !status.success() {
|
|
panic!("`{:?}` exited with status code {}", command, status);
|
|
}
|
|
|
|
println!("Go compile success");
|
|
|
|
println!("cargo:rustc-link-lib=static=nebula");
|
|
println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap());
|
|
|
|
//let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
|
|
//println!("cargo:rustc-link-search={}", out_path.display());
|
|
println!("cargo:rerun-if-changed=go.mod");
|
|
println!("cargo:rerun-if-changed=go.sum");
|
|
println!("cargo:rerun-if-changed=main.go");
|
|
|
|
println!("Generating bindings");
|
|
|
|
let bindings = bindgen::Builder::default()
|
|
.header(out_path.join("libnebula.h").display().to_string())
|
|
.parse_callbacks(Box::new(CargoCallbacks))
|
|
.generate()
|
|
.expect("Error generating CFFI bindings");
|
|
|
|
|
|
bindings
|
|
.write_to_file(out_path.join("bindings.rs"))
|
|
.expect("Couldn't write bindings!");
|
|
}
|
|
|
|
#[cfg(target_family = "unix")]
|
|
const LIBRARY_EXTENSION: & str = ".a";
|
|
#[cfg(target_family = "unix")]
|
|
const LIBRARY_PREFIX: & str = "lib";
|
|
|
|
#[cfg(target_family = "windows")]
|
|
const LIBRARY_EXTENSION: &str = ".lib";
|
|
#[cfg(target_family = "windows")]
|
|
const LIBRARY_PREFIX: &str = "";
|
|
|
|
fn goarch() -> String {
|
|
match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
|
|
"x86" => "386",
|
|
"x86_64" => "amd64",
|
|
"mips" => "mips",
|
|
"powerpc" => "ppc",
|
|
"powerpc64" => "ppc64",
|
|
"arm" => "arm",
|
|
"aarch64" => "arm64",
|
|
arch => panic!("unsupported architecture {arch}")
|
|
}.to_string()
|
|
}
|
|
fn goos() -> String {
|
|
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
|
|
"windows" => "windows",
|
|
"macos" => "darwin",
|
|
"ios" => "darwin",
|
|
"linux" => "linux",
|
|
"android" => "android",
|
|
"freebsd" => "freebsd",
|
|
"dragonfly" => "dragonfly",
|
|
"openbsd" => "openbsd",
|
|
"netbsd" => "netbsd",
|
|
os => panic!("unsupported operating system {os}")
|
|
}.to_string()
|
|
} |