How can I export a binary output from my elf output as part of my Zig build process?
This should happen as part of the default build command zig build
.
I am using Zig 0.11.
My build.zig
contains the code below. I have added comments to describe what I think should be happening.
const std = @import("std");
const Builder = std.build.Builder;
pub fn build(b: *Builder) void {
const optimization = std.builtin.OptimizeMode.ReleaseFast;
const cpu_model = &std.Target.arm.cpu.cortex_m0;
// elf should be a build step that emits output.elf
const elf = b.addExecutable(.{
.name = "output.elf",
.root_source_file = .{ .path = "src/startup.zig" },
.target = .{
.cpu_arch = .thumb,
.os_tag = .freestanding,
.abi = .none,
.cpu_model = .{ .explicit = cpu_model },
},
.optimize = optimization,
});
elf.setLinkerScript(.{ .path = "src/STM32Z/MCU/STM32L052.ld" });
// bin should be a build step that objcopy's output.bin from output.elf
const bin = b.addObjCopy(.{ elf.getEmittedBin(), .{
.format = .bin,
});
// This step requires output.elf to exist
bin.step.dependOn(&elf.step);
// This is the step that I want to be completed when I run `zig build`.
// I would expect zig build to generate the elf and then the bin file
b.default_step = &bin.step;
}
This builds with no error at all. Yet a zig-out directory is not created, so I cannot find either output.elf
or output.bi
.
I'm not really clear on:
elf.getEmittedBin()
is the correct thing to pass into the b.addObjCopy
methodNot sure if this was the case in 2023, but the latest available now (0.14.0-dev.1713) you can call std.Build.Step.Compile.addObjCopy
and only need to set the build dependency for the object copy install step:
b.installArtifact(elf); // as normal
const bin = elf.addObjCopy(.{.format: .bin}); // no need for the elf emitted path
const installBin = b.addInstallBinFile(bin.getOutput(), "output.bin");
b.getInstallStep().dependOn(&installBin.step);
so the full build script can become:
const std = @import("std");
const Builder = std.build.Builder;
pub fn build(b: *Builder) void {
const optimization = std.builtin.OptimizeMode.ReleaseSmall;
const cpu_model = &std.Target.arm.cpu.cortex_m0;
// Build the elf
const elf = b.addExecutable(.{
.name = "output.elf",
.root_source_file = .{ .path = "src/startup.zig" },
.target = .{
.cpu_arch = .thumb,
.os_tag = .freestanding,
.abi = .none,
.cpu_model = .{ .explicit = cpu_model },
},
.optimize = optimization,
.single_threaded = true,
});
elf.setLinkerScript(.{ .path = "src/STM32Z/MCU/STM32L052.ld" });
b.installArtifact(elf);
const bin = elf.addObjCopy(.{.format: .bin});
const installBin = b.addInstallBinFile(bin.getOutput(), "output.bin");
b.getInstallStep().dependOn(&installBin.step);
}