| |
1 use anyhow::bail; |
| |
2 use build_print::info; |
| |
3 use cc; |
| |
4 use conda_build::python_config; |
| |
5 use std::env; |
| |
6 use std::path::PathBuf; |
| |
7 |
| |
8 const NANOBIND_SOURCES: [&str; 7] = [ |
| |
9 "common.cpp", |
| |
10 "trampoline.cpp", |
| |
11 "nb_func.cpp", |
| |
12 "nb_type.cpp", |
| |
13 "nb_internals.cpp", |
| |
14 "error.cpp", |
| |
15 "implicit.cpp", |
| |
16 ]; |
| |
17 |
| |
18 fn main() -> Result<(), anyhow::Error> { |
| |
19 // Need to build it |
| |
20 let (pyc_e, py_conda) = python_config(); |
| |
21 |
| |
22 // This is very clumsy due to PythonConfig::Error not supporting |
| |
23 // conversion into std::error::Error, just std::io::Error. |
| |
24 let (pyc, mut includes, _py_ldflags) = pyc_e |
| |
25 .and_then(|pyc| { |
| |
26 pyc.include_paths() |
| |
27 .and_then(|ip| pyc.ldflags().map(|ld| (pyc, ip, ld))) |
| |
28 }) |
| |
29 .map_err(|e| anyhow::Error::from(std::io::Error::from(e)))?; |
| |
30 |
| |
31 let nanobind_root = pyc |
| |
32 .prefix_path().ok() |
| |
33 .zip(pyc.semantic_version().ok()) |
| |
34 .and_then(|(prefix, version)| { |
| |
35 info!("{}Python {} found at prefix {}", if py_conda { "Conda " } else { ""}, version, prefix.display()); |
| |
36 let nanobind_root = prefix |
| |
37 .join("lib") |
| |
38 .join(format!("python{}.{}", version.major, version.minor)) |
| |
39 .join("site-packages") |
| |
40 .join("nanobind"); |
| |
41 if !nanobind_root.exists() { |
| |
42 info!("… but no nanobind installed there"); |
| |
43 None |
| |
44 } else { |
| |
45 Some(nanobind_root) |
| |
46 } |
| |
47 }) |
| |
48 .map_or_else(|| { |
| |
49 let last_ditch = "/usr/share/nanobind"; |
| |
50 let nanobind_root = PathBuf::from(last_ditch); |
| |
51 if !nanobind_root.exists() { |
| |
52 bail!("Could not find nanobind in known locations. The recommended installation method is with pip at system Python location, or with Conda into the active environment. Also /usr/share/nanobind was attempted."); |
| |
53 } else { |
| |
54 info!("Found in {last_ditch}."); |
| |
55 Ok(nanobind_root) |
| |
56 } |
| |
57 }, Ok)?; |
| |
58 |
| |
59 let nanobind_src = nanobind_root.join("src"); |
| |
60 |
| |
61 println!("cargo:rerun-if-changed=build.rs"); |
| |
62 |
| |
63 //println!("cargo:rustc-link-arg={}", py_ldflags); |
| |
64 |
| |
65 includes.extend([ |
| |
66 nanobind_root.join("include"), |
| |
67 nanobind_root.join("ext/robin_map/include"), |
| |
68 ]); |
| |
69 |
| |
70 println!( |
| |
71 "cargo:include={}", |
| |
72 env::join_paths(&includes)?.into_string().unwrap() |
| |
73 ); |
| |
74 |
| |
75 cc::Build::new() |
| |
76 .std("c++20") |
| |
77 .files(NANOBIND_SOURCES.map(|f| nanobind_src.join(f))) |
| |
78 .includes(includes) |
| |
79 //.flags(pyc.cflags()?) |
| |
80 .compile("nanobind-sys"); |
| |
81 |
| |
82 Ok(()) |
| |
83 } |