Cross-compiling to bare-metal x86 with build.rs fails on aarch64 host

Hello everyone,

I seem to be encountering some issues with cross-compiling bare-metal Rust from my M3 Mac to x86_64, when building with build.rs.

This is the error I get when try compiling with cargo build --target x86_64-unknown-none:

   Compiling two v0.1.0 (/Users/user/dev/two)
The following warnings were emitted during compilation:

warning: two@0.1.0: error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: can't open file: /Users/user/dev/two/target/x86_64-unknown-none/debug/build/two-12e52249957c2a35/out/libtwo.a (No such file or directory)
warning: two@0.1.0: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar: internal ranlib command failed

error: failed to run custom build command for `two v0.1.0 (/Users/user/dev/two)`

Caused by:
  process didn't exit successfully: `/Users/user/dev/two/target/debug/build/two-7c4fde09e1578573/build-script-build` (exit status: 1)
  --- stdout
  OUT_DIR = Some(/Users/user/dev/two/target/x86_64-unknown-none/debug/build/two-12e52249957c2a35/out)
  TARGET = Some(x86_64-unknown-none)
  HOST = Some(aarch64-apple-darwin)
  cargo:rerun-if-env-changed=AR_x86_64-unknown-none
  AR_x86_64-unknown-none = None
  cargo:rerun-if-env-changed=AR_x86_64_unknown_none
  AR_x86_64_unknown_none = None
  cargo:rerun-if-env-changed=TARGET_AR
  TARGET_AR = None
  cargo:rerun-if-env-changed=AR
  AR = None
  cargo:rerun-if-env-changed=CROSS_COMPILE
  CROSS_COMPILE = None
  RUSTC_LINKER = None
  cargo:rerun-if-env-changed=ARFLAGS_x86_64-unknown-none
  ARFLAGS_x86_64-unknown-none = None
  cargo:rerun-if-env-changed=ARFLAGS_x86_64_unknown_none
  ARFLAGS_x86_64_unknown_none = None
  cargo:rerun-if-env-changed=TARGET_ARFLAGS
  TARGET_ARFLAGS = None
  cargo:rerun-if-env-changed=ARFLAGS
  ARFLAGS = None
  cargo:rerun-if-env-changed=CC_ENABLE_DEBUG_OUTPUT
  cargo:warning=error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: can't open file: /Users/user/dev/two/target/x86_64-unknown-none/debug/build/two-12e52249957c2a35/out/libtwo.a (No such file or directory)
  cargo:warning=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar: internal ranlib command failed

  --- stderr


  error occurred: Command "ar" "s" "/Users/user/dev/two/target/x86_64-unknown-none/debug/build/two-12e52249957c2a35/out/libtwo.a" with args ar did not execute successfully (status code exit status: 1).

This is my build.rs:

use cc;
use std::{env, fs, path};

fn add_files_to_build(build: &mut cc::Build, path: &path::PathBuf) {
    if path.is_dir() && !path.is_symlink() {
        let entries = match fs::read_dir(path) {
            Ok(entries) => entries,
            Err(_) => return,
        };

        for entry in entries {
            let unwrapped_entry = match entry {
                Ok(entry) => entry,
                Err(_) => continue,
            };

            let entry_path = unwrapped_entry.path();

            if entry_path.is_dir() && !entry_path.is_symlink() {
                add_files_to_build(build, &entry_path);
                continue;
            }

            let file_extension = match entry_path.extension() {
                Some(ext) => ext,
                None => continue,
            };

            if entry_path.is_file() && (file_extension == "s" || file_extension == "c") {
                println!("cargo::rerun-if-changed={}", entry_path.to_str().unwrap());
                build.file(entry_path);
            }
        }
    }
}

fn find_all_casm(build: &mut cc::Build) {
    let mut valid_dirs: Vec<&str> = Vec::from(["src/kernel"]);

    if env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "aarch64" {
        valid_dirs.push("src/arch/aarch64/common");
    } else {
        valid_dirs.push("src/arch/x86_64");
    };

    #[cfg(feature = "bcm2711")]
    {
        valid_dirs.push("src/arch/aarch64/boards/bcm/common");
        valid_dirs.push("src/arch/aarch64/boards/bcm/bcm2711");
    }

    for dir in valid_dirs {
        add_files_to_build(build, &path::Path::new(dir).to_path_buf());
    }
}

fn main() {
    let mut cc_build = cc::Build::new();

    if env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "aarch64" {
        println!("cargo::rerun-if-changed=src/arch/aarch64/common/boot/boot.s");
        cc_build.file("src/arch/aarch64/common/boot/boot.s");

        println!("cargo::rustc-link-arg=-T./src/arch/x86_64/linker.ld");
        cc_build.flag("-T ./src/arch/x86_64/linker.ld");
    }

    #[cfg(feature = "bcm2711")]
    {
        println!("cargo::rustc-link-arg=-T./src/arch/aarch64/boards/bcm/bcm2711/linker.ld");
        cc_build.flag("-T ./src/arch/aarch64/boards/bcm/bcm2711/linker.ld");
    }

    find_all_casm(&mut cc_build);

    cc_build.compile("two")
}

In my build.rs I'm compiling everything depending on architectures and boards. I have both x86_64 and aarch64 cross-compilers installed.

I checked and ar and newlib seem to be failing due to target/x86_64-unknown-none/debug/build/two-12e52249957c2a35/out/libtwo.a not existing as the error says.

Thanks for the help!

Update:
When building on an x86_64 machine it seems to be failing with the same reason as well.