From 380267dd8f990432d4c054f44dc39388973b1474 Mon Sep 17 00:00:00 2001
From: Christian Legnitto <christian@legnitto.com>
Date: Thu, 22 May 2025 20:29:47 -0400
Subject: [PATCH] Use `MANIFEST_DIR` in build scripts

This should be a no-op unless running cargo from
a different location using `--manifest-path`.
---
 crates/cust_raw/build/main.rs      | 59 +++++++++++++++++++++---------
 examples/cuda/gemm/build.rs        |  4 +-
 examples/cuda/path_tracer/build.rs |  9 ++++-
 examples/cuda/vecadd/build.rs      |  8 ++--
 4 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/crates/cust_raw/build/main.rs b/crates/cust_raw/build/main.rs
index 07a8c9cc..abf8d69c 100644
--- a/crates/cust_raw/build/main.rs
+++ b/crates/cust_raw/build/main.rs
@@ -35,6 +35,10 @@ fn main() {
     let outdir = path::PathBuf::from(
         env::var("OUT_DIR").expect("OUT_DIR environment variable should be set by cargo."),
     );
+    let manifest_dir = path::PathBuf::from(
+        env::var("CARGO_MANIFEST_DIR")
+            .expect("CARGO_MANIFEST_DIR environment variable should be set by cargo."),
+    );
 
     let sdk = cuda_sdk::CudaSdk::new().expect("Cannot create CUDA SDK instance.");
     // Emit metadata for the build script.
@@ -63,11 +67,11 @@ fn main() {
         println!("cargo::rerun-if-env-changed={}", e);
     }
 
-    create_cuda_driver_bindings(&sdk, outdir.as_path());
-    create_cuda_runtime_bindings(&sdk, outdir.as_path());
-    create_cublas_bindings(&sdk, outdir.as_path());
-    create_nptx_compiler_bindings(&sdk, outdir.as_path());
-    create_nvvm_bindings(&sdk, outdir.as_path());
+    create_cuda_driver_bindings(&sdk, &outdir, &manifest_dir);
+    create_cuda_runtime_bindings(&sdk, &outdir, &manifest_dir);
+    create_cublas_bindings(&sdk, &outdir, &manifest_dir);
+    create_nptx_compiler_bindings(&sdk, &outdir, &manifest_dir);
+    create_nvvm_bindings(&sdk, &outdir, &manifest_dir);
 
     if cfg!(any(
         feature = "driver",
@@ -101,14 +105,19 @@ fn main() {
     }
 }
 
-fn create_cuda_driver_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
+fn create_cuda_driver_bindings(
+    sdk: &cuda_sdk::CudaSdk,
+    outdir: &path::Path,
+    manifest_dir: &path::Path,
+) {
     if !cfg!(feature = "driver") {
         return;
     }
     let bindgen_path = path::PathBuf::from(format!("{}/driver_sys.rs", outdir.display()));
-    let header = "build/driver_wrapper.h";
+    let header = manifest_dir.join("build/driver_wrapper.h");
+    println!("cargo::rerun-if-changed={}", header.display());
     let bindings = bindgen::Builder::default()
-        .header(header)
+        .header(header.to_str().expect("header should be valid UTF-8"))
         .parse_callbacks(Box::new(callbacks::FunctionRenames::new(
             "cu",
             outdir,
@@ -145,14 +154,19 @@ fn create_cuda_driver_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
         .expect("Cannot write CUDA driver bindgen output to file.");
 }
 
-fn create_cuda_runtime_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
+fn create_cuda_runtime_bindings(
+    sdk: &cuda_sdk::CudaSdk,
+    outdir: &path::Path,
+    manifest_dir: &path::Path,
+) {
     if !cfg!(feature = "runtime") {
         return;
     }
     let bindgen_path = path::PathBuf::from(format!("{}/runtime_sys.rs", outdir.display()));
-    let header = "build/runtime_wrapper.h";
+    let header = manifest_dir.join("build/runtime_wrapper.h");
+    println!("cargo::rerun-if-changed={}", header.display());
     let bindings = bindgen::Builder::default()
-        .header(header)
+        .header(header.to_str().expect("header should be valid UTF-8"))
         .parse_callbacks(Box::new(callbacks::FunctionRenames::new(
             "cuda",
             outdir,
@@ -187,7 +201,7 @@ fn create_cuda_runtime_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
         .expect("Cannot write CUDA runtime bindgen output to file.");
 }
 
-fn create_cublas_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
+fn create_cublas_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path, manifest_dir: &path::Path) {
     #[rustfmt::skip]
     let params = &[
         (cfg!(feature = "cublas"), "cublas", "^cublas.*", "^CUBLAS.*"),
@@ -199,9 +213,10 @@ fn create_cublas_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
             continue;
         }
         let bindgen_path = path::PathBuf::from(format!("{}/{pkg}_sys.rs", outdir.display()));
-        let header = format!("build/{pkg}_wrapper.h");
+        let header = manifest_dir.join(format!("build/{pkg}_wrapper.h"));
+        println!("cargo::rerun-if-changed={}", header.display());
         let bindings = bindgen::Builder::default()
-            .header(&header)
+            .header(header.to_str().expect("header should be valid UTF-8"))
             .parse_callbacks(Box::new(callbacks::FunctionRenames::new(
                 pkg,
                 outdir,
@@ -235,13 +250,19 @@ fn create_cublas_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
     }
 }
 
-fn create_nptx_compiler_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
+fn create_nptx_compiler_bindings(
+    sdk: &cuda_sdk::CudaSdk,
+    outdir: &path::Path,
+    manifest_dir: &path::Path,
+) {
     if !cfg!(feature = "nvptx-compiler") {
         return;
     }
     let bindgen_path = path::PathBuf::from(format!("{}/nvptx_compiler_sys.rs", outdir.display()));
+    let header = manifest_dir.join("build/nvptx_compiler_wrapper.h");
+    println!("cargo::rerun-if-changed={}", header.display());
     let bindings = bindgen::Builder::default()
-        .header("build/nvptx_compiler_wrapper.h")
+        .header(header.to_str().expect("header should be valid UTF-8"))
         .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
         .clang_args(
             sdk.cuda_include_paths()
@@ -268,13 +289,15 @@ fn create_nptx_compiler_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
         .expect("Cannot write nvptx-compiler bindgen output to file.");
 }
 
-fn create_nvvm_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path) {
+fn create_nvvm_bindings(sdk: &cuda_sdk::CudaSdk, outdir: &path::Path, manifest_dir: &path::Path) {
     if !cfg!(feature = "nvvm") {
         return;
     }
     let bindgen_path = path::PathBuf::from(format!("{}/nvvm_sys.rs", outdir.display()));
+    let header = manifest_dir.join("build/nvvm_wrapper.h");
+    println!("cargo::rerun-if-changed={}", header.display());
     let bindings = bindgen::Builder::default()
-        .header("build/nvvm_wrapper.h")
+        .header(header.to_str().expect("header should be valid UTF-8"))
         .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
         .clang_args(
             sdk.nvvm_include_paths()
diff --git a/examples/cuda/gemm/build.rs b/examples/cuda/gemm/build.rs
index 9dfb16af..7f23bac1 100644
--- a/examples/cuda/gemm/build.rs
+++ b/examples/cuda/gemm/build.rs
@@ -8,7 +8,9 @@ fn main() {
     println!("cargo::rerun-if-changed=kernels");
 
     let out_path = path::PathBuf::from(env::var("OUT_DIR").unwrap());
-    CudaBuilder::new("kernels")
+    let manifest_dir = path::PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
+
+    CudaBuilder::new(manifest_dir.join("kernels"))
         .copy_to(out_path.join("kernels.ptx"))
         .build()
         .unwrap();
diff --git a/examples/cuda/path_tracer/build.rs b/examples/cuda/path_tracer/build.rs
index da3f5a50..b2bd7712 100644
--- a/examples/cuda/path_tracer/build.rs
+++ b/examples/cuda/path_tracer/build.rs
@@ -4,12 +4,17 @@ use std::path;
 use cuda_builder::CudaBuilder;
 
 fn main() {
+    println!("cargo::rerun-if-changed=build.rs");
+    println!("cargo::rerun-if-changed=kernels");
+
     let out_path = path::PathBuf::from(env::var("OUT_DIR").unwrap());
-    CudaBuilder::new("kernels")
+    let manifest_dir = path::PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
+
+    CudaBuilder::new(manifest_dir.join("kernels"))
         .copy_to(out_path.join("kernels.ptx"))
         .build()
         .unwrap();
-    CudaBuilder::new("kernels")
+    CudaBuilder::new(manifest_dir.join("kernels"))
         .copy_to(out_path.join("kernels_optix.ptx"))
         .build_args(&["--features", "optix"])
         .build()
diff --git a/examples/cuda/vecadd/build.rs b/examples/cuda/vecadd/build.rs
index 2046e342..7f23bac1 100644
--- a/examples/cuda/vecadd/build.rs
+++ b/examples/cuda/vecadd/build.rs
@@ -4,11 +4,13 @@ use std::path;
 use cuda_builder::CudaBuilder;
 
 fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-changed=kernels");
+    println!("cargo::rerun-if-changed=build.rs");
+    println!("cargo::rerun-if-changed=kernels");
 
     let out_path = path::PathBuf::from(env::var("OUT_DIR").unwrap());
-    CudaBuilder::new("kernels")
+    let manifest_dir = path::PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
+
+    CudaBuilder::new(manifest_dir.join("kernels"))
         .copy_to(out_path.join("kernels.ptx"))
         .build()
         .unwrap();