The build.zig is probably relevant here.
const std = @import("std");
const builtin = @import("builtin");
pub fn build(b: *std.Build) void {
const exe_name = "dweomer_example";
const query: std.Target.Query = .{
.cpu_arch = .thumb,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 },
.os_tag = .freestanding,
.abi = .eabihf,
.glibc_version = null,
};
const target = b.resolveTargetQuery(query);
const optimize = b.standardOptimizeOption(.{});
const c_optimization = if (optimize == .Debug) "-Og" else if (optimize == .ReleaseSmall) "-Os" else "-O2";
// HAL --------------------------------------------------------------------------------------------------
const hal_device = "stm32f4xx"; // match the submodule path
const hal_cmsis = "cmsis-device-f4"; // match submodule path
const hal_includes = [_][]const u8{
"src/bsp/hal",
"src/bsp/hal/" ++ hal_device ++ "/Inc",
"src/bsp/hal/" ++ hal_device ++ "/Inc/Legacy",
"src/bsp/hal/" ++ hal_cmsis ++ "/Include",
"src/bsp/hal/cmsis/CMSIS/Core/Include",
"src/bsp/hal/cmsis/Device/ARM/ARMCM4/Include",
};
const hal_sources = [_][]const u8{
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_adc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_adc_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_can.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_cec.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_cortex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_crc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_cryp.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_cryp_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dac.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dac_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dcmi.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dcmi_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dfsdm.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dma.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dma_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dma2d.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_dsi.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_eth.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_exti.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_flash.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_flash_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_flash_ramfunc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_fmpi2c.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_fmpi2c_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_fmpsmbus.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_fmpsmbus_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_gpio.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_hash.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_hash_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_hcd.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_i2c.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_i2c_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_i2s.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_i2s_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_irda.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_iwdg.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_lptim.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_ltdc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_ltdc_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_mmc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_msp_template.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_nand.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_nor.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_pccard.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_pcd.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_pcd_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_pwr.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_pwr_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_qspi.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_rcc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_rcc_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_rng.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_rtc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_rtc_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_sai.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_sai_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_sd.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_sdram.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_smartcard.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_smbus.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_spdifrx.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_spi.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_sram.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_tim.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_tim_ex.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_uart.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_usart.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_hal_wwdg.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_adc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_crc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_dac.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_dma.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_dma2d.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_exti.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_fmc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_fmpi2c.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_fsmc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_gpio.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_i2c.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_lptim.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_pwr.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_rcc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_rng.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_rtc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_sdmmc.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_spi.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_tim.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_usart.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_usb.c",
"src/bsp/hal/" ++ hal_device ++ "/Src/" ++ hal_device ++ "_ll_utils.c",
"src/bsp/hal/" ++ hal_cmsis ++ "/Source/Templates/system_" ++ hal_device ++ ".c",
};
// -------------------------------------------------------------------------------------------------- HAL
const main_mod = b.addModule("main", .{
.root_source_file = b.path("src/main.zig"),
});
for (hal_includes) |path| {
main_mod.addIncludePath(b.path(path));
}
const s_mod = b.createModule(.{
.root_source_file = b.path("src/bsp/startup.zig"),
.target = target,
.optimize = optimize,
.link_libc = null,
.strip = true,
.single_threaded = true, // single core cpu
.sanitize_c = if (optimize == .Debug) false else true,
});
s_mod.addImport("main", main_mod);
const elf = b.addExecutable(.{
.name = exe_name ++ ".elf",
.linkage = .static,
.root_module = s_mod,
});
elf.setLinkerScript(b.path("src/bsp/linker.ld"));
elf.entry = .{ .symbol_name = "resetHandler" };
elf.link_data_sections = true; // -fdata-sections
elf.link_function_sections = true; // -ffunction-sections
elf.link_gc_sections = true; // -Wl,--gc-sections
elf.want_lto = false; // -flto (.isr_vector size will be zero if set to true)
// include HAL
const hal_flags = [_][]const u8{
c_optimization,
// "-std=gnu17",
"-std=c99",
"-Wall",
"-Wextra",
"-DUSE_HAL_DRIVER",
"-DSTM32F407xx",
"-D__CORTEX_M4",
};
elf.addCSourceFiles(.{
.files = &hal_sources,
.flags = &hal_flags,
});
for (hal_includes) |path| {
elf.addIncludePath(b.path(path));
}
// display section sizes
const size_prog: ?[]const u8 = b.findProgram(&.{"arm-none-eabi-size"}, &.{}) catch
b.findProgram(&.{"llvm-size"}, &.{}) catch blk: {
std.log.warn("could not find arm-none-eabi-size or llvm-size, skipping size step", .{});
break :blk null;
};
if (size_prog) |prog| {
const size_run = b.addSystemCommand(&[_][]const u8{
prog,
"zig-out/bin/" ++ exe_name ++ ".elf",
});
size_run.step.dependOn(&elf.step);
b.getInstallStep().dependOn(&size_run.step);
}
const readelf_prog: ?[]const u8 = b.findProgram(&.{"arm-none-eabi-readelf"}, &.{}) catch null;
if (readelf_prog) |prog| {
const readelf_run = b.addSystemCommand(&[_][]const u8{
prog,
"--sections",
"zig-out/bin/" ++ exe_name ++ ".elf",
});
readelf_run.step.dependOn(&elf.step);
b.getInstallStep().dependOn(&readelf_run.step);
}
// get bin and hex formats from elf
const obj_bin = b.addObjCopy(elf.getEmittedBin(), .{
.format = .bin,
});
obj_bin.step.dependOn(&elf.step);
const bin_out = b.addInstallBinFile(obj_bin.getOutput(), exe_name ++ ".bin");
b.default_step.dependOn(&bin_out.step);
const obj_hex = b.addObjCopy(elf.getEmittedBin(), .{
.format = .hex,
});
obj_hex.step.dependOn(&elf.step);
const hex_out = b.addInstallBinFile(obj_hex.getOutput(), exe_name ++ ".hex");
b.default_step.dependOn(&hex_out.step);
// get srec from output uising srecord
const srec_prog: ?[]const u8 = b.findProgram(&.{"srec_cat"}, &.{}) catch null;
if (srec_prog) |prog| {
const srec_cmd = b.addSystemCommand(&[_][]const u8{
prog,
b.getInstallPath(.bin, exe_name ++ ".hex"),
"-Intel",
"-o",
b.getInstallPath(.bin, exe_name ++ ".srec"),
"-Motorola",
});
srec_cmd.step.dependOn(&hex_out.step);
b.getInstallStep().dependOn(&srec_cmd.step);
} else {
std.log.warn("could not find srec_cat program", .{});
}
// This declares intent for the executable to be installed into the
// standard location when the user invokes the "install" step (the default
// step when running `zig build`).
b.default_step.dependOn(&elf.step);
b.installArtifact(elf);
}