#![allow(unreachable_code)]
use std::{env, path::PathBuf};
pub fn main() {
if std::env::var("DOCS_RS").is_ok() {
return;
}
#[cfg(all(target_os = "macos", feature = "cuda"))]
panic!("The feature `cuda` is not available on macOS.");
#[cfg(all(not(target_os = "macos"), feature = "metal"))]
panic!("The feature `metal` is only available on macOS.");
let mut open_subdiv = cmake::Config::new("OpenSubdiv");
open_subdiv
.always_configure(true)
.define("NO_EXAMPLES", "1")
.define("NO_TUTORIALS", "1")
.define("NO_REGRESSION", "1")
.define("NO_PTEX", "1")
.define("NO_DOC", "1")
.define("NO_GLFW", "1")
.define("NO_OPENGL", "1") .define("NO_DX", "1") .define("CMAKE_CXX_STANDARD", "14");
#[cfg(not(feature = "cuda"))]
open_subdiv.define("NO_CUDA", "1");
#[cfg(feature = "cuda")]
{
if std::process::Command::new("gcc-12")
.arg("--version")
.output()
.is_ok()
{
open_subdiv
.define("OSD_CUDA_NVCC_FLAGS", "-ccbin gcc-12")
.env("NVCC_PREPEND_FLAGS", "-ccbin /usr/bin/g++-12")
.env("CUDAHOSTCXX", "/usr/bin/g++-12");
} else {
open_subdiv.define("OSD_CUDA_NVCC_FLAGS",
"-allow-unsupported-compiler -D_Float32=float -D_Float64=double -D_Float32x=float -D_Float64x=\"long double\" -D_Float128=\"long double\"");
}
}
#[cfg(not(feature = "tbb"))]
open_subdiv.define("NO_TBB", "1");
#[cfg(not(feature = "opencl"))]
{
open_subdiv.define("NO_OPENCL", "1");
open_subdiv.define("NO_CLEW", "1");
}
#[cfg(any(target_os = "macos", not(feature = "openmp")))]
open_subdiv.define("NO_OMP", "1");
#[cfg(any(not(target_os = "macos"), not(feature = "metal")))]
open_subdiv.define("NO_METAL", "1");
let open_subdiv = open_subdiv.build();
let osd_inlude_path = open_subdiv.join("include");
let osd_lib_path = open_subdiv.join("lib");
let mut osd_capi = cc::Build::new();
if let Ok(cxxflags) = env::var("CXXFLAGS")
&& cxxflags.contains("-stdlib=libc++")
{
osd_capi.flag("-stdlib=libc++");
}
osd_capi
.include(&osd_inlude_path)
.include("OpenSubdiv") .cpp(true)
.flag("-std=c++14")
.flag("-Wno-return-type-c-linkage")
.file("c-api/far/primvar_refiner.cpp")
.file("c-api/far/stencil_table.cpp")
.file("c-api/far/stencil_table_factory.cpp")
.file("c-api/far/limit_stencil_table.cpp")
.file("c-api/far/topology_refiner.cpp")
.file("c-api/far/topology_level.cpp")
.file("c-api/far/patch_table.cpp")
.file("c-api/far/patch_evaluator.cpp")
.file("c-api/bfr/surface_factory.cpp")
.file("c-api/osd/cpu_evaluator.cpp")
.file("c-api/osd/cpu_vertex_buffer.cpp");
#[cfg(all(feature = "openmp", not(target_os = "macos")))]
osd_capi.file("c-api/osd/omp_evaluator.cpp");
#[cfg(all(feature = "cuda", not(target_os = "macos")))]
osd_capi
.include(&osd_inlude_path)
.file("c-api/osd/cuda_evaluator.cpp")
.file("c-api/osd/cuda_vertex_buffer.cpp");
#[cfg(all(feature = "metal", target_os = "macos"))]
osd_capi
.include(&osd_inlude_path)
.file("c-api/osd/metal_evaluator.cpp")
.file("c-api/osd/metal_vertex_buffer.cpp");
#[cfg(feature = "opencl")]
osd_capi
.include(&osd_inlude_path)
.file("c-api/osd/opencl_evaluator.cpp")
.file("c-api/osd/opencl_vertex_buffer.cpp");
#[cfg(feature = "tbb")]
osd_capi
.include(&osd_inlude_path)
.file("c-api/osd/tbb_evaluator.cpp");
osd_capi.compile("osd-capi");
println!("cargo:rustc-link-lib=static=osd-capi");
println!("cargo:rustc-link-search=native={}", osd_lib_path.display());
println!("cargo:rustc-link-lib=static=osdCPU");
#[cfg(all(feature = "openmp", not(target_os = "macos")))]
println!("cargo:rustc-link-lib=static=osdOMP");
#[cfg(feature = "tbb")]
println!("cargo:rustc-link-lib=dylib=tbb");
#[cfg(feature = "cuda")]
{
println!("cargo:rustc-link-lib=static=osdGPU");
if std::path::Path::new("/usr/local/cuda/lib64").exists() {
println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64");
} else if std::path::Path::new("/usr/lib/x86_64-linux-gnu/libcudart.so").exists() {
println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu");
}
println!("cargo:rustc-link-lib=dylib=cudart");
}
#[cfg(feature = "metal")]
{
println!("cargo:rustc-link-lib=static=osdGPU");
println!("cargo:rustc-link-lib=framework=Metal");
println!("cargo:rustc-link-lib=framework=Foundation");
}
#[cfg(feature = "opencl")]
{
println!("cargo:rustc-link-lib=static=osdGPU");
println!("cargo:rustc-link-lib=dylib=OpenCL");
}
#[cfg(target_os = "linux")]
{
if let Ok(cxxflags) = env::var("CXXFLAGS") {
if cxxflags.contains("-stdlib=libc++") {
println!("cargo:rustc-link-lib=dylib=c++");
println!("cargo:rustc-link-lib=dylib=c++abi");
} else {
println!("cargo:rustc-link-lib=dylib=stdc++");
}
} else {
println!("cargo:rustc-link-lib=dylib=stdc++");
}
}
#[cfg(target_os = "macos")]
println!("cargo:rustc-link-lib=dylib=c++");
println!("cargo:rerun-if-changed=wrapper.hpp");
let bindings = bindgen::Builder::default()
.header("wrapper.hpp")
.clang_arg("-IOpenSubdiv")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.allowlist_function("PatchTableFactory_.*")
.allowlist_function("PatchTable_.*")
.allowlist_function("PatchDescriptor_.*")
.allowlist_function("PatchParam_.*")
.allowlist_type("OpenSubdiv.*")
.blocklist_type("std::.*")
.blocklist_type(".*StencilTableReal.*")
.blocklist_type(".*LimitStencilTableReal.*")
.blocklist_type(".*_BaseTable")
.blocklist_type(".*StencilTableFactory.*")
.blocklist_type(".*StencilTableF")
.blocklist_type(".*StencilTableD")
.blocklist_type(".*StencilTablePtr.*")
.blocklist_type(".*PatchTable_StencilTablePtr.*")
.blocklist_type(".*PatchTableBuilder.*")
.opaque_type("std::.*")
.opaque_type("OpenSubdiv_v3_7_0_Far_PatchTable")
.derive_partialeq(true)
.derive_eq(true)
.derive_hash(true)
.derive_debug(true)
.layout_tests(false);
let mut bindings = bindings.clang_arg("-xc++").clang_arg("-std=c++14");
if let Ok(cxxflags) = env::var("CXXFLAGS")
&& cxxflags.contains("-stdlib=libc++")
{
bindings = bindings.clang_arg("-stdlib=libc++");
}
let out_path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let bindings = bindings
.clang_args(&["-F", osd_inlude_path.to_str().unwrap()])
.generate()
.expect("Unable to generate bindings");
let bindings_path = out_path.join("bindings.rs");
bindings
.write_to_file(bindings_path)
.expect("Couldn't write bindings");
println!("cargo:rerun-if-changed=build.rs");
}