use std::{ borrow::Borrow, env, ffi::OsStr, fs, path::{Path, PathBuf}, process::Command, }; fn main() { let we_created = if !Path::new("r8brain/LICENSE").exists() { eprintln!("Setting up submodules"); run_command_or_fail(".", "git", &["clone", "https://github.com/avaneev/r8brain-free-src.git", "r8brain"]); run_command_or_fail("r8brain", "git", &["checkout", "234e71462f781032c078e8f197cd427ec3c2dfb9"]); true } else { false }; if !Path::new("r8brain/LICENSE").exists() { panic!("Submodules not found"); } let mut dst = cmake::Config::new(".").build_target("r8brain").build(); println!("cargo:rustc-link-search=native={}", dst.display()); dst.push("build"); println!("cargo:rustc-link-search=native={}", dst.display()); dst.push(env::var("PROFILE").expect("Profile must be specified")); println!("cargo:rustc-link-search=native={}", dst.display()); println!("cargo:rustc-link-lib=static=r8brain"); let target = env::var("TARGET").unwrap(); if target.contains("apple") { println!("cargo:rustc-link-lib=dylib=c++"); } else if target.contains("linux") { println!("cargo:rustc-link-lib=dylib=stdc++"); } if we_created { fs::remove_dir_all("r8brain").expect("Failed to remove r8brain"); } } // thank you rdkafka-sys for this code fn run_command_or_fail(dir: &str, cmd: P, args: &[S]) where P: AsRef, S: Borrow + AsRef { let cmd = cmd.as_ref(); let cmd = if cmd.components().count() > 1 && cmd.is_relative() { // If `cmd` is a relative path (and not a bare command that should be // looked up in PATH), absolutize it relative to `dir`, as otherwise the // behavior of std::process::Command is undefined. // https://github.com/rust-lang/rust/issues/37868 PathBuf::from(dir).join(cmd).canonicalize().expect("canonicalization failed") } else { PathBuf::from(cmd) }; eprintln!("Running command: \"{} {}\" in dir: {}", cmd.display(), args.join(" "), dir); let ret = Command::new(cmd).current_dir(dir) .args(args) .stderr(std::process::Stdio::inherit()) .stdout(std::process::Stdio::inherit()) .status(); match ret.map(|status| (status.success(), status.code())) { | Ok((true, _)) => eprintln!("Command succeeded"), | Ok((false, Some(c))) => panic!("Command failed with error code {}", c), | Ok((false, None)) => panic!("Command got killed"), | Err(e) => panic!("Command failed with error: {}", e), } }