use std::env;
use std::error::Error;
use std::fs;
use std::path::PathBuf;
fn get_bazel_library_version(library_name: &str) -> String {
let output: std::process::Output = std::process::Command::new("bazel")
.arg("mod")
.arg("explain")
.output()
.expect("Failed to execute 'bazel mod explain'");
let process_output: String = String::from_utf8_lossy(&output.stdout).to_string();
let library_token: String = library_name.to_owned() + "@";
let mut process_output_lines: std::str::Lines = process_output.lines();
let line_index: usize = process_output_lines
.position(|line| line.contains(&library_token))
.expect("Couldn't find the library");
let mut library_version: &str = process_output
.lines()
.nth(line_index)
.expect("Failed to retrieve the line from the process output.")
.split('@')
.last()
.expect("Failed to retrieve library version.")
.trim(); if library_version == "_" {
library_version = "override";
}
String::from(library_version)
}
fn main() -> Result<(), Box<dyn Error>> {
println!("cargo:rerun-if-changed=src/lib.rs");
println!("cargo:rerun-if-changed=.bazelrc");
println!("cargo:rerun-if-changed=BUILD.bazel");
println!("cargo:rerun-if-changed=MODULE.bazel");
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let bazel_output_base_dir = out_dir.join("bazel_output_base");
fs::create_dir_all(&bazel_output_base_dir)?;
let jobs = env::var("NUM_JOBS").unwrap().to_string();
let code = std::process::Command::new("bazel")
.arg(format!("--output_base={}", bazel_output_base_dir.display()))
.arg("build")
.arg(format!(
"--symlink_prefix={}",
bazel_output_base_dir.join("bazel-").display()
))
.arg(format!("--jobs={}", jobs))
.arg("//...")
.status()
.expect("Failed to generate build script");
if code.code() != Some(0) {
panic!("Failed to generate build script");
}
let bazel_bin_dir = bazel_output_base_dir.join("bazel-bin");
let maliput_version = get_bazel_library_version("maliput");
println!("Detected maliput version: <{}>", maliput_version);
let maliput_bin_path = bazel_bin_dir
.join("external")
.join(format!("maliput~{}", maliput_version));
let maliput_malidrive_version = get_bazel_library_version("maliput_malidrive");
println!("Detected maliput_malidrive version: <{}>", maliput_malidrive_version);
let maliput_malidrive_bin_path = bazel_bin_dir
.join("external")
.join(format!("maliput_malidrive~{}", maliput_malidrive_version));
let virtual_includes_path = maliput_bin_path.join("_virtual_includes");
let mut virtual_includes = Vec::new();
for entry in fs::read_dir(virtual_includes_path)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
virtual_includes.push(path);
}
}
for (i, path) in virtual_includes.iter().enumerate() {
println!("cargo:CXXBRIDGE_DIR{}={}", i, path.display());
}
let maliput_malidrive_resource_path = bazel_bin_dir
.join("libmaliput_sdk.so.runfiles")
.join(String::from("maliput_malidrive~") + &maliput_malidrive_version)
.join("resources");
println!("cargo:rustc-env=MALIPUT_BIN_PATH={}", maliput_bin_path.display());
println!(
"cargo:rustc-env=MALIPUT_MALIDRIVE_BIN_PATH={}",
maliput_malidrive_bin_path.display()
);
println!(
"cargo:rustc-env=MALIPUT_MALIDRIVE_PLUGIN_PATH={}",
maliput_malidrive_bin_path.join("maliput_plugins").display()
);
println!(
"cargo:rustc-env=MALIPUT_MALIDRIVE_RESOURCE_PATH={}",
maliput_malidrive_resource_path.display()
);
println!("cargo:root={}", out_dir.display()); println!("cargo:maliput_bin_path={}", maliput_bin_path.display()); println!(
"cargo:maliput_malidrive_bin_path={}",
maliput_malidrive_bin_path.display()
); println!(
"cargo:maliput_malidrive_plugin_path={}",
maliput_malidrive_bin_path.join("maliput_plugins").display()
);
Ok(())
}