use std::process::Command; use std::env; use std::path::Path; fn main() { if !Command::new("git").args(&["submodule", "update", "--init", "--recursive"]).status().unwrap().success() { panic!("git failed to init submodules"); } if !Command ::new("mkdir").args(&["-p", ".build"]) .current_dir(&Path::new("c")).status().unwrap().success() { panic!("failed to create a directory to track build progress"); } let out_dir = &env::var("OUT_DIR").unwrap(); // Use a file to signal if Monero was already built, as that should never be rebuilt // If the signaling file was deleted, run this script again to rebuild Monero though // TODO: Move this signaling file into OUT_DIR once Monero is built statically successfully println!("cargo:rerun-if-changed=c/.build/monero"); if !Path::new("c/.build/monero").exists() { if !Command::new("cmake").args(&["cmake", "-DCMAKE_BUILD_TYPE=Release", "-DBUILD_SHARED_LIBS=1", "."]) .current_dir(&Path::new("c/monero")).status().unwrap().success() { panic!("cmake failed to generate Monero's build scripts"); } if !Command::new("make").arg(format!("-j{}", &env::var("THREADS").unwrap_or("2".to_string()))) .current_dir(&Path::new("c/monero")).status().unwrap().success() { panic!("make failed to build Monero. Please check your dependencies"); } if !Command::new("touch").arg("monero") .current_dir(&Path::new("c/.build")).status().unwrap().success() { panic!("failed to create a file to label Monero as built"); } } println!("cargo:rerun-if-env-changed=OUT_DIR"); if !Path::new( &format!( "{}/{}cncrypto.{}", out_dir, &env::consts::DLL_PREFIX, &env::consts::DLL_EXTENSION ) ).exists() { for (folder, lib) in [ ("crypto", "cncrypto"), ("device", "device"), ("ringct", "ringct_basic"), ("ringct", "ringct") ] { if !Command::new("cp").args(&[ &format!( "c/monero/src/{}/{}{}.{}", folder, &env::consts::DLL_PREFIX, lib, &env::consts::DLL_EXTENSION ), out_dir ]).status().unwrap().success() { panic!("Failed to cp {}", lib); } } } println!("cargo:rerun-if-changed=c/wrapper.cpp"); if !Command::new("g++").args(&[ "-O3", "-Wall", "-shared", "-std=c++14", "-fPIC", "-Imonero/contrib/epee/include", "-Imonero/src", "wrapper.cpp", "-o", &format!( "{}/{}wrapper.{}", out_dir, &env::consts::DLL_PREFIX, &env::consts::DLL_EXTENSION ), &format!("-L{}", out_dir), "-ldevice", "-lringct_basic", "-lringct" ]).current_dir(&Path::new("c")).status().unwrap().success() { panic!("g++ failed to build the wrapper"); } println!("cargo:rustc-link-search={}", out_dir); println!("cargo:rustc-link-lib=cncrypto"); println!("cargo:rustc-link-lib=device"); println!("cargo:rustc-link-lib=ringct_basic"); println!("cargo:rustc-link-lib=ringct"); println!("cargo:rustc-link-lib=wrapper"); }