musikr: implement taglib build step for rust module

This commit is contained in:
Alexander Capehart 2025-02-04 17:02:59 -07:00
parent 6216e1d591
commit ed0abb661c
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
8 changed files with 301 additions and 0 deletions

View file

@ -25,3 +25,7 @@ android.nonFinalResIds=true
org.gradle.parallel=true org.gradle.parallel=true
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
project.RUST_ANDROID_GRADLE_ARMV7_LINUX_ANDROIDEABI_NDK_PATH=android.ndkDirectory
project.RUST_ANDROID_GRADLE_I686_LINUX_ANDROID_NDK_PATH=android.ndkDirectory
project.RUST_ANDROID_GRADLE_AARCH64_LINUX_ANDROID_NDK_PATH=android.ndkDirectory
project.RUST_ANDROID_GRADLE_X64_64_LINUX_ANDROID_NDK_PATH=android.ndkDirectory

View file

@ -46,6 +46,7 @@ android {
} }
} }
cargo { cargo {
module = "./src/main/jni" module = "./src/main/jni"
libname = "metadatajni" libname = "metadatajni"
@ -78,6 +79,7 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
} }
// //
//task assembleTaglib(type: Exec) { //task assembleTaglib(type: Exec) {
// def jniDir = "$projectDir/src/main/cpp" // def jniDir = "$projectDir/src/main/cpp"

View file

@ -2,12 +2,27 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.10.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
[[package]]
name = "cc"
version = "1.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2"
dependencies = [
"shlex",
]
[[package]] [[package]]
name = "cesu8" name = "cesu8"
version = "1.1.0" version = "1.1.0"
@ -20,6 +35,42 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
dependencies = [
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "codespan-reporting"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [
"termcolor",
"unicode-width",
]
[[package]] [[package]]
name = "combine" name = "combine"
version = "4.6.7" version = "4.6.7"
@ -30,6 +81,71 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "cxx"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fc894913dccfed0f84106062c284fa021c3ba70cb1d78797d6f5165d4492e45"
dependencies = [
"cc",
"cxxbridge-cmd",
"cxxbridge-flags",
"cxxbridge-macro",
"foldhash",
"link-cplusplus",
]
[[package]]
name = "cxx-build"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "503b2bfb6b3e8ce7f95d865a67419451832083d3186958290cee6c53e39dfcfe"
dependencies = [
"cc",
"codespan-reporting",
"proc-macro2",
"quote",
"scratch",
"syn",
]
[[package]]
name = "cxxbridge-cmd"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0d2cb64a95b4b5a381971482235c4db2e0208302a962acdbe314db03cbbe2fb"
dependencies = [
"clap",
"codespan-reporting",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f797b0206463c9c2a68ed605ab28892cca784f1ef066050f4942e3de26ad885"
[[package]]
name = "cxxbridge-macro"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e79010a2093848e65a3e0f7062d3f02fb2ef27f866416dfe436fccfa73d3bb59"
dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]]
name = "foldhash"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.21.1" version = "0.21.1"
@ -52,6 +168,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "link-cplusplus"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.25" version = "0.4.25"
@ -68,6 +193,8 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
name = "metadatajni" name = "metadatajni"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"cxx",
"cxx-build",
"jni", "jni",
] ]
@ -89,6 +216,12 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rustversion"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]] [[package]]
name = "same-file" name = "same-file"
version = "1.0.6" version = "1.0.6"
@ -98,6 +231,24 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "scratch"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.98" version = "2.0.98"
@ -109,6 +260,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.69" version = "1.0.69"
@ -135,6 +295,12 @@ version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]]
name = "unicode-width"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]] [[package]]
name = "walkdir" name = "walkdir"
version = "2.5.0" version = "2.5.0"

View file

@ -8,4 +8,8 @@ crate-type = ["cdylib"]
name = "metadatajni" name = "metadatajni"
[dependencies] [dependencies]
cxx = "1.0.137"
jni = "0.21.1" jni = "0.21.1"
[build-dependencies]
cxx-build = "1.0.137"

View file

@ -0,0 +1,15 @@
# Define the minimum CMake version and project name
cmake_minimum_required(VERSION 3.22.1)
# Set the Android NDK path
option(ANDROID_NDK_PATH "Path to Android NDK Install. Should be same version specified in gradle." REQUIRED)
# Specify the target Android API level
set(ANDROID_PLATFORM android-24)
# Define the toolchain
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI})
set(CMAKE_ANDROID_NDK ${ANDROID_NDK_PATH})
set(CMAKE_ANDROID_STL_TYPE c++_static)
set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)

View file

@ -0,0 +1,101 @@
use std::env;
use std::path::Path;
use std::process::Command;
use cxx_build;
fn main() {
let working_dir = env::current_dir().expect("Failed to get current working directory");
// New: Extract ndk path from CLANG_PATH.
let clang_path = env::var("CLANG_PATH").expect("CLANG_PATH env var not set");
let toolchains_marker = "/toolchains";
let ndk_path = if let Some(pos) = clang_path.find(toolchains_marker) {
&clang_path[..pos]
} else {
panic!("CLANG_PATH does not contain '{}'", toolchains_marker);
};
let working_dir = Path::new(&working_dir);
// Define directories.
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");
let ndk_toolchain = working_dir.join("android.toolchain.cmake");
// Define architectures.
let target = env::var("TARGET").expect("TARGET env var not set");
let arch = if target.contains("x86_64") {
"x86_64"
} else if target.contains("i686") {
"x86"
} else if target.contains("aarch64") {
"arm64-v8a"
} else if target.contains("arm") {
"armeabi-v7a"
} else {
"unknown"
};
let arch_build_dir = taglib_build_dir.join(arch);
let arch_pkg_dir = taglib_pkg_dir.join(arch);
// Configure step.
let status = Command::new("cmake")
.arg("-B")
.arg(arch_build_dir.to_str().unwrap())
.arg(format!("-DANDROID_NDK_PATH={}", ndk_path))
.arg(format!(
"-DCMAKE_TOOLCHAIN_FILE={}",
ndk_toolchain.to_str().unwrap()
))
.arg(format!("-DANDROID_ABI={}", arch))
.arg("-DBUILD_SHARED_LIBS=OFF")
.arg("-DVISIBILITY_HIDDEN=ON")
.arg("-DBUILD_TESTING=OFF")
.arg("-DBUILD_EXAMPLES=OFF")
.arg("-DBUILD_BINDINGS=OFF")
.arg("-DWITH_ZLIB=OFF")
.arg("-DCMAKE_BUILD_TYPE=Release")
.arg("-DCMAKE_CXX_FLAGS=-fPIC")
.current_dir(&taglib_src_dir)
.status()
.expect("Failed to run cmake configure");
if !status.success() {
panic!("cmake configure failed for arch {}", arch);
}
// Build step.
let status = Command::new("cmake")
.arg("--build")
.arg(arch_build_dir.to_str().unwrap())
.arg("--config")
.arg("Release")
.arg(format!("-j{}", std::thread::available_parallelism().unwrap().get()))
.status()
.expect("Failed to run cmake build");
if !status.success() {
panic!("cmake build failed for arch {}", arch);
}
// Install step.
let status = Command::new("cmake")
.arg("--install")
.arg(arch_build_dir.to_str().unwrap())
.arg("--config")
.arg("Release")
.arg("--prefix")
.arg(arch_pkg_dir.to_str().unwrap())
.arg("--strip")
.status()
.expect("Failed to run cmake install");
if !status.success() {
panic!("cmake install failed for arch {}", arch);
}
cxx_build::bridge("src/lib.rs")
.include(format!["taglib/pkg/{}/include", arch]) // path to Taglib includes
.flag_if_supported("-std=c++14")
.compile("taglib_cxx_bindings");
// println!("cargo:rerun-if-changed=src/lib.rs");
}

View file

@ -1,3 +1,4 @@
# Deprecated: Please use the new Rust buildscript in build.rs
set -e set -e
WORKING_DIR=$1 WORKING_DIR=$1
echo "Working directory is at $WORKING_DIR" echo "Working directory is at $WORKING_DIR"

View file

@ -2,6 +2,14 @@ use jni::objects::{JClass, JString};
use jni::sys::jstring; use jni::sys::jstring;
use jni::JNIEnv; use jni::JNIEnv;
#[cxx::bridge]
mod ffi {
unsafe extern "C++" {
include!("taglib/taglib.h");
// Add the C++ APIs you need to call.
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn Java_org_oxycblt_musikr_metadata_MetadataJNI_rust( pub extern "C" fn Java_org_oxycblt_musikr_metadata_MetadataJNI_rust(
mut env: JNIEnv, mut env: JNIEnv,