use std::env;
use std::error::Error;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
fn get_bazel_library_version(library_name: &str) -> String {
let output: Output = 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('@')
.next_back()
.expect("Failed to retrieve library version.")
.trim(); if library_version == "_" {
library_version = "override";
}
String::from(library_version)
}
fn resolve_bazel_package_path(
bazel_bin_dir: &Path,
subdir: &str,
crate_name: &str,
version: &str,
postfix_path: Option<&str>,
) -> PathBuf {
let base_path = bazel_bin_dir.join(subdir);
let try_path = |suffix: String| {
let mut path = base_path.join(suffix);
if let Some(postfix) = postfix_path {
path = path.join(postfix);
}
path
};
let plus_path = try_path(format!("{}+", crate_name));
if plus_path.exists() {
return plus_path;
}
let tilde_path = try_path(format!("{}~{}", crate_name, version));
if tilde_path.exists() {
return tilde_path;
}
panic!(
"Could not resolve Bazel path for `{}` using either '+' or '~{}'",
crate_name, 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 = 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("--macos_minimum_os=10.15")
.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!("cargo:info=maliput version: <{}>", maliput_version);
let maliput_bin_path = resolve_bazel_package_path(&bazel_bin_dir, "external", "maliput", &maliput_version, None);
let maliput_malidrive_version = get_bazel_library_version("maliput_malidrive");
println!("cargo:info=maliput_malidrive version: <{}>", maliput_malidrive_version);
let maliput_malidrive_bin_path = resolve_bazel_package_path(
&bazel_bin_dir,
"external",
"maliput_malidrive",
&maliput_malidrive_version,
None,
);
println!("cargo:info=maliput_bin_path: {:?}", maliput_bin_path);
println!(
"cargo:info=maliput_malidrive_bin_path: {:?}",
maliput_malidrive_bin_path
);
let virtual_includes_path = maliput_bin_path.join("_virtual_includes");
println!("{:?}", virtual_includes_path);
let mut virtual_includes = Vec::new();
for entry in fs::read_dir(virtual_includes_path)? {
println!("{:?}", entry);
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 lib_dir = if cfg!(target_os = "macos") {
"libmaliput_malidrive_dummy.dylib.runfiles"
} else if cfg!(target_os = "linux") {
"libmaliput_malidrive_dummy.so.runfiles"
} else {
"maliput_malidrive_dummy.dll.runfiles"
};
let maliput_malidrive_resource_path = resolve_bazel_package_path(
&bazel_bin_dir,
lib_dir,
"maliput_malidrive",
&maliput_malidrive_version,
Some("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:bin_path={}", bazel_bin_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(())
}