use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;
use std::process::Command;
fn qmake_query(var: &str) -> Result<String, std::io::Error> {
let qmake = std::env::var("QMAKE").unwrap_or("qmake".to_string());
Ok(String::from_utf8(
Command::new(qmake).env("QT_SELECT", "qt5").args(&["-query", var]).output()?.stdout,
)
.expect("UTF-8 conversion failed"))
}
fn detect_qreal_size(qt_include_path: &str, qt_library_path: &str) {
let mut path = Path::new(qt_include_path).join("QtCore/qconfig.h");
if cfg!(target_os = "macos") {
if !path.exists() {
path = Path::new(qt_library_path).join("QtCore.framework/Headers/qconfig.h");
}
}
let f = std::fs::File::open(&path).expect(&format!("Cannot open `{:?}`", path));
let b = BufReader::new(f);
for line in b.lines() {
let line = line.expect("qconfig.h is valid UTF-8");
if line.contains("QT_COORD_TYPE") {
if line.contains("float") {
println!("cargo:rustc-cfg=qreal_is_float");
return;
} else {
panic!("QT_COORD_TYPE with unknown declaration {}", line);
}
}
}
}
fn main() {
let qt_version = match qmake_query("QT_VERSION") {
Ok(v) => v,
Err(_err) => {
#[cfg(feature = "required")]
panic!(
"Error: Failed to execute qmake. Make sure 'qmake' is in your path!\n{:?}",
_err
);
#[cfg(not(feature = "required"))]
{
println!("cargo:rustc-cfg=no_qt");
println!("cargo:FOUND=0");
return;
}
}
};
let qt_include_path = qmake_query("QT_INSTALL_HEADERS").unwrap();
let qt_library_path = qmake_query("QT_INSTALL_LIBS").unwrap();
let mut config = cpp_build::Config::new();
if cfg!(target_os = "macos") {
config.flag("-F");
config.flag(qt_library_path.trim());
}
detect_qreal_size(&qt_include_path.trim(), qt_library_path.trim());
config.include(qt_include_path.trim()).build("src/lib.rs");
println!("cargo:VERSION={}", qt_version.trim());
println!("cargo:LIBRARY_PATH={}", qt_library_path.trim());
println!("cargo:INCLUDE_PATH={}", qt_include_path.trim());
println!("cargo:FOUND=1");
let macos_lib_search = if cfg!(target_os = "macos") { "=framework" } else { "" };
let macos_lib_framework = if cfg!(target_os = "macos") { "" } else { "5" };
let debug = std::env::var("DEBUG").ok().map_or(false, |s| s == "true");
let windows_dbg_suffix = if debug && cfg!(target_os = "windows") {
println!("cargo:rustc-link-lib=msvcrtd");
"d"
} else {
""
};
if cfg!(target_os = "macos") {
println!("cargo:rustc-cdylib-link-arg=-Wl,-rpath,{}", qt_library_path.trim());
}
println!("cargo:rustc-link-search{}={}", macos_lib_search, qt_library_path.trim());
let link_lib = |lib: &str| {
println!(
"cargo:rustc-link-lib{search}=Qt{vers}{lib}{suffix}",
search = macos_lib_search,
vers = macos_lib_framework,
lib = lib,
suffix = windows_dbg_suffix
)
};
link_lib("Core");
link_lib("Gui");
link_lib("Widgets");
#[cfg(feature = "qtquick")]
link_lib("Quick");
#[cfg(feature = "qtquick")]
link_lib("Qml");
#[cfg(feature = "qtwebengine")]
link_lib("WebEngine");
println!("cargo:rerun-if-changed=src/lib.rs");
}