use std::env;
use std::path::PathBuf;
const C_SOURCES: &[&str] = &[
"main.c", "iniparse.c", "log.c",
"application.c", "button.c", "checkbox.c", "combobox.c", "entry.c",
"label.c", "menu.c", "progressbar.c", "radiobutton.c", "statusbar.c",
"textlist.c", "textview.c", "theme.c", "widget.c", "window.c", "image.c",
"spinner.c", "scale.c", "spinbutton.c", "switch.c", "frame.c",
"separator.c", "expander.c", "box.c",
"editor.c", "editor_lang.c", "editor_autoc.c", "editor_view.c",
"editor_json.c", "editor_tm.c", "editor_search.c", "editor_ops.c",
"json.c", "sparkline.c", "gauge.c", "barchart.c", "tree.c", "table.c",
"map.c", "tabs.c", "mindmap.c", "segdisplay.c", "linechart.c", "hexview.c",
"calendar.c", "dialog.c", "filechooser.c", "custom.c", "colordialog.c",
"piechart.c", "scatter.c", "widget_send_key.c",
];
fn main() {
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
println!("cargo:rerun-if-changed=wrapper.h");
println!("cargo:rerun-if-changed=build.rs");
if env::var("DOCS_RS").is_ok() {
std::fs::copy(
manifest_dir.join("docsrs-bindings.rs"),
out_path.join("bindings.rs"),
)
.expect("copy docsrs-bindings.rs (regenerate it after an API change)");
return;
}
let vendor = manifest_dir.join("vendor");
let src_root = if vendor.join("src").exists() {
vendor.join("src")
} else {
manifest_dir
.join("../../../..")
.canonicalize()
.expect("cannot resolve repo root")
.join("src")
};
let include_dir = src_root.join("include");
let caca = pkg_config::Config::new()
.probe("caca")
.expect("libcaca not found via pkg-config. Install it: \
`apt install libcaca-dev`, `dnf install libcaca-devel`, \
or `brew install libcaca`.");
let mut build = cc::Build::new();
build
.include(&include_dir)
.std("gnu99") .warnings(false);
for inc in &caca.include_paths {
build.include(inc);
}
for src in C_SOURCES {
build.file(src_root.join(src));
}
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
match target_os.as_str() {
"macos" => { build.define("MACOS", "1"); }
"linux" => { build.define("LINUX", "1"); }
"windows" => { build.define("WIN32", "1"); }
_ => {}
}
if env::var("CARGO_CFG_TARGET_ENDIAN").as_deref() == Ok("big") {
build.define("HAVE_LITTLE_ENDIAN", "0").define("HAVE_BIG_ENDIAN", "1");
} else {
build.define("HAVE_LITTLE_ENDIAN", "1").define("HAVE_BIG_ENDIAN", "0");
}
build.define("GTCACA_DATA_DIR", "\"/usr/local/share/gtcaca/\"");
build.compile("gtcaca");
if target_os == "linux" {
println!("cargo:rustc-link-lib=pthread");
println!("cargo:rustc-link-lib=m");
}
let mut bindgen_builder = bindgen::Builder::default()
.header("wrapper.h")
.clang_arg(format!("-I{}", include_dir.display()))
.layout_tests(false)
.allowlist_function("gtcaca_.*")
.allowlist_function("caca_get_event.*")
.allowlist_type("gtcaca_.*")
.allowlist_type("_?g(mo|tcaca)_.*")
.allowlist_type("caca_event.*")
.allowlist_var("GTCACA_.*")
.allowlist_var("CACA_.*")
.allowlist_var("gmo")
.blocklist_type("FILE")
.blocklist_type("__sFILE.*")
.blocklist_type("_IO_FILE.*")
.blocklist_type("fpos_t")
.blocklist_type("_G_fpos_t")
.blocklist_type("__darwin.*")
.blocklist_type("__int64_t")
.raw_line("pub type FILE = ::std::os::raw::c_void;")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()));
for inc in &caca.include_paths {
bindgen_builder = bindgen_builder.clang_arg(format!("-I{}", inc.display()));
}
let bindings = bindgen_builder.generate().expect("bindgen failed");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("failed to write bindings.rs");
println!("cargo:include={}", include_dir.display());
}