2023-06-26 02:00:36 +00:00
|
|
|
use bindgen::CargoCallbacks;
|
2023-06-27 03:17:49 +00:00
|
|
|
use std::path::Path;
|
2023-11-23 20:23:52 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::{env, process};
|
2023-06-26 02:00:36 +00:00
|
|
|
|
2023-10-10 13:21:37 +00:00
|
|
|
fn get_cargo_target_dir() -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
|
2023-12-16 03:59:20 +00:00
|
|
|
let skip_triple = std::env::var("TARGET")? == std::env::var("HOST")?;
|
|
|
|
let skip_parent_dirs = if skip_triple { 4 } else { 5 };
|
|
|
|
|
2023-10-10 13:21:37 +00:00
|
|
|
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR")?);
|
2023-12-16 03:59:20 +00:00
|
|
|
let mut current = out_dir.as_path();
|
|
|
|
for _ in 0..skip_parent_dirs {
|
|
|
|
current = current.parent().ok_or("not found")?;
|
2023-10-10 13:21:37 +00:00
|
|
|
}
|
2023-12-16 03:59:20 +00:00
|
|
|
|
|
|
|
Ok(std::path::PathBuf::from(current))
|
2023-10-10 13:21:37 +00:00
|
|
|
}
|
|
|
|
|
2023-06-26 02:00:36 +00:00
|
|
|
fn main() {
|
2023-10-09 19:06:02 +00:00
|
|
|
// 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()
|
|
|
|
}
|
|
|
|
}
|
2023-09-25 00:20:14 +00:00
|
|
|
};
|
2023-06-27 03:17:49 +00:00
|
|
|
|
2023-10-09 19:06:02 +00:00
|
|
|
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);
|
2023-10-10 13:21:37 +00:00
|
|
|
let out_file = lib_name();
|
2023-10-09 19:06:02 +00:00
|
|
|
let out = out_path.join(out_file);
|
|
|
|
|
|
|
|
let mut command = process::Command::new(compiler);
|
2023-11-23 20:23:52 +00:00
|
|
|
command.args([
|
|
|
|
"build",
|
|
|
|
"-buildmode",
|
|
|
|
link_type().as_str(),
|
|
|
|
"-o",
|
|
|
|
out.display().to_string().as_str(),
|
|
|
|
"main.go",
|
|
|
|
]);
|
2023-10-09 19:06:02 +00:00
|
|
|
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);
|
|
|
|
}
|
2023-07-12 14:32:19 +00:00
|
|
|
|
|
|
|
println!("Go compile success");
|
2023-10-10 13:21:37 +00:00
|
|
|
copy_if_windows();
|
2023-06-26 02:00:36 +00:00
|
|
|
|
2023-10-10 00:12:44 +00:00
|
|
|
print_link();
|
2023-11-23 20:23:52 +00:00
|
|
|
println!(
|
|
|
|
"cargo:rustc-link-search=native={}",
|
|
|
|
env::var("OUT_DIR").unwrap()
|
|
|
|
);
|
2023-10-09 19:06:02 +00:00
|
|
|
|
|
|
|
//let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
2023-06-26 02:00:36 +00:00
|
|
|
|
2023-10-09 19:06:02 +00:00
|
|
|
//println!("cargo:rustc-link-search={}", out_path.display());
|
2023-06-26 02:00:36 +00:00
|
|
|
println!("cargo:rerun-if-changed=go.mod");
|
|
|
|
println!("cargo:rerun-if-changed=go.sum");
|
|
|
|
println!("cargo:rerun-if-changed=main.go");
|
|
|
|
|
2023-07-12 14:32:19 +00:00
|
|
|
println!("Generating bindings");
|
|
|
|
|
2023-06-26 02:00:36 +00:00
|
|
|
let bindings = bindgen::Builder::default()
|
2023-10-10 13:21:37 +00:00
|
|
|
.header(out_path.join(header_name()).display().to_string())
|
2023-06-26 02:00:36 +00:00
|
|
|
.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!");
|
2023-07-12 14:32:19 +00:00
|
|
|
}
|
2023-10-09 19:06:02 +00:00
|
|
|
|
2023-10-10 13:21:37 +00:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
2023-10-09 19:06:02 +00:00
|
|
|
|
2023-10-10 13:21:37 +00:00
|
|
|
fn copy_if_windows() {
|
|
|
|
let target_dir = get_cargo_target_dir().unwrap();
|
|
|
|
let target_file = target_dir.join(lib_name());
|
|
|
|
let out_dir = env::var("OUT_DIR").unwrap();
|
|
|
|
let out_path = PathBuf::from(out_dir);
|
|
|
|
let out_file = lib_name();
|
|
|
|
let out = out_path.join(out_file);
|
|
|
|
std::fs::copy(out, target_file).unwrap();
|
|
|
|
}
|
2023-10-09 19:06:02 +00:00
|
|
|
|
|
|
|
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",
|
2023-11-23 20:23:52 +00:00
|
|
|
arch => panic!("unsupported architecture {arch}"),
|
|
|
|
}
|
|
|
|
.to_string()
|
2023-10-09 19:06:02 +00:00
|
|
|
}
|
|
|
|
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",
|
2023-11-23 20:23:52 +00:00
|
|
|
os => panic!("unsupported operating system {os}"),
|
|
|
|
}
|
|
|
|
.to_string()
|
2023-10-10 00:12:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn print_link() {
|
2023-10-10 13:21:37 +00:00
|
|
|
if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "windows" {
|
|
|
|
println!("cargo:rustc-link-lib=dylib=nebula");
|
|
|
|
} else {
|
|
|
|
println!("cargo:rustc-link-lib=static=nebula");
|
|
|
|
}
|
2023-10-10 00:12:44 +00:00
|
|
|
}
|
2023-10-10 13:21:37 +00:00
|
|
|
|
2023-10-10 00:12:44 +00:00
|
|
|
fn link_type() -> String {
|
2023-10-10 13:21:37 +00:00
|
|
|
if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "windows" {
|
|
|
|
"c-shared".to_string()
|
|
|
|
} else {
|
|
|
|
"c-archive".to_string()
|
|
|
|
}
|
2023-11-23 20:23:52 +00:00
|
|
|
}
|