How to cross-compile in the "new" Zig master?

Hello there,

after I finally found a way how I could implement a “framebuffer console” (with compiled-in 16x8 vga font) and I wanted to implement, I started my daily routine: First cd into $HOME/Executables/zig, then git pull, then build zig (master) with llvm, and then start development.
But well, when I just tested out the Zig compiler today, there seemed to be some changes to the Zig Build System.
There was the change of the cross-compiling API. The Zig Build System wanted Target.Query and Target for the Build.ResolvedTarget instead of just a Target.Query.
However, when I came up with the following code, LLVM greeted me with “64-bit code requested on a subtarget that doesn’t support it!”. My actual target was like the following:

    const bootloader_target = Target{
        .cpu = .{
            .arch = .x86_64,
            .model = Target.Cpu.Model.generic(.x86_64),
            .features = Target.Cpu.Feature.Set.empty,
        },
        .os = .{
            .tag = .uefi,
            .version_range = Target.Os.VersionRange.default(.uefi, .x86_64),
        },
        .abi = .msvc,
        .ofmt = .coff,
    };

And this error occurs for the bootloader and the kernel, so it has to do something with the .cpu.
What am I doing wrong?

The solution might be very simple, but I was not able to find it…

Looking forwards,
Samuel Fiedler

News on my problem: I was able to fix this by using Target.Cpu.baseline(.x86_64).
But now QEMU greets me with the following when the bootloader tries to get the memory map and to exit boot services.

!!!! X64 Exception Type - 06(#UD - Invalid Opcode)  CPU Apic ID - 00000000 !!!!
RIP  - 00000000061890A4, CS  - 0000000000000038, RFLAGS - 0000000000000046
RAX  - 0000000000000000, RCX - 0000000007EFA4E0, RDX - 0000000000000006
RBX  - 0000000000000000, RSP - 0000000007EFA340, RBP - 0000000007EFA340
RSI  - 0000000000000000, RDI - 00000000062A5D18
R8   - 00000000061924C1, R9  - 000000000000001E, R10 - 00000000076E6860
R11  - 000000009172BA06, R12 - 0000000000000000, R13 - 0000000006B5ECF0
R14  - 0000000000000000, R15 - 0000000007F131A0
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007801000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000075DC000 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007248018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007EF9FA0

What is the reason for that?

I think I can solve it now, it seemed to be a bug in the bootloader itself.

Check out the Upgrade Guide here: Move many settings from being per-Compilation to being per-Module by andrewrk · Pull Request #18160 · ziglang/zig · GitHub

In summary, I think you should use something like this:

const target = b.resolveTargetQuery(.{
    .cpu_arch = .x86_64,
    .os_tag = .uefi,
});

Then you can pass target to addExecutable and friends.

6 Likes

In case someone wants to target a more specific cpu. Here the is the target for the Raspberry Pi Zerov1

    const target = b.resolveTargetQuery(.{
        .abi = .eabihf,
        .cpu_arch = .arm,
        .os_tag = std.Target.Os.Tag.freestanding,
        .cpu_model = std.Target.Query.CpuModel{ .explicit = &std.Target.arm.cpu.arm1176jz_s },
    });