Improve build system (#329)

Also fix Dockerfile and Windows build
This commit is contained in:
Andrzej Janik
2025-01-28 01:55:36 +01:00
committed by GitHub
parent 9c0747a5f7
commit df5a96d935
13 changed files with 1444 additions and 15 deletions

View File

@ -0,0 +1,2 @@
[alias]
xtask = "run --package xtask --"

View File

@ -32,7 +32,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update -y && DEBIAN_FRONTEND=noninter
cuda-profiler-api-${CUDA_PKG_VERSION} \ cuda-profiler-api-${CUDA_PKG_VERSION} \
cuda-nvcc-${CUDA_PKG_VERSION} cuda-nvcc-${CUDA_PKG_VERSION}
ARG ROCM_VERSION=6.2.2 ARG ROCM_VERSION=6.3.1
RUN mkdir --parents --mode=0755 /etc/apt/keyrings && \ RUN mkdir --parents --mode=0755 /etc/apt/keyrings && \
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \ wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \
gpg --dearmor | tee /etc/apt/keyrings/rocm.gpg > /dev/null && \ gpg --dearmor | tee /etc/apt/keyrings/rocm.gpg > /dev/null && \
@ -43,7 +43,7 @@ RUN mkdir --parents --mode=0755 /etc/apt/keyrings && \
rocm-gdb \ rocm-gdb \
rocm-smi-lib \ rocm-smi-lib \
rocm-llvm-dev \ rocm-llvm-dev \
hip-runtime-amd && \ hip-runtime-amd \
hip-dev && \ hip-dev && \
echo '/opt/rocm/lib' > /etc/ld.so.conf.d/rocm.conf && \ echo '/opt/rocm/lib' > /etc/ld.so.conf.d/rocm.conf && \
ldconfig ldconfig

1197
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@ members = [
"ptx_parser", "ptx_parser",
"ptx_parser_macros", "ptx_parser_macros",
"ptx_parser_macros_impl", "ptx_parser_macros_impl",
"xtask",
"zluda_bindgen", "zluda_bindgen",
] ]
@ -27,3 +28,6 @@ default-members = ["zluda", "zluda_ml", "zluda_inject", "zluda_redirect"]
inherits = "release" inherits = "release"
codegen-units = 1 codegen-units = 1
lto = true lto = true
[profile.dev.package.xtask]
opt-level = 2

View File

@ -51,18 +51,7 @@ Not supported
* Git clone the repo (make sure to use `--recursive` option to fetch submodules): * Git clone the repo (make sure to use `--recursive` option to fetch submodules):
`git clone --recursive https://github.com/vosen/ZLUDA.git` `git clone --recursive https://github.com/vosen/ZLUDA.git`
* Enter freshly cloned `ZLUDA` directory and build with cargo (this takes a while): * Enter freshly cloned `ZLUDA` directory and build with cargo (this takes a while):
`cargo build --release` `cargo xtask --release`
### Linux
If you are building on Linux you must also symlink the ZLUDA output binaries after ZLUDA build finishes:
```
cd target/release
ln -s libnvcuda.so libcuda.so
ln -s libnvcuda.so libcuda.so.1
ln -s libnvml.so libnvidia-ml.so
ln -s libnvml.so libnvidia-ml.so.1
```
## Contributing ## Contributing

11
xtask/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "xtask"
version = "0.0.0"
authors = ["Andrzej Janik <vosen@vosen.pl>"]
edition = "2021"
[dependencies]
bpaf = { version = "0.9.15", features = ["derive"] }
cargo_metadata = "0.19.1"
serde = "1.0.217"
serde_json = "1.0.137"

198
xtask/src/main.rs Normal file
View File

@ -0,0 +1,198 @@
use bpaf::{Args, Bpaf, Parser};
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)]
/// Arguments to pass to cargo, e.g. `--release` for release build
cargo_arguments: Vec<OsString>,
}
fn not_help(s: OsString) -> Option<OsString> {
if s == "-h" || s == "--help" {
None
} else {
Some(s)
}
}
// 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)]
struct Cargo {
#[bpaf(switch, long, short)]
release: Option<bool>,
#[bpaf(long)]
profile: Option<String>,
#[bpaf(any("", Some), many)]
_unused: Vec<OsString>,
}
struct Project {
name: String,
clib_name: Option<String>,
meta: ZludaMetadata,
}
impl Project {
fn try_new(p: Package) -> Option<Project> {
let name = p.name;
let clib_name = p.targets.into_iter().find_map(|target| {
if target.is_cdylib() {
Some(target.name)
} else {
None
}
});
serde_json::from_value::<Option<Metadata>>(p.metadata)
.unwrap()
.map(|m| Self {
name,
clib_name,
meta: m.zluda,
})
}
}
#[derive(Deserialize)]
struct Metadata {
zluda: ZludaMetadata,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct ZludaMetadata {
#[serde(default)]
windows_only: bool,
#[serde(default)]
debug_only: bool,
#[serde(default)]
linux_symlinks: Vec<String>,
}
fn main() {
let options = match options().run_inner(Args::current_args()) {
Ok(b) => b,
Err(err) => match build().to_options().run_inner(Args::current_args()) {
Ok(b) => Options::Build(b),
Err(_) => {
err.print_message(100);
std::process::exit(err.exit_code());
}
},
};
match options {
Options::Build(b) => compile(b),
Options::Zip => zip(),
}
}
fn compile(b: Build) {
let profile = sniff_out_profile_name(&b.cargo_arguments);
let meta = MetadataCommand::new().no_deps().exec().unwrap();
let target_directory = meta.target_directory.into_std_path_buf();
let projects = meta
.packages
.into_iter()
.filter_map(Project::try_new)
.collect::<Vec<_>>();
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.iter() {
if project.meta.windows_only && cfg!(not(windows)) {
continue;
}
if project.meta.debug_only && profile != "debug" {
continue;
}
command.arg("--package");
command.arg(&project.name);
}
command.args(b.cargo_arguments);
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 {
use std::path::PathBuf;
pub fn make_symlinks(
target_directory: std::path::PathBuf,
projects: Vec<super::Project>,
profile: String,
) {
use std::fs;
use std::os::unix::fs as unix_fs;
for project in projects.iter() {
let clib_name = match project.clib_name {
Some(ref l) => l,
None => continue,
};
let libname = format!("lib{}.so", clib_name);
for source in project.meta.linux_symlinks.iter() {
let relative_link = PathBuf::from(source);
let ancestors = relative_link.as_path().ancestors().count();
let mut target = std::iter::repeat_with(|| "../").take(ancestors - 2).fold(
PathBuf::new(),
|mut buff, segment| {
buff.push(segment);
buff
},
);
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();
target.push(&*libname);
unix_fs::symlink(&target, link).unwrap();
}
}
}
}
#[cfg(not(unix))]
mod os {
pub fn make_symlinks(
target_directory: std::path::PathBuf,
projects: Vec<super::Project>,
profile: String,
) {
}
}

View File

@ -24,3 +24,9 @@ rustc-hash = "1.1"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["heapapi", "std"] } winapi = { version = "0.3", features = ["heapapi", "std"] }
[package.metadata.zluda]
linux_symlinks = [
"libcuda.so",
"libcuda.so.1",
]

View File

@ -29,3 +29,11 @@ detours-sys = { path = "../detours-sys" }
[target.'cfg(not(windows))'.dependencies] [target.'cfg(not(windows))'.dependencies]
libc = "0.2" libc = "0.2"
[package.metadata.zluda]
linux_symlinks = [
"dump/libcuda.so",
"dump/libcuda.so.1",
"dump_nvidia/libcuda.so",
"dump_nvidia/libcuda.so.1",
]

View File

@ -10,7 +10,7 @@ use winapi::{
um::libloaderapi::{GetProcAddress, LoadLibraryW}, um::libloaderapi::{GetProcAddress, LoadLibraryW},
}; };
use cuda_types::CUuuid; use cuda_types::cuda::CUuuid;
pub(crate) const LIBCUDA_DEFAULT_PATH: &'static str = "C:\\Windows\\System32\\nvcuda.dll"; pub(crate) const LIBCUDA_DEFAULT_PATH: &'static str = "C:\\Windows\\System32\\nvcuda.dll";
const LOAD_LIBRARY_NO_REDIRECT: &'static [u8] = b"ZludaLoadLibraryW_NoRedirect\0"; const LOAD_LIBRARY_NO_REDIRECT: &'static [u8] = b"ZludaLoadLibraryW_NoRedirect\0";

View File

@ -19,3 +19,6 @@ detours-sys = { path = "../detours-sys" }
zluda_redirect = { path = "../zluda_redirect" } zluda_redirect = { path = "../zluda_redirect" }
zluda_dump = { path = "../zluda_dump" } zluda_dump = { path = "../zluda_dump" }
zluda_ml = { path = "../zluda_ml" } zluda_ml = { path = "../zluda_ml" }
[package.metadata.zluda]
windows_only = true

View File

@ -11,3 +11,11 @@ crate-type = ["cdylib"]
[dependencies] [dependencies]
cuda_base = { path = "../cuda_base" } cuda_base = { path = "../cuda_base" }
cuda_types = { path = "../cuda_types" } 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",
]

View File

@ -11,3 +11,6 @@ crate-type = ["cdylib"]
detours-sys = { path = "../detours-sys" } detours-sys = { path = "../detours-sys" }
wchar = "0.6" wchar = "0.6"
winapi = { version = "0.3", features = [ "sysinfoapi", "memoryapi", "processthreadsapi", "winbase", "winnt", "winerror", "libloaderapi", "tlhelp32", "handleapi", "std"] } winapi = { version = "0.3", features = [ "sysinfoapi", "memoryapi", "processthreadsapi", "winbase", "winnt", "winerror", "libloaderapi", "tlhelp32", "handleapi", "std"] }
[package.metadata.zluda]
windows_only = true