Function getExternalExecutor [src]

Return whether or not the given host is capable of running executables of the other target.

Prototype

pub fn getExternalExecutor( host: std.Target, candidate: *const std.Target, options: GetExternalExecutorOptions, ) Executor

Parameters

host: std.Targetcandidate: *const std.Targetoptions: GetExternalExecutorOptions

Source

pub fn getExternalExecutor( host: std.Target, candidate: *const std.Target, options: GetExternalExecutorOptions, ) Executor { const os_match = host.os.tag == candidate.os.tag; const cpu_ok = cpu_ok: { if (host.cpu.arch == candidate.cpu.arch) break :cpu_ok true; if (host.cpu.arch == .x86_64 and candidate.cpu.arch == .x86) break :cpu_ok true; if (host.cpu.arch == .aarch64 and candidate.cpu.arch == .arm) break :cpu_ok true; if (host.cpu.arch == .aarch64_be and candidate.cpu.arch == .armeb) break :cpu_ok true; // TODO additionally detect incompatible CPU features. // Note that in some cases the OS kernel will emulate missing CPU features // when an illegal instruction is encountered. break :cpu_ok false; }; var bad_result: Executor = .bad_os_or_cpu; if (os_match and cpu_ok) native: { if (options.link_libc) { if (candidate.dynamic_linker.get()) |candidate_dl| { fs.cwd().access(candidate_dl, .{}) catch { bad_result = .{ .bad_dl = candidate_dl }; break :native; }; } } return .native; } // If the OS match and OS is macOS and CPU is arm64, we can use Rosetta 2 // to emulate the foreign architecture. if (options.allow_rosetta and os_match and host.os.tag == .macos and host.cpu.arch == .aarch64) { switch (candidate.cpu.arch) { .x86_64 => return .rosetta, else => return bad_result, } } // If the OS matches, we can use QEMU to emulate a foreign architecture. if (options.allow_qemu and os_match and (!cpu_ok or options.qemu_fixes_dl)) { return switch (candidate.cpu.arch) { .aarch64 => Executor{ .qemu = "qemu-aarch64" }, .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" }, .arm, .thumb => Executor{ .qemu = "qemu-arm" }, .armeb, .thumbeb => Executor{ .qemu = "qemu-armeb" }, .hexagon => Executor{ .qemu = "qemu-hexagon" }, .loongarch64 => Executor{ .qemu = "qemu-loongarch64" }, .m68k => Executor{ .qemu = "qemu-m68k" }, .mips => Executor{ .qemu = "qemu-mips" }, .mipsel => Executor{ .qemu = "qemu-mipsel" }, .mips64 => Executor{ .qemu = switch (candidate.abi) { .gnuabin32, .muslabin32 => "qemu-mipsn32", else => "qemu-mips64", }, }, .mips64el => Executor{ .qemu = switch (candidate.abi) { .gnuabin32, .muslabin32 => "qemu-mipsn32el", else => "qemu-mips64el", }, }, .powerpc => Executor{ .qemu = "qemu-ppc" }, .powerpc64 => Executor{ .qemu = "qemu-ppc64" }, .powerpc64le => Executor{ .qemu = "qemu-ppc64le" }, .riscv32 => Executor{ .qemu = "qemu-riscv32" }, .riscv64 => Executor{ .qemu = "qemu-riscv64" }, .s390x => Executor{ .qemu = "qemu-s390x" }, .sparc => Executor{ .qemu = if (std.Target.sparc.featureSetHas(candidate.cpu.features, .v9)) "qemu-sparc32plus" else "qemu-sparc", }, .sparc64 => Executor{ .qemu = "qemu-sparc64" }, .x86 => Executor{ .qemu = "qemu-i386" }, .x86_64 => switch (candidate.abi) { .gnux32, .muslx32 => return bad_result, else => Executor{ .qemu = "qemu-x86_64" }, }, .xtensa => Executor{ .qemu = "qemu-xtensa" }, else => return bad_result, }; } switch (candidate.os.tag) { .windows => { if (options.allow_wine) { // x86_64 wine does not support emulating aarch64-windows and // vice versa. if (candidate.cpu.arch != builtin.cpu.arch and !(candidate.cpu.arch == .thumb and builtin.cpu.arch == .aarch64) and !(candidate.cpu.arch == .x86 and builtin.cpu.arch == .x86_64)) { return bad_result; } switch (candidate.ptrBitWidth()) { 32 => return Executor{ .wine = "wine" }, 64 => return Executor{ .wine = "wine64" }, else => return bad_result, } } return bad_result; }, .wasi => { if (options.allow_wasmtime) { switch (candidate.ptrBitWidth()) { 32 => return Executor{ .wasmtime = "wasmtime" }, else => return bad_result, } } return bad_result; }, .macos => { if (options.allow_darling) { // This check can be loosened once darling adds a QEMU-based emulation // layer for non-host architectures: // https://github.com/darlinghq/darling/issues/863 if (candidate.cpu.arch != builtin.cpu.arch) { return bad_result; } return Executor{ .darling = "darling" }; } return bad_result; }, else => return bad_result, } }