You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
microzig/build.zig

179 lines
6.0 KiB
Zig

//! Some words on the build script here:
//! We cannot use a test runner here as we're building for freestanding.
//! This means we need to use addExecutable() instead of using
const std = @import("std");
const Board = struct {
name: []const u8,
path: []const u8,
chip: Chip,
};
const Chip = struct {
name: []const u8,
path: []const u8,
cpu: Cpu,
};
const Cpu = struct {
name: []const u8,
path: []const u8,
target: std.zig.CrossTarget,
linker_script: []const u8,
};
pub const Backing = union(enum) {
board: Board,
chip: Chip,
};
fn addEmbeddedExecutable(builder: *std.build.Builder, name: []const u8, source: []const u8, backing: Backing) *std.build.LibExeObjStep {
const Pkg = std.build.Pkg;
const exe = builder.addExecutable(name, source);
// TODO:
// - Generate the linker scripts from the "chip" or "board" package instead of using hardcoded ones.
// - This requires building another tool that runs on the host that compiles those files and emits the linker script.
// - src/tools/linkerscript-gen.zig is the source file for this
exe.bundle_compiler_rt = false;
switch (backing) {
.chip => |chip| {
exe.addBuildOption(bool, "microzig_has_board", false);
exe.addBuildOption([]const u8, "microzig_chip_name", chip.name);
exe.addBuildOption([]const u8, "microzig_cpu_name", chip.cpu.name);
exe.setTarget(chip.cpu.target);
exe.setLinkerScriptPath(chip.cpu.linker_script);
exe.addPackage(Pkg{
.name = "microzig",
.path = "src/core/microzig.zig",
.dependencies = &[_]Pkg{
Pkg{
.name = "chip",
.path = chip.path,
.dependencies = &[_]Pkg{
Pkg{
.name = "cpu",
.path = chip.cpu.path,
},
},
},
},
});
},
.board => |board| {
exe.addBuildOption(bool, "microzig_has_board", true);
exe.addBuildOption([]const u8, "microzig_board_name", board.name);
exe.addBuildOption([]const u8, "microzig_chip_name", board.chip.name);
exe.addBuildOption([]const u8, "microzig_cpu_name", board.chip.cpu.name);
exe.setTarget(board.chip.cpu.target);
exe.setLinkerScriptPath(board.chip.cpu.linker_script);
exe.addPackage(Pkg{
.name = "microzig",
.path = "src/core/microzig.zig",
.dependencies = &[_]Pkg{
Pkg{
.name = "board",
.path = board.path,
.dependencies = &[_]Pkg{
Pkg{
.name = "chip",
.path = board.chip.path,
.dependencies = &[_]Pkg{
Pkg{
.name = "cpu",
.path = board.chip.cpu.path,
},
},
},
},
},
},
});
},
}
return exe;
}
const pkgs = struct {
const cpus = struct {
const avr5 = Cpu{
.name = "avr",
.path = "src/modules/cpus/avr/avr5.zig",
.linker_script = "src/modules/cpus/avr/linker.ld",
.target = std.zig.CrossTarget{
.cpu_arch = .avr,
.cpu_model = .{ .explicit = &std.Target.avr.cpu.avr5 },
.os_tag = .freestanding,
.abi = .eabi,
},
};
const cortex_m3 = Cpu{
.name = "cortex-m3",
.path = "src/modules/cpus/cortex-m3/cortex-m3.zig",
.linker_script = "src/modules/cpus/cortex-m3/linker.ld",
.target = std.zig.CrossTarget{
.cpu_arch = .arm,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m3 },
.os_tag = .freestanding,
.abi = .eabi,
},
};
};
const chips = struct {
const atmega328p = Chip{
.name = "AtMega328p",
.path = "src/modules/chips/atmega328p/atmega328p.zig",
.cpu = cpus.avr5,
};
const lpc1768 = Chip{
.name = "mcu",
.path = "src/modules/chips/lpc1768/lpc1768.zig",
.cpu = cpus.cortex_m3,
};
};
const boards = struct {
const arduino_nano = Board{
.name = "board",
.path = "src/modules/boards/arduino-nano/arduino-nano.zig",
.chip = chips.atmega328p,
};
const mbed_lpc1768 = Board{
.name = "mbed LPC1768",
.path = "src/modules/boards/mbed-lpc1768/mbed-lpc1768.zig",
.chip = chips.lpc1768,
};
};
};
pub fn build(b: *std.build.Builder) void {
const mode = b.standardReleaseOptions();
const test_step = b.step("test", "Builds and runs the library test suite");
const BuildConfig = struct { name: []const u8, backing: Backing };
const all_backings = [_]BuildConfig{
BuildConfig{ .name = "boards.arduino_nano", .backing = Backing{ .board = pkgs.boards.arduino_nano } },
BuildConfig{ .name = "boards.mbed_lpc1768", .backing = Backing{ .board = pkgs.boards.mbed_lpc1768 } },
BuildConfig{ .name = "chips.atmega328p", .backing = Backing{ .chip = pkgs.chips.atmega328p } },
BuildConfig{ .name = "chips.lpc1768", .backing = Backing{ .chip = pkgs.chips.lpc1768 } },
};
inline for (all_backings) |cfg| {
const exe = addEmbeddedExecutable(
b,
"test-minimal-" ++ cfg.name,
"tests/minimal.zig",
cfg.backing,
);
exe.setBuildMode(mode);
test_step.dependOn(&exe.step);
}
}