diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 39077eb..9484979 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -3,6 +3,17 @@ use cargo_metadata::{MetadataCommand, Package}; use serde::Deserialize; use std::{env, ffi::OsString, process::Command}; +#[derive(Debug, Clone, Bpaf)] +#[bpaf(options)] +enum Options { + #[bpaf(command)] + /// Compile ZLUDA (default command) + Build(#[bpaf(external(build))] Build), + #[bpaf(command)] + /// Build ZLUDA package + Zip, +} + #[derive(Debug, Clone, Bpaf)] struct Build { #[bpaf(any("CARGO", not_help), many)] @@ -18,15 +29,16 @@ fn not_help(s: OsString) -> Option { } } +// We need to sniff out some args passed to cargo to understand how to create +// symlinks (should they go into `target/debug`, `target/release` or custom) #[derive(Debug, Clone, Bpaf)] -#[bpaf(options)] -enum Options { - #[bpaf(command)] - /// Compile ZLUDA (default command) - Build(#[bpaf(external(build))] Build), - #[bpaf(command)] - /// Build ZLUDA package - Zip, +struct Cargo { + #[bpaf(switch, long, short)] + release: Option, + #[bpaf(long)] + profile: Option, + #[bpaf(any("", Some), many)] + _unused: Vec, } struct Project { @@ -57,6 +69,8 @@ struct ZludaMetadata { windows_only: bool, #[serde(default)] debug_only: bool, + #[serde(default)] + linux_symlinks: Vec, } fn main() { @@ -77,30 +91,83 @@ fn main() { } fn compile(b: Build) { + let profile = sniff_out_profile_name(&b.cargo_arguments); let meta = MetadataCommand::new().no_deps().exec().unwrap(); - let is_release = b - .cargo_arguments - .iter() - .any(|a| a == "-r" || a == "--release"); - let projects = meta.packages.into_iter().filter_map(Project::try_new); + let target_directory = meta.target_directory.into_std_path_buf(); + let projects = meta + .packages + .into_iter() + .filter_map(Project::try_new) + .collect::>(); let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()); let mut command = Command::new(&cargo); command.arg("build"); command.arg("--locked"); - for project in projects { + for project in projects.iter() { if project.meta.windows_only && cfg!(not(windows)) { continue; } - if project.meta.debug_only && is_release { + if project.meta.debug_only && profile != "debug" { continue; } command.arg("--package"); command.arg(&project.name); } command.args(b.cargo_arguments); - command.status().unwrap(); + assert!(command.status().unwrap().success()); + os::make_symlinks(target_directory, projects, profile); +} + +fn sniff_out_profile_name(b: &[OsString]) -> String { + let parsed_cargo_arguments = cargo().to_options().run_inner(b); + match parsed_cargo_arguments { + Ok(Cargo { + release: Some(true), + .. + }) => "release".to_string(), + Ok(Cargo { + profile: Some(profile), + .. + }) => profile, + _ => "debug".to_string(), + } } fn zip() { todo!() } + +#[cfg(unix)] +mod os { + pub fn make_symlinks( + target_directory: std::path::PathBuf, + projects: Vec, + profile: String, + ) { + use std::fs; + use std::os::unix::fs as unix_fs; + for project in projects.iter() { + let mut target = target_directory.clone(); + target.extend([&*profile, &format!("lib{}.so", project.name)]); + for source in project.meta.linux_symlinks.iter() { + let mut link = target_directory.clone(); + link.extend([&*profile, source]); + let mut dir = link.clone(); + assert!(dir.pop()); + fs::create_dir_all(dir).unwrap(); + fs::remove_file(&link).ok(); + unix_fs::symlink(&target, link).unwrap(); + } + } + } +} + +#[cfg(not(unix))] +mod os { + pub fn make_symlinks( + target_directory: std::path::PathBuf, + projects: Vec, + profile: String, + ) { + } +} diff --git a/zluda/Cargo.toml b/zluda/Cargo.toml index 2ffe7ea..6bafefc 100644 --- a/zluda/Cargo.toml +++ b/zluda/Cargo.toml @@ -26,3 +26,7 @@ rustc-hash = "1.1" winapi = { version = "0.3", features = ["heapapi", "std"] } [package.metadata.zluda] +linux_symlinks = [ + "libcuda.so", + "libcuda.so.1", +] \ No newline at end of file diff --git a/zluda_dump/Cargo.toml b/zluda_dump/Cargo.toml index 58df9e3..c5985a1 100644 --- a/zluda_dump/Cargo.toml +++ b/zluda_dump/Cargo.toml @@ -31,4 +31,9 @@ detours-sys = { path = "../detours-sys" } libc = "0.2" [package.metadata.zluda] -debug_only = true +linux_symlinks = [ + "dump/libcuda.so", + "dump/libcuda.so.1", + "dump_nvidia/libcuda.so", + "dump_nvidia/libcuda.so.1", +] diff --git a/zluda_ml/Cargo.toml b/zluda_ml/Cargo.toml index 29d88d7..1440dec 100644 --- a/zluda_ml/Cargo.toml +++ b/zluda_ml/Cargo.toml @@ -13,3 +13,9 @@ cuda_base = { path = "../cuda_base" } cuda_types = { path = "../cuda_types" } [package.metadata.zluda] +linux_symlinks = [ + "libnvidia-ml.so", + "libnvidia-ml.so.1", + "dump/libnvidia-ml.so", + "dump/libnvidia-ml.so.1", +]