Propagate linker failure (#4728)

* Propagate linker failure

* make sure we still write linker error

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Moritz HedtkeandJonathan Kelley authored and GitHub committed 2025-10-06 16:22:07 -07:00
1 parent bee89b795d
commit b35a52f337
3 files changed
+25 -8

No files matched your search

+18 -6
View File
@@ -1,7 +1,7 @@
use crate::Result;
use anyhow::Context;
use anyhow::{bail, Context};
use serde::{Deserialize, Serialize};
use std::{borrow::Cow, ffi::OsString, path::PathBuf};
use std::{borrow::Cow, ffi::OsString, path::PathBuf, process::ExitCode};
use target_lexicon::Triple;
/// `dx` can act as a linker in a few scenarios. Note that we don't *actually* implement the linker logic,
@@ -106,16 +106,20 @@ impl LinkAction {
Ok(())
}
pub(crate) fn run_link(self) {
pub(crate) fn run_link(self) -> ExitCode {
let link_err_file = self.link_err_file.clone();
let res = self.run_link_inner();
if let Err(err) = self.run_link_inner() {
eprintln!("Linker error: {err}");
if let Err(err) = res {
// If we failed to run the linker, we need to write the error to the file
// so that the main process can read it.
_ = std::fs::create_dir_all(link_err_file.parent().unwrap());
_ = std::fs::write(link_err_file, format!("Linker error: {err}"));
return ExitCode::FAILURE;
}
ExitCode::SUCCESS
}
/// Write the incoming linker args to a file
@@ -149,12 +153,20 @@ impl LinkAction {
};
let res = cmd.output().expect("Failed to run linker");
if !res.status.success() {
bail!(
"{}\n{}",
String::from_utf8_lossy(&res.stdout),
String::from_utf8_lossy(&res.stderr)
);
}
if !res.stderr.is_empty() || !res.stdout.is_empty() {
// Write linker warnings to file so that the main process can read them.
_ = std::fs::create_dir_all(self.link_err_file.parent().unwrap());
_ = std::fs::write(
self.link_err_file,
format!(
"Linker error: {}\n{}",
"Linker warnings: {}\n{}",
String::from_utf8_lossy(&res.stdout),
String::from_utf8_lossy(&res.stderr)
),
+5 -1
View File
@@ -24,6 +24,8 @@ mod wasm_bindgen;
mod wasm_opt;
mod workspace;
use std::process::ExitCode;
pub(crate) use build::*;
pub(crate) use cli::*;
pub(crate) use config::*;
@@ -39,7 +41,7 @@ pub(crate) use wasm_bindgen::*;
pub(crate) use workspace::*;
#[tokio::main]
async fn main() {
async fn main() -> ExitCode {
// The CLI uses dx as a rustcwrapper in some instances (like binary patching)
if rustcwrapper::is_wrapping_rustc() {
return rustcwrapper::run_rustc();
@@ -81,4 +83,6 @@ async fn main() {
output => tracing::info!(json = %output),
}
ExitCode::SUCCESS
}
+2 -1
View File
@@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
use std::{
env::{args, vars},
path::PathBuf,
process::ExitCode,
};
/// The environment variable indicating where the args file is located.
@@ -65,7 +66,7 @@ fn has_linking_args() -> bool {
/// Run rustc directly, but output the result to a file.
///
/// <https://doc.rust-lang.org/cargo/reference/config.html#buildrustc>
pub fn run_rustc() {
pub fn run_rustc() -> ExitCode {
// If we are being asked to link, delegate to the linker action.
if has_linking_args() {
return crate::link::LinkAction::from_env()