Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surface the failing command's name from the build error dump #253

Merged
merged 5 commits into from
Sep 20, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 42 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl Build {
}

#[cfg(windows)]
#[track_caller]
fn check_env_var(&self, var_name: &str) -> Option<bool> {
env::var_os(var_name).map(|s| {
if s == "1" {
Expand Down Expand Up @@ -121,7 +122,15 @@ impl Build {
false
}

#[track_caller]
pub fn build(&mut self) -> Artifacts {
match self.try_build() {
Ok(a) => a,
Err(e) => panic!("\n\n\n{e}\n\n\n"),
}
}

pub fn try_build(&mut self) -> Result<Artifacts, String> {
let target = &self.target.as_ref().expect("TARGET dir not set")[..];
let host = &self.host.as_ref().expect("HOST dir not set")[..];
let out_dir = self.out_dir.as_ref().expect("OUT_DIR not set");
Expand Down Expand Up @@ -574,24 +583,24 @@ impl Build {

// And finally, run the perl configure script!
configure.current_dir(&inner_dir);
self.run_command(configure, "configuring OpenSSL build");
self.run_command(configure, "configuring OpenSSL build")?;

// On MSVC we use `nmake.exe` with a slightly different invocation, so
// have that take a different path than the standard `make` below.
if target.contains("msvc") {
let mut build =
cc::windows_registry::find(target, "nmake.exe").expect("failed to find nmake");
build.arg("build_libs").current_dir(&inner_dir);
self.run_command(build, "building OpenSSL");
self.run_command(build, "building OpenSSL")?;

let mut install =
cc::windows_registry::find(target, "nmake.exe").expect("failed to find nmake");
install.arg("install_dev").current_dir(&inner_dir);
self.run_command(install, "installing OpenSSL");
self.run_command(install, "installing OpenSSL")?;
} else {
let mut depend = self.cmd_make();
depend.arg("depend").current_dir(&inner_dir);
self.run_command(depend, "building OpenSSL dependencies");
self.run_command(depend, "building OpenSSL dependencies")?;

let mut build = self.cmd_make();
build.arg("build_libs").current_dir(&inner_dir);
Expand All @@ -607,11 +616,11 @@ impl Build {
build.env("CROSS_SDK", components[1]);
}

self.run_command(build, "building OpenSSL");
self.run_command(build, "building OpenSSL")?;

let mut install = self.cmd_make();
install.arg("install_dev").current_dir(&inner_dir);
self.run_command(install, "installing OpenSSL");
self.run_command(install, "installing OpenSSL")?;
}

let libs = if target.contains("msvc") {
Expand All @@ -622,39 +631,47 @@ impl Build {

fs::remove_dir_all(&inner_dir).unwrap();

Artifacts {
Ok(Artifacts {
lib_dir: install_dir.join("lib"),
bin_dir: install_dir.join("bin"),
include_dir: install_dir.join("include"),
libs: libs,
target: target.to_string(),
}
})
}

fn run_command(&self, mut command: Command, desc: &str) {
#[track_caller]
fn run_command(&self, mut command: Command, desc: &str) -> Result<(), String> {
println!("running {:?}", command);
let status = command.status();

let (status_or_failed, error) = match status {
Ok(status) if status.success() => return,
Ok(status) => ("Exit status", format!("{}", status)),
Err(failed) => ("Failed to execute", format!("{}", failed)),
let verbose_error = match status {
Ok(status) if status.success() => return Ok(()),
Ok(status) => format!(
"'{exe}' reported failure with {status}",
exe = command.get_program().to_string_lossy()
),
Err(failed) => match failed.kind() {
std::io::ErrorKind::NotFound => format!(
"Command '{exe}' not found. Is {exe} installed?",
exe = command.get_program().to_string_lossy()
),
_ => format!(
"Could not run '{exe}', because {failed}",
exe = command.get_program().to_string_lossy()
),
},
};
panic!(
"


Error {}:
Command: {:?}
{}: {}


",
desc, command, status_or_failed, error
);
println!("cargo:warning={desc}: {verbose_error}");
Err(format!(
"Error {desc}:
{verbose_error}
Command failed: {command:?}"
))
}
}

#[track_caller]
fn cp_r(src: &Path, dst: &Path) {
for f in fs::read_dir(src).unwrap() {
let f = f.unwrap();
Expand Down