diff --git a/.github/workflows/build_emscripten.yml b/.github/workflows/build_emscripten.yml index db146db..8ebd1cf 100644 --- a/.github/workflows/build_emscripten.yml +++ b/.github/workflows/build_emscripten.yml @@ -21,6 +21,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - name: Setup EMSDK uses: mymindstorm/setup-emsdk@v14 diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index b2b61e5..ac7ee8c 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -21,7 +21,9 @@ jobs: steps: - uses: actions/checkout@v4 - + with: + submodules: recursive + - name: Install Packages run: | sudo apt-get update diff --git a/.github/workflows/build_osx.yml b/.github/workflows/build_osx.yml index 496a8b1..a472547 100644 --- a/.github/workflows/build_osx.yml +++ b/.github/workflows/build_osx.yml @@ -21,6 +21,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - name: Update Local Toolchain run: | diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index f42bb22..c56aaa7 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -21,10 +21,12 @@ jobs: steps: - uses: actions/checkout@v4 - + with: + submodules: recursive + - name: Install Dependencies run: vcpkg --triplet=x64-windows-static-md install glew - + - name: Update Local Toolchain run: | rustup update diff --git a/.github/workflows/publish_crate.yml b/.github/workflows/publish_crate.yml index 604cfc2..99194f6 100644 --- a/.github/workflows/publish_crate.yml +++ b/.github/workflows/publish_crate.yml @@ -14,6 +14,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - name: Install Packages run: | @@ -52,6 +54,6 @@ jobs: - name: Publish env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: | cargo publish --token $CARGO_REGISTRY_TOKEN \ No newline at end of file diff --git a/.github/workflows/publish_sys_crate.yml b/.github/workflows/publish_sys_crate.yml index 16872b7..7183f1a 100644 --- a/.github/workflows/publish_sys_crate.yml +++ b/.github/workflows/publish_sys_crate.yml @@ -14,6 +14,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - name: Install Packages run: | @@ -45,7 +47,7 @@ jobs: - name: Publish env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: | cd projectm-sys cargo publish --token $CARGO_REGISTRY_TOKEN \ No newline at end of file diff --git a/.gitignore b/.gitignore index 088ba6b..67366cb 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,7 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk + +.DS_Store + +.idea/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a330f63 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,5 @@ +[submodule "projectm-sys/libprojectM"] + path = projectm-sys/libprojectM + url = https://github.com/projectM-visualizer/projectm.git +[submodule "libprojectM"] + branch = v4.1.2 diff --git a/Cargo.toml b/Cargo.toml index e05ed68..9dc90ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,21 +1,22 @@ [package] name = "projectm" -version = "2.0.1-alpha" +version = "2.0.2" edition = "2021" rust-version = "1.65" -authors = ["AnomieVision "] +authors = ["AnomieVision ", "Mischa Spiegelmock "] description = "Bindings for ProjectM" license = " LGPL-3.0-or-later" repository = "https://github.com/projectM-visualizer/projectm-rs" #https://github.com/anomievision/projectm-rs -keywords = ["visualization", "audio", "sound", "projectm"] +keywords = ["visualization", "audio", "sound", "projectm"] categories = ["multimedia", "multimedia::video", "multimedia::audio"] readme = "README.md" [dependencies] -libc = "0.2.147" -projectm-sys = { path = "projectm-sys", version = "1.0.8", features = ["playlist"] } -rand = "0.8.5" +libc = "0.2" +#projectm-sys = { path = "projectm-sys", version = "1.0.9-rc.1", features = ["playlist"] } +projectm-sys = { version = "1.0.10" } +rand = "0.8" [features] default = ["playlist"] -playlist = [] +playlist = ["projectm-sys/playlist"] \ No newline at end of file diff --git a/projectm-sys/Cargo.toml b/projectm-sys/Cargo.toml index e0a54ba..54a1eda 100644 --- a/projectm-sys/Cargo.toml +++ b/projectm-sys/Cargo.toml @@ -1,25 +1,49 @@ [package] name = "projectm-sys" -version = "1.0.8" +version = "1.0.10" edition = "2021" rust-version = "1.65" -authors = ["AnomieVision "] +authors = ["AnomieVision ", "Mischa Spiegelmock "] description = "Bindings for ProjectM" license = "LGPL-3.0-or-later" -repository = "https://github.com/anomievision/projectm-sys" +repository = "https://github.com/projectM-visualizer/projectm-rs" documentation = "https://docs.rs/projectm-sys/latest" -keywords = ["visualization", "audio", "sound", "projectm"] +keywords = ["visualization", "audio", "sound", "projectm"] categories = ["multimedia", "multimedia::video", "multimedia::audio"] readme = "README.md" links = "projectm" +include = [ + "src/**", + "Cargo.toml", + "build.rs", + "README.md", + "LICENSE", + "build_bindgen.rs", + "libprojectM/CMakeLists.txt", + "libprojectM/src/**", + "libprojectM/include/**", + "libprojectM/presets/CMakeLists.txt", + "libprojectM/cmake/**", + "libprojectM/vendor/**", + "libprojectM/vendor/projectm-eval/**", + "libprojectM/vendor/**/CMakeLists.txt", + "libprojectM/vendor/**/cmake/**", + "libprojectM/**/*.cmake", + "libprojectM/**/*.h", + "libprojectM/**/*.hpp", + "libprojectM/config*", + "libprojectM/vcpkg*", + "bindgen/**", +] + [dependencies] [build-dependencies] cmake = "0.1.50" -bindgen = "0.66.1" +bindgen = "0.70.1" lazy_static = "1.4.0" [features] default = ["playlist"] -playlist = [] \ No newline at end of file +playlist = [] diff --git a/projectm-sys/build.rs b/projectm-sys/build.rs index 03bba86..43d20ee 100644 --- a/projectm-sys/build.rs +++ b/projectm-sys/build.rs @@ -1,128 +1,134 @@ -#[macro_use] -extern crate lazy_static; - -use std::{env, path::Path, process::Command}; +use std::env; +use std::path::PathBuf; mod build_bindgen; use crate::build_bindgen::bindgen; -lazy_static! { - static ref PROJECTM_BUILD: String = format!("{}/projectm", env::var("OUT_DIR").unwrap()); -} - fn main() { - if !Path::new(PROJECTM_BUILD.as_str()).exists() { - let _ = Command::new("git") - .args([ - "-c", - "advice.detachedHead=false", - "clone", - "--recurse-submodules", - "--depth=1", - "--branch", - "v4.0.0", - "https://github.com/projectM-visualizer/projectm.git", - &PROJECTM_BUILD, - ]) - .status(); - } - - // Feature: enable-playlist - fn enable_playlist() -> String { - if cfg!(feature = "playlist") { - "ON".to_string() - } else { - "OFF".to_string() - } - } - - #[cfg(target_os = "windows")] - let dst = cmake::Config::new(PROJECTM_BUILD.as_str()) - .generator("Visual Studio 17 2022") - .define( - "CMAKE_TOOLCHAIN_FILE", - format!( - "{}/scripts/buildsystems/vcpkg.cmake", - env::var("VCPKG_INSTALLATION_ROOT").unwrap() - ), - ) - .define("VCPKG_TARGET_TRIPLET", "x64-windows-static-md") - .define( - "CMAKE_MSVC_RUNTIME_LIBRARY", - "MultiThreaded$<$:Debug>DLL", - ) - .define("ENABLE_PLAYLIST", enable_playlist().as_str()) - .build(); - - #[cfg(target_os = "linux")] - let dst = cmake::Config::new(PROJECTM_BUILD.as_str()) - .define("ENABLE_PLAYLIST", enable_playlist().as_str()) - .build(); - - #[cfg(target_os = "macos")] - let dst = cmake::Config::new(PROJECTM_BUILD.as_str()) - .define("ENABLE_PLAYLIST", enable_playlist().as_str()) - .build(); - - #[cfg(target_os = "emscripten")] - let dst = cmake::Config::new(PROJECTM_BUILD.as_str()) - .define("ENABLE_PLAYLIST", enable_playlist().as_str()) - .define("ENABLE_EMSCRIPTEN", "ON") - .build(); - - println!("cargo:rustc-link-search=native={}/lib", dst.display()); - - #[cfg(target_os = "windows")] - if Ok("release".to_owned()) == env::var("PROFILE") { - println!("cargo:rustc-link-lib=dylib=projectM-4"); - - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlist"); - } else { - println!("cargo:rustc-link-lib=dylib=projectM-4d"); - - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlistd"); + // Get the path to the projectM source code + let projectm_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("libprojectM"); + + // Check if the libprojectM source code exists + if !projectm_path.exists() { + println!("cargo:warning=The libprojectM source code is missing."); + println!( + "cargo:warning=If you are building from a git clone, please run 'git submodule update --init --recursive'." + ); + println!("cargo:warning=If you downloaded this crate from crates.io, please ensure that the crate was packaged correctly."); + std::process::exit(1); } - #[cfg(target_os = "linux")] - if Ok("release".to_owned()) == env::var("PROFILE") { - println!("cargo:rustc-link-lib=dylib=libprojectM=4"); - - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlist"); + // Determine if the 'playlist' feature is enabled + let enable_playlist = if cfg!(feature = "playlist") { + "ON" } else { - println!("cargo:rustc-link-lib=dylib=projectM-4d"); - - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlistd"); - } - - #[cfg(target_os = "macos")] - if Ok("release".to_owned()) == env::var("PROFILE") { - println!("cargo:rustc-link-lib=dylib=projectM-4"); + "OFF" + }; + + let dst; + + // Platform-specific configurations + if cfg!(target_os = "windows") { + // Ensure VCPKG installation root is set + let vcpkg_root = match env::var("VCPKG_INSTALLATION_ROOT") { + Ok(val) => val, + Err(_) => { + println!("cargo:warning=VCPKG_INSTALLATION_ROOT is not set. Please set it to your VCPKG installation directory."); + std::process::exit(1); + } + }; + + let vcpkg_root = PathBuf::from(vcpkg_root); + let vcpkg_toolchain = vcpkg_root + .join("scripts") + .join("buildsystems") + .join("vcpkg.cmake"); + + if !vcpkg_toolchain.exists() { + println!( + "cargo:warning=The vcpkg toolchain file was not found at: {}", + vcpkg_toolchain.display() + ); + std::process::exit(1); + } - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlist"); + // Set VCPKG_ROOT for CMake + env::set_var("VCPKG_ROOT", &vcpkg_root); + + // Optionally set CMAKE_PREFIX_PATH + let vcpkg_installed = vcpkg_root.join("installed").join("x64-windows-static-md"); + + // Configure and build libprojectM using CMake for Windows + dst = cmake::Config::new(&projectm_path) + .generator("Visual Studio 17 2022") + .define("CMAKE_TOOLCHAIN_FILE", &vcpkg_toolchain) + .define("VCPKG_TARGET_TRIPLET", "x64-windows-static-md") + .define( + "CMAKE_MSVC_RUNTIME_LIBRARY", + "MultiThreaded$<$:Debug>DLL", + ) + .define("ENABLE_PLAYLIST", enable_playlist) + .define( + "projectM_Eval_DIR", + &projectm_path.join("vendor").join("projectm-eval"), + ) + .define("CMAKE_PREFIX_PATH", &vcpkg_installed) + .define("CMAKE_VERBOSE_MAKEFILE", "ON") + .define("BUILD_TESTING", "OFF") + .define("BUILD_EXAMPLES", "OFF") + .build(); + } else if cfg!(target_os = "emscripten") { + // Configure and build libprojectM using CMake for Emscripten + dst = cmake::Config::new(&projectm_path) + .define("ENABLE_PLAYLIST", enable_playlist) + .define("BUILD_TESTING", "OFF") + .define("BUILD_EXAMPLES", "OFF") + .define("ENABLE_EMSCRIPTEN", "ON") + .build(); } else { - println!("cargo:rustc-link-lib=dylib=projectM-4d"); - - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlistd"); + // Configure and build libprojectM using CMake for other platforms + dst = cmake::Config::new(&projectm_path) + .define("ENABLE_PLAYLIST", enable_playlist) + .define("BUILD_TESTING", "OFF") + .define("BUILD_EXAMPLES", "OFF") + .build(); } - #[cfg(target_os = "emscripten")] - if Ok("release".to_owned()) == env::var("PROFILE") { - println!("cargo:rustc-link-lib=static=projectM-4"); + // Specify the library search path + println!("cargo:rustc-link-search=native={}/lib", dst.display()); - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlist"); + // Determine the library name based on the build profile + let profile = env::var("PROFILE").unwrap_or_else(|_| "release".to_string()); + + // Platform-specific library linking + if cfg!(target_os = "windows") || cfg!(target_os = "emscripten") { + // Use static linking for Windows and Emscripten + if profile == "release" { + println!("cargo:rustc-link-lib=static=projectM-4"); + if cfg!(feature = "playlist") { + println!("cargo:rustc-link-lib=static=projectM-4-playlist"); + } + } else { + println!("cargo:rustc-link-lib=static=projectM-4d"); + if cfg!(feature = "playlist") { + println!("cargo:rustc-link-lib=static=projectM-4-playlistd"); + } + } } else { - println!("cargo:rustc-link-lib=static=projectM-4d"); - - #[cfg(feature = "playlist")] - println!("cargo:rustc-link-lib=dylib=projectM-4-playlistd"); + // Use dynamic linking for other platforms (Linux, macOS) + if profile == "release" { + println!("cargo:rustc-link-lib=dylib=projectM-4"); + if cfg!(feature = "playlist") { + println!("cargo:rustc-link-lib=dylib=projectM-4-playlist"); + } + } else { + println!("cargo:rustc-link-lib=dylib=projectM-4d"); + if cfg!(feature = "playlist") { + println!("cargo:rustc-link-lib=dylib=projectM-4-playlistd"); + } + } } - bindgen() + // Run bindgen to generate Rust bindings + bindgen(); } diff --git a/projectm-sys/build_bindgen.rs b/projectm-sys/build_bindgen.rs index 07399ff..5f00b9d 100644 --- a/projectm-sys/build_bindgen.rs +++ b/projectm-sys/build_bindgen.rs @@ -18,7 +18,7 @@ pub fn bindgen() { .header(get_header()) .allowlist_function("projectm_.*") .clang_arg(format!("-I{}/include", out_dir.display())) - .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .generate() .expect("Unable to generate bindings"); diff --git a/projectm-sys/libprojectM b/projectm-sys/libprojectM new file mode 160000 index 0000000..db035da --- /dev/null +++ b/projectm-sys/libprojectM @@ -0,0 +1 @@ +Subproject commit db035da5623b46ac6313b3b84d9c1ecbfc405b7b