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