use std::path::{Path, PathBuf};
use std::{env, fs};
include!("shim_compiler.rs");
const LIB_DIRS: &[&str] = &[
"/root/Bela/lib",
"/usr/evl/lib/aarch64-linux-gnu",
"/usr/local/lib",
"/usr/lib/aarch64-linux-gnu",
];
const LIBS: &[&str] = &["belaextra", "bela", "asound", "seasocks", "evl", "stdc++"];
const SHIM_SOURCES: &[&str] = &["shim/midi.cpp", "shim/midi.h"];
const SHIM_INCLUDE_DIRS: &[&str] = &["/root/Bela/include", "/root/Bela"];
const AR_ENV: &[&str] = &[
"AR_aarch64-unknown-linux-gnu",
"AR_aarch64_unknown_linux_gnu",
"TARGET_AR",
"AR",
];
const SHIM_PROBE: &str = "/root/Bela/libraries/Midi/Midi.h";
fn main() {
println!("cargo::rerun-if-changed=build.rs");
for source in SHIM_SOURCES {
println!("cargo::rerun-if-changed={source}");
}
println!("cargo::rerun-if-env-changed=BELA_SYSROOT");
println!("cargo::rerun-if-env-changed=BELA_CXX");
for name in AR_ENV {
println!("cargo::rerun-if-env-changed={name}");
}
println!("cargo::rerun-if-env-changed=BELA_CC");
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
let os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
if !(arch == "aarch64" && os == "linux") {
return;
}
let sysroot = env::var("BELA_SYSROOT").unwrap_or_default();
for dir in LIB_DIRS {
println!("cargo::rustc-link-search=native={sysroot}{dir}");
}
if let Some(dir) = gcc_lib_dir(&sysroot) {
println!("cargo::rustc-link-search=native={}", dir.display());
}
build_shim(&sysroot);
for lib in LIBS {
println!("cargo::rustc-link-lib=dylib={lib}");
}
}
#[allow(
clippy::panic,
reason = "a build script reports a misconfiguration by failing the build"
)]
fn build_shim(sysroot: &str) {
let probe = format!("{sysroot}{SHIM_PROBE}");
println!("cargo::rerun-if-changed={probe}");
if !Path::new(&probe).exists() {
let where_ = if sysroot.is_empty() {
"BELA_SYSROOT is unset and this is not a board".to_owned()
} else {
format!("{sysroot}{SHIM_PROBE} is missing")
};
println!(
"cargo::warning=MIDI shim not compiled ({where_}); \
linking a device binary will fail on bela_midi_* until \
scripts/sync-sysroot.sh has run"
);
return;
}
let compiler = match shim_compiler_from(
&env::var("BELA_CXX").unwrap_or_default(),
&env::var("BELA_CC").unwrap_or_default(),
) {
Ok(compiler) => compiler,
Err(message) => panic!("{message}"),
};
let mut build = cc::Build::new();
build
.cpp(true)
.std("c++14")
.file("shim/midi.cpp")
.compiler(&compiler);
if !AR_ENV.iter().any(|name| env::var_os(name).is_some()) {
if let Some(archiver) = shim_archiver(&compiler) {
build.archiver(archiver);
}
}
for dir in SHIM_INCLUDE_DIRS {
build.include(format!("{sysroot}{dir}"));
}
if !sysroot.is_empty() {
build.flag(format!("--sysroot={sysroot}"));
build.include(format!("{sysroot}/usr/include/aarch64-linux-gnu"));
}
build.compile("bela_midi_shim");
}
fn gcc_lib_dir(sysroot: &str) -> Option<PathBuf> {
let base = PathBuf::from(format!("{sysroot}/usr/lib/gcc/aarch64-linux-gnu"));
fs::read_dir(base)
.ok()?
.filter_map(Result::ok)
.map(|entry| entry.path())
.filter(|path| path.join("libstdc++.so").exists())
.max()
}