musikr: clean up buildscript

This commit is contained in:
Alexander Capehart 2025-02-19 12:44:58 -07:00
parent 2b73be1995
commit 89ab6ee336
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47

View file

@ -1,25 +1,22 @@
use cxx_build;
use std::env;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::error::Error;
fn main() {
let working_dir = env::current_dir().expect("Failed to get current working directory");
let target = env::var("TARGET").expect("TARGET env var not set");
let working_dir = Path::new(&working_dir);
// Define directories
fn build_taglib(target: &str, working_dir: &Path) -> Result<PathBuf, Box<dyn Error>> {
let taglib_src_dir = working_dir.join("taglib");
let taglib_build_dir = taglib_src_dir.join("build");
let taglib_pkg_dir = taglib_src_dir.join("pkg");
// Determine if building for Android
let is_android = target.contains("android");
let arch_build_dir = taglib_build_dir.join(&target);
let arch_pkg_dir = taglib_pkg_dir.join(&target);
// Prepare cmake command
// If lib/libtag.a exists, we don't need to build it
if arch_pkg_dir.join("lib/libtag.a").exists() {
return Ok(arch_pkg_dir);
}
// Prepare basic cmake arguments
let mut cmake_args = vec![
"-B".to_string(),
arch_build_dir.to_str().unwrap().to_string(),
@ -33,9 +30,8 @@ fn main() {
"-DCMAKE_CXX_FLAGS=-fPIC".to_string(),
];
// Add Android-specific arguments if building for Android
if is_android {
// Get architecture
if target.contains("android") {
// Android target, we need to tack on the NDK toolchain file/args
let arch = if target == "x86_64-linux-android" {
"x86_64"
} else if target.contains("i686-linux-android") {
@ -45,7 +41,8 @@ fn main() {
} else if target.contains("armv7-linux-androideabi") {
"armeabi-v7a"
} else {
panic!("Unsupported Android target: {}", target);
// should never happen
return Err(format!("Unsupported Android target: {}", target).into());
};
let clang_path = env::var("CLANG_PATH").expect("CLANG_PATH env var not set");
@ -53,7 +50,7 @@ fn main() {
let ndk_path = if let Some(pos) = clang_path.find(toolchains_marker) {
&clang_path[..pos]
} else {
panic!("CLANG_PATH does not contain '{}'", toolchains_marker);
return Err(format!("CLANG_PATH does not contain '{}'", toolchains_marker).into());
};
let ndk_toolchain = working_dir.join("android.toolchain.cmake");
@ -69,10 +66,9 @@ fn main() {
let status = Command::new("cmake")
.args(&cmake_args)
.current_dir(&taglib_src_dir)
.status()
.expect("Failed to run cmake configure");
.status()?;
if !status.success() {
panic!("cmake configure failed for target {}", target);
return Err(format!("cmake configure failed for target {}", target).into());
}
// Build step
@ -85,10 +81,9 @@ fn main() {
"-j{}",
std::thread::available_parallelism().unwrap().get()
))
.status()
.expect("Failed to run cmake build");
.status()?;
if !status.success() {
panic!("cmake build failed for target {}", target);
return Err(format!("cmake build failed for target {}", target).into());
}
// Install step
@ -100,22 +95,15 @@ fn main() {
.arg("--prefix")
.arg(arch_pkg_dir.to_str().unwrap())
.arg("--strip")
.status()
.expect("Failed to run cmake install");
.status()?;
if !status.success() {
panic!("cmake install failed for arch {}", target);
return Err(format!("cmake install failed for arch {}", target).into());
}
println!(
"cargo:rustc-link-search=native={}/lib",
arch_pkg_dir.display()
);
println!("cargo:rustc-link-lib=static=tag");
println!("cargo:rustc-link-lib=static=c++_static");
println!("cargo:rustc-link-lib=static=c++abi");
println!("cargo:rustc-link-lib=unwind");
Ok(arch_pkg_dir)
}
// Build the shim and cxx bridge together
fn configure_cxx_bridge(target: &str) -> Result<(), Box<dyn Error>> {
let mut builder = cxx_build::bridge("src/taglib/bridge.rs");
builder
.file("shim/iostream_shim.cpp")
@ -127,19 +115,44 @@ fn main() {
.file("shim/id3v2_shim.cpp")
.file("shim/mp4_shim.cpp")
.include(format!("taglib/pkg/{}/include", target))
.include(".") // Add the current directory to include path
.include(".")
.flag_if_supported("-std=c++14");
if is_android {
if target.contains("android") {
builder
.cpp_link_stdlib("c++_static")
.flag("-static-libstdc++")
// Magic linker flags that statically link exception handling symbols
// to the library.
.flag("-fexceptions")
.flag("-funwind-tables"); // Use shared C++ runtime for Android compatibility
.flag("-funwind-tables");
}
builder.compile("taglib_cxx_bindings");
// Rebuild if shim files change
println!("cargo:rerun-if-changed=shim/");
println!("cargo:rerun-if-changed=taglib/");
Ok(())
}
fn main() -> Result<(), Box<dyn Error>> {
let working_dir = env::current_dir()?;
let target = env::var("TARGET")?;
let working_dir = Path::new(&working_dir);
let arch_pkg_dir = build_taglib(&target, &working_dir)?;
println!(
"cargo:rustc-link-search=native={}/lib",
arch_pkg_dir.display()
);
println!("cargo:rustc-link-lib=static=tag");
println!("cargo:rerun-if-changed=taglib/");
configure_cxx_bridge(&target)?;
if target.contains("android") {
// Magic linker flags that statically link the C++ runtime
// and exception handling to the library.
println!("cargo:rustc-link-lib=static=c++_static");
println!("cargo:rustc-link-lib=static=c++abi");
println!("cargo:rustc-link-lib=unwind");
}
println!("cargo:rerun-if-changed=shim/");
Ok(())
}