Skip to content
This repository was archived by the owner on Apr 21, 2025. It is now read-only.

Commit acb0e07

Browse files
authored
Merge pull request #14 from ZigEmbeddedGroup/catchup-0.13.0
Catch up to Zig 0.14.0
2 parents 6f1b3e9 + d5a6f28 commit acb0e07

File tree

15 files changed

+195
-101
lines changed

15 files changed

+195
-101
lines changed

.github/workflows/build.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,23 @@ jobs:
99
matrix:
1010
os: [ubuntu-latest, windows-latest, macos-latest]
1111
steps:
12-
- uses: actions/checkout@v2
13-
- uses: goto-bus-stop/setup-zig@v1.3.0
12+
- name: Checkout
13+
uses: actions/checkout@v4
14+
15+
- name: Setup Zig
16+
uses: mlugg/setup-zig@v1
1417
with:
15-
version: 0.11.0
18+
version: 0.14.0
1619

1720
- name: Build
1821
run: zig build install
19-
20-
- name: Test Suite
22+
23+
- name: Run Test Suite
2124
run: zig build test
25+
26+
- name: Run Samples
27+
run: |
28+
./zig-out/bin/aviron --info
29+
./zig-out/bin/aviron --trace zig-out/samples/math.elf
30+
./zig-out/bin/aviron zig-out/samples/hello-world.elf
31+

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
zig-*
1+
zig-out
2+
.zig-cache

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
AVR simulator in Zig.
44

5-
> DISCLAIMER: This is work in project and can currently emulate a good amount of the AVR instruction set
6-
> without cycle counting.
5+
> DISCLAIMER: This is work in project and can currently emulate a good amount of the AVR instruction set without cycle counting.
76
87
## Development
98

9+
Use [Zig 0.14.0](https://ziglang.org/download/#release-0.14.0) to compile AViRon.
10+
1011
### Repo Architecture
1112

1213
```sh

build.zig

Lines changed: 108 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
const std = @import("std");
2+
const Build = std.Build;
3+
const LazyPath = Build.LazyPath;
4+
const ResolvedTarget = Build.ResolvedTarget;
5+
26
const TestSuiteConfig = @import("src/testconfig.zig").TestSuiteConfig;
37

48
const samples = [_][]const u8{
59
"math",
10+
"hello-world",
611
};
712

8-
const avr_target = std.zig.CrossTarget{
13+
const avr_target_query = std.Target.Query{
914
.cpu_arch = .avr,
1015
.cpu_model = .{ .explicit = &std.Target.avr.cpu.atmega328p },
1116
.os_tag = .freestanding,
@@ -15,7 +20,7 @@ const avr_target = std.zig.CrossTarget{
1520
// Although this function looks imperative, note that its job is to
1621
// declaratively construct a build graph that will be executed by an external
1722
// runner.
18-
pub fn build(b: *std.Build) !void {
23+
pub fn build(b: *Build) !void {
1924
// Targets
2025
const test_step = b.step("test", "Run test suite");
2126
const run_step = b.step("run", "Run the app");
@@ -36,31 +41,35 @@ pub fn build(b: *std.Build) !void {
3641
// Modules
3742

3843
const isa_module = b.createModule(.{
39-
.source_file = .{ .path = "src/shared/isa.zig" },
44+
.root_source_file = b.path("src/shared/isa.zig"),
4045
});
4146
const isa_tables_module = b.createModule(.{
42-
.source_file = generateIsaTables(b, isa_module),
43-
.dependencies = &.{
47+
.root_source_file = generateIsaTables(b, isa_module),
48+
.imports = &.{
4449
.{ .name = "isa", .module = isa_module },
4550
},
4651
});
4752
const aviron_module = b.addModule("aviron", .{
48-
.source_file = .{ .path = "src/lib/aviron.zig" },
49-
.dependencies = &.{
53+
.root_source_file = b.path("src/lib/aviron.zig"),
54+
.imports = &.{
5055
.{ .name = "autogen-tables", .module = isa_tables_module },
5156
.{ .name = "isa", .module = isa_module },
5257
},
5358
});
5459

60+
const testsuite_module = b.addModule("aviron-testsuite", .{
61+
.root_source_file = b.path("src/libtestsuite/lib.zig"),
62+
});
63+
5564
// Main emulator executable
5665
const aviron_exe = b.addExecutable(.{
5766
.name = "aviron",
58-
.root_source_file = .{ .path = "src/main.zig" },
67+
.root_source_file = b.path("src/main.zig"),
5968
.target = target,
6069
.optimize = optimize,
6170
});
62-
aviron_exe.addModule("args", args_module);
63-
aviron_exe.addModule("aviron", aviron_module);
71+
aviron_exe.root_module.addImport("args", args_module);
72+
aviron_exe.root_module.addImport("aviron", aviron_module);
6473
b.installArtifact(aviron_exe);
6574

6675
const run_cmd = b.addRunArtifact(aviron_exe);
@@ -70,17 +79,20 @@ pub fn build(b: *std.Build) !void {
7079
}
7180
run_step.dependOn(&run_cmd.step);
7281

82+
const avr_target = b.resolveTargetQuery(avr_target_query);
83+
7384
// Samples
7485
for (samples) |sample_name| {
7586
const sample = b.addExecutable(.{
7687
.name = sample_name,
77-
.root_source_file = .{ .path = b.fmt("samples/{s}.zig", .{sample_name}) },
88+
.root_source_file = b.path(b.fmt("samples/{s}.zig", .{sample_name})),
7889
.target = avr_target,
7990
.optimize = .ReleaseSmall,
91+
.strip = false,
8092
});
8193
sample.bundle_compiler_rt = false;
82-
sample.setLinkerScriptPath(std.build.FileSource{ .path = "linker.ld" });
83-
sample.strip = false;
94+
sample.setLinkerScript(b.path("linker.ld"));
95+
sample.root_module.addImport("testsuite", testsuite_module);
8496

8597
// install to the prefix:
8698
const install_elf_sample = b.addInstallFile(sample.getEmittedBin(), b.fmt("samples/{s}.elf", .{sample_name}));
@@ -89,40 +101,43 @@ pub fn build(b: *std.Build) !void {
89101

90102
// Test suite:
91103

92-
try addTestSuite(b, test_step, debug_testsuite_step, target, optimize, args_module, aviron_module);
104+
try addTestSuite(b, test_step, debug_testsuite_step, target, avr_target, optimize, args_module, aviron_module);
93105

94106
try addTestSuiteUpdate(b, update_testsuite_step);
95107
}
96108

97109
fn addTestSuite(
98-
b: *std.Build,
99-
test_step: *std.Build.Step,
100-
debug_step: *std.Build.Step,
101-
target: std.zig.CrossTarget,
110+
b: *Build,
111+
test_step: *Build.Step,
112+
debug_step: *Build.Step,
113+
host_target: ResolvedTarget,
114+
avr_target: ResolvedTarget,
102115
optimize: std.builtin.OptimizeMode,
103-
args_module: *std.build.Module,
104-
aviron_module: *std.build.Module,
116+
args_module: *Build.Module,
117+
aviron_module: *Build.Module,
105118
) !void {
106119
const unit_tests = b.addTest(.{
107-
.root_source_file = .{ .path = "src/main.zig" },
108-
.target = target,
120+
.root_source_file = b.path("src/main.zig"),
121+
.target = host_target,
109122
.optimize = optimize,
110123
});
111124
test_step.dependOn(&b.addRunArtifact(unit_tests).step);
112125

113126
const testrunner_exe = b.addExecutable(.{
114127
.name = "aviron-test-runner",
115-
.root_source_file = .{ .path = "src/testrunner.zig" },
116-
.target = target,
128+
.root_source_file = b.path("src/testrunner.zig"),
129+
.target = host_target,
117130
.optimize = optimize,
118131
});
119-
testrunner_exe.addModule("args", args_module);
120-
testrunner_exe.addModule("aviron", aviron_module);
132+
testrunner_exe.root_module.addImport("args", args_module);
133+
testrunner_exe.root_module.addImport("aviron", aviron_module);
121134

122135
debug_step.dependOn(&b.addInstallArtifact(testrunner_exe, .{}).step);
123136

124137
{
125-
var walkdir = try b.build_root.handle.openIterableDir("testsuite", .{});
138+
var walkdir = try b.build_root.handle.openDir("testsuite", .{
139+
.iterate = true,
140+
});
126141
defer walkdir.close();
127142

128143
var walker = try walkdir.walk(b.allocator);
@@ -132,6 +147,11 @@ fn addTestSuite(
132147
if (entry.kind != .file)
133148
continue;
134149

150+
if (std.mem.eql(u8, entry.path, "dummy.zig")) {
151+
// This file is not interesting to test.
152+
continue;
153+
}
154+
135155
const FileAction = union(enum) {
136156
compile,
137157
load,
@@ -162,7 +182,7 @@ fn addTestSuite(
162182
} else .unknown;
163183

164184
const ConfigAndExe = struct {
165-
binary: std.Build.LazyPath,
185+
binary: LazyPath,
166186
config: TestSuiteConfig,
167187
};
168188

@@ -177,26 +197,58 @@ fn addTestSuite(
177197
const config = try parseTestSuiteConfig(b, file);
178198

179199
const custom_target = if (config.cpu) |cpu|
180-
std.zig.CrossTarget.parse(.{
200+
b.resolveTargetQuery(std.Target.Query.parse(.{
181201
.arch_os_abi = "avr-freestanding-eabi",
182202
.cpu_features = cpu,
183-
}) catch @panic(cpu)
203+
}) catch @panic(cpu))
184204
else
185205
avr_target;
186206

207+
const file_ext = std.fs.path.extension(entry.path);
208+
const is_zig_test = std.mem.eql(u8, file_ext, ".zig");
209+
const is_c_test = std.mem.eql(u8, file_ext, ".c");
210+
const is_asm_test = std.mem.eql(u8, file_ext, ".S");
211+
212+
std.debug.assert(is_zig_test or is_c_test or is_asm_test);
213+
214+
const source_file = b.path(b.fmt("testsuite/{s}", .{entry.path}));
215+
const root_file = if (is_zig_test)
216+
source_file
217+
else
218+
b.path("testsuite/dummy.zig");
219+
187220
const test_payload = b.addExecutable(.{
188221
.name = std.fs.path.stem(entry.basename),
189-
.root_source_file = .{ .path = b.fmt("testsuite/{s}", .{entry.path}) },
190222
.target = custom_target,
191223
.optimize = config.optimize,
224+
.strip = false,
225+
.root_source_file = if (is_zig_test) root_file else null,
226+
.link_libc = false,
192227
});
228+
test_payload.want_lto = false; // AVR has no LTO support!
229+
test_payload.verbose_link = true;
230+
test_payload.verbose_cc = true;
193231
test_payload.bundle_compiler_rt = false;
194-
test_payload.addIncludePath(.{ .path = "testsuite" });
195-
test_payload.setLinkerScriptPath(std.build.FileSource{ .path = "linker.ld" });
196-
test_payload.addAnonymousModule("testsuite", .{
197-
.source_file = .{ .path = "src/libtestsuite/lib.zig" },
198-
});
199-
test_payload.strip = false;
232+
233+
test_payload.setLinkerScript(b.path("linker.ld"));
234+
235+
if (is_c_test or is_asm_test) {
236+
test_payload.addIncludePath(b.path("testsuite"));
237+
}
238+
if (is_c_test) {
239+
test_payload.addCSourceFile(.{
240+
.file = source_file,
241+
.flags = &.{},
242+
});
243+
}
244+
if (is_asm_test) {
245+
test_payload.addAssemblyFile(source_file);
246+
}
247+
if (is_zig_test) {
248+
test_payload.root_module.addAnonymousImport("testsuite", .{
249+
.root_source_file = b.path("src/libtestsuite/lib.zig"),
250+
});
251+
}
200252

201253
debug_step.dependOn(&b.addInstallFile(
202254
test_payload.getEmittedBin(),
@@ -219,7 +271,7 @@ fn addTestSuite(
219271
} else |_| @panic(config_path);
220272

221273
break :blk ConfigAndExe{
222-
.binary = .{ .path = b.fmt("testsuite/{s}", .{entry.path}) },
274+
.binary = b.path(b.fmt("testsuite/{s}", .{entry.path})),
223275
.config = config,
224276
};
225277
},
@@ -229,7 +281,7 @@ fn addTestSuite(
229281

230282
const test_run = b.addRunArtifact(testrunner_exe);
231283
test_run.addArg("--config");
232-
test_run.addFileArg(write_file.files.items[0].getPath());
284+
test_run.addFileArg(write_file.getDirectory().path(b, "config.json"));
233285
test_run.addArg("--name");
234286
test_run.addArg(entry.path);
235287

@@ -242,16 +294,20 @@ fn addTestSuite(
242294
}
243295
}
244296

245-
fn addTestSuiteUpdate(b: *std.Build, invoke_step: *std.Build.Step) !void {
246-
const avr_gcc = if (b.findProgram(&.{"avr-gcc"}, &.{})) |path| std.build.LazyPath{
297+
fn addTestSuiteUpdate(
298+
b: *Build,
299+
invoke_step: *Build.Step,
300+
) !void {
301+
const avr_gcc = if (b.findProgram(&.{"avr-gcc"}, &.{})) |path| LazyPath{
247302
.cwd_relative = path,
248303
} else |_| b.addExecutable(.{
249304
.name = "no-avr-gcc",
250-
.root_source_file = .{ .path = "tools/no-avr-gcc.zig" },
305+
.target = b.graph.host,
306+
.root_source_file = b.path("tools/no-avr-gcc.zig"),
251307
}).getEmittedBin();
252308

253309
{
254-
var walkdir = try b.build_root.handle.openIterableDir("testsuite.avr-gcc", .{});
310+
var walkdir = try b.build_root.handle.openDir("testsuite.avr-gcc", .{ .iterate = true });
255311
defer walkdir.close();
256312

257313
var walker = try walkdir.walk(b.allocator);
@@ -295,11 +351,12 @@ fn addTestSuiteUpdate(b: *std.Build, invoke_step: *std.Build.Step) !void {
295351

296352
const config = try parseTestSuiteConfig(b, file);
297353

298-
const gcc_invocation = std.Build.Step.Run.create(b, "run avr-gcc");
354+
const gcc_invocation = Build.Step.Run.create(b, "run avr-gcc");
299355
gcc_invocation.addFileArg(avr_gcc);
300356
gcc_invocation.addArg("-o");
301357
gcc_invocation.addArg(b.fmt("testsuite/{s}/{s}.elf", .{ std.fs.path.dirname(entry.path).?, std.fs.path.stem(entry.basename) }));
302-
gcc_invocation.addArg(b.fmt("-mmcu={s}", .{config.cpu orelse avr_target.cpu_model.explicit.llvm_name orelse @panic("Unknown MCU!")}));
358+
gcc_invocation.addArg(b.fmt("-mmcu={s}", .{config.cpu orelse @panic("Uknown MCU!")}));
359+
//avr_target.cpu_model.explicit.llvm_name orelse @panic("Unknown MCU!")}));
303360
for (config.gcc_flags) |opt| {
304361
gcc_invocation.addArg(opt);
305362
}
@@ -310,7 +367,7 @@ fn addTestSuiteUpdate(b: *std.Build, invoke_step: *std.Build.Step) !void {
310367
const write_file = b.addWriteFile("config.json", config.toString(b));
311368

312369
const copy_file = b.addSystemCommand(&.{"cp"}); // todo make this cross-platform!
313-
copy_file.addFileArg(write_file.files.items[0].getPath());
370+
copy_file.addFileArg(write_file.getDirectory().path(b, "config.json"));
314371
copy_file.addArg(b.fmt("testsuite/{s}/{s}.elf.json", .{ std.fs.path.dirname(entry.path).?, std.fs.path.stem(entry.basename) }));
315372

316373
invoke_step.dependOn(&gcc_invocation.step);
@@ -321,7 +378,7 @@ fn addTestSuiteUpdate(b: *std.Build, invoke_step: *std.Build.Step) !void {
321378
}
322379
}
323380

324-
fn parseTestSuiteConfig(b: *std.Build, file: std.fs.File) !TestSuiteConfig {
381+
fn parseTestSuiteConfig(b: *Build, file: std.fs.File) !TestSuiteConfig {
325382
var code = std.ArrayList(u8).init(b.allocator);
326383
defer code.deinit();
327384

@@ -355,14 +412,14 @@ fn parseTestSuiteConfig(b: *std.Build, file: std.fs.File) !TestSuiteConfig {
355412
);
356413
}
357414

358-
fn generateIsaTables(b: *std.Build, isa_mod: *std.Build.Module) std.Build.LazyPath {
415+
fn generateIsaTables(b: *Build, isa_mod: *Build.Module) LazyPath {
359416
const generate_tables_exe = b.addExecutable(.{
360417
.name = "aviron-generate-tables",
361-
.root_source_file = .{ .path = "tools/generate-tables.zig" },
362-
.target = .{},
418+
.root_source_file = b.path("tools/generate-tables.zig"),
419+
.target = b.graph.host,
363420
.optimize = .Debug,
364421
});
365-
generate_tables_exe.addModule("isa", isa_mod);
422+
generate_tables_exe.root_module.addImport("isa", isa_mod);
366423

367424
const run = b.addRunArtifact(generate_tables_exe);
368425

0 commit comments

Comments
 (0)