Skip to content

Build Script Refinements/Static Linking #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ readme = "README.md"
[dependencies]
libc = "0.2"
#projectm-sys = { path = "projectm-sys", version = "1.0.9-rc.1", features = ["playlist"] }
projectm-sys = { version = "1.0.10" }
projectm-sys = { version = "1.1.0-alpha.1" }
rand = "0.8"

[features]
default = ["playlist"]
playlist = ["projectm-sys/playlist"]
playlist = ["projectm-sys/playlist"]
static = ["projectm-sys/static"]
3 changes: 3 additions & 0 deletions projectm-sys/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[target.wasm32-unknown-emscripten]
linker = ".cargo/linker-emscripten"

[target.x86_64-unknown-linux-gnu]
rustflags = "-C link-arg=-lGL -C link-arg=-lstdc++ -C link-arg=-lgomp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these needed?
should we really overwrite linker args just for linux/x86?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've found that these are necessary otherwise the linker complains. I think rustc only links libc, not libc++, and gomp which I guess is a projectm dependency of some sort.

4 changes: 3 additions & 1 deletion projectm-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "projectm-sys"
version = "1.0.10"
version = "1.1.0-alpha.1"
edition = "2021"
rust-version = "1.65"
authors = ["AnomieVision <[email protected]>", "Mischa Spiegelmock <[email protected]>"]
Expand Down Expand Up @@ -47,3 +47,5 @@ lazy_static = "1.4.0"
[features]
default = ["playlist"]
playlist = []
static = []

137 changes: 95 additions & 42 deletions projectm-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,29 @@ use std::path::PathBuf;
mod build_bindgen;
use crate::build_bindgen::bindgen;

// Functions to determine feature flags
fn enable_playlist() -> &'static str {
if cfg!(feature = "playlist") {
"ON"
} else {
"OFF"
}
}

// Are we linking to shared or static libraries?
fn build_shared_libs_flag() -> &'static str {
if cfg!(feature = "static") {
"OFF" // Disable shared libs to enable static linking
} else {
"ON" // Enable shared libs
}
}

fn main() {
// Get the path to the projectM source code
// 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
// Verify the existence of the libprojectM directory
if !projectm_path.exists() {
println!("cargo:warning=The libprojectM source code is missing.");
println!(
Expand All @@ -18,16 +36,13 @@ fn main() {
std::process::exit(1);
}

// Determine if the 'playlist' feature is enabled
let enable_playlist = if cfg!(feature = "playlist") {
"ON"
} else {
"OFF"
};
// Determine feature flags
let enable_playlist_flag = enable_playlist();
let build_shared_libs = build_shared_libs_flag();

let dst;

// Platform-specific configurations
// Platform-specific CMake configurations
if cfg!(target_os = "windows") {
// Ensure VCPKG installation root is set
let vcpkg_root = match env::var("VCPKG_INSTALLATION_ROOT") {
Expand Down Expand Up @@ -55,80 +70,118 @@ fn main() {
// Set VCPKG_ROOT for CMake
env::set_var("VCPKG_ROOT", &vcpkg_root);

// Optionally set CMAKE_PREFIX_PATH
// Define the installation path for vcpkg
let vcpkg_installed = vcpkg_root.join("installed").join("x64-windows-static-md");
let vcpkg_installed_str = vcpkg_installed.to_str().unwrap();

// Define projectM_Eval_DIR and store in a variable
let projectm_eval_dir = projectm_path.join("vendor").join("projectm-eval");
let projectm_eval_dir_str = projectm_eval_dir.to_str().unwrap();

// Convert vcpkg_toolchain to string
let vcpkg_toolchain_str = vcpkg_toolchain.to_str().unwrap();

// Configure and build libprojectM using CMake for Windows
dst = cmake::Config::new(&projectm_path)
let mut cmake_config = cmake::Config::new(&projectm_path);
cmake_config
.generator("Visual Studio 17 2022")
.define("CMAKE_TOOLCHAIN_FILE", &vcpkg_toolchain)
.define("CMAKE_TOOLCHAIN_FILE", vcpkg_toolchain_str)
.define("VCPKG_TARGET_TRIPLET", "x64-windows-static-md")
.define(
"CMAKE_MSVC_RUNTIME_LIBRARY",
"MultiThreaded$<$<CONFIG:Debug>: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("ENABLE_PLAYLIST", enable_playlist_flag)
.define("projectM_Eval_DIR", projectm_eval_dir_str)
.define("CMAKE_PREFIX_PATH", vcpkg_installed_str)
.define("CMAKE_VERBOSE_MAKEFILE", "ON")
.define("BUILD_TESTING", "OFF")
.define("BUILD_EXAMPLES", "OFF")
.build();
.define("BUILD_SHARED_LIBS", build_shared_libs); // static/dynamic

dst = cmake_config.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("ENABLE_PLAYLIST", enable_playlist_flag)
.define("BUILD_TESTING", "OFF")
.define("BUILD_EXAMPLES", "OFF")
.define("ENABLE_EMSCRIPTEN", "ON")
.define("BUILD_SHARED_LIBS", build_shared_libs) // static/dynamic
.build();
} else {
// Configure and build libprojectM using CMake for other platforms
// Configure and build libprojectM using CMake for other platforms (Linux, macOS)
dst = cmake::Config::new(&projectm_path)
.define("ENABLE_PLAYLIST", enable_playlist)
.define("ENABLE_PLAYLIST", enable_playlist_flag)
.define("BUILD_TESTING", "OFF")
.define("BUILD_EXAMPLES", "OFF")
.define("BUILD_SHARED_LIBS", build_shared_libs) // static/dynamic
.build();
}

// Specify the library search path
println!("cargo:rustc-link-search=native={}/lib", dst.display());

// Determine the library name based on the build profile
// Determine the build profile (release or debug)
let profile = env::var("PROFILE").unwrap_or_else(|_| "release".to_string());

// Platform-specific library linking
// Platform and feature-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");
// Static or Dynamic linking based on 'static' feature
if cfg!(feature = "static") {
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");
if cfg!(feature = "playlist") {
println!("cargo:rustc-link-lib=static=projectM-4-playlistd");
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");
}
}
}
} else {
// 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");
// For other platforms (Linux, macOS)
if cfg!(feature = "static") {
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=dylib=projectM-4d");
if cfg!(feature = "playlist") {
println!("cargo:rustc-link-lib=dylib=projectM-4-playlistd");
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");
}
}
}
}

// Run bindgen to generate Rust bindings
// Generate Rust bindings using bindgen
bindgen();
}
}