use std::env;
use std::path::Path;
use std::process::Command;
fn main() {
let target = env::var("TARGET").unwrap();
let current_dir = env::current_dir().unwrap();
let out_dir = env::var("OUT_DIR").unwrap();
let env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap();
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
println!("target: {}", target);
println!("current_dir: {}", current_dir.to_string_lossy());
println!("out_dir: {}", out_dir);
println!("env: {}", out_dir);
println!("target_family: {}", target_family);
run_cbindgen();
run_qmake(
¤t_dir.join("src/platform/qt/qt_wrapper/cpp"),
&out_dir,
);
run_make(&env, &out_dir);
cargo_link_static(&out_dir, "qt_wrapper");
cargo_link_qt(&env, &target_family);
generate_bindings("src/platform/qt/qt_wrapper/cpp/qt_wrapper.h", &out_dir);
}
fn run_cbindgen() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let out_dir = env::var("OUT_DIR").unwrap();
cbindgen::Builder::new()
.with_crate(crate_dir)
.generate()
.expect("Unable to generate bindings")
.write_to_file(&Path::new(&out_dir).join("rust_ffi.h"));
}
fn run_qmake(src_dir: &Path, out_dir: &str) {
let output = Command::new("qmake")
.args(&[src_dir])
.current_dir(&Path::new(&out_dir))
.output()
.expect("failed to execute 'qmake' process");
println!("qmake.status: {}", output.status);
println!("qmake.stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("qmake.stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success(), "failed to execute qmake process");
}
fn run_make(env: &str, dir: &str) {
let output = if env == "msvc" {
Command::new("nmake")
.current_dir(&Path::new(&dir))
.output()
.expect("failed to execute 'make' process")
} else {
Command::new("make")
.args(&["-j16"])
.current_dir(&Path::new(&dir))
.output()
.expect("failed to execute 'make' process")
};
println!("make.status: {}", output.status);
println!("make.stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("make.stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success(), "failed to execute make process");
}
fn cargo_link_static(dir: &str, lib: &str) {
println!("cargo:rustc-link-search={}", dir);
println!("cargo:rustc-link-lib={}", lib);
}
fn qmake_query(var: &str) -> String {
String::from_utf8(
Command::new("qmake")
.args(&["-query", var])
.output()
.expect("Failed to execute qmake. Make sure 'qmake' is in your path")
.stdout,
)
.expect("UTF-8 conversion failed")
}
fn cargo_link_qt(env: &str, target_family: &str) {
let qt_library_path = qmake_query("QT_INSTALL_LIBS");
println!("cargo:rustc-link-search={}", qt_library_path);
println!("cargo:rustc-link-lib={}", "Qt5Widgets");
println!("cargo:rustc-link-lib={}", "Qt5Gui");
println!("cargo:rustc-link-lib={}", "Qt5Core");
if target_family == "unix" {
println!("cargo:rustc-link-lib={}", "KF5WindowSystem");
}
if env != "msvc" {
println!("cargo:rustc-link-lib=stdc++");
}
}
fn generate_bindings(src: &str, out_dir: &str) {
let bindings = bindgen::Builder::default()
.header(src)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(&Path::new(out_dir).join("bindings.rs"))
.expect("Couldn't write bindings!");
}