improvements from working on RP2040 (#115)

* improvements from working on RP2040

* fix missing file bug
wch-ch32v003
Matt Knight 2 years ago committed by GitHub
parent 6f5b7268f6
commit dabc9325cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -30,8 +30,18 @@ pub const Backing = union(enum) {
pub const EmbeddedExecutable = struct {
inner: *LibExeObjStep,
pub fn addModule(exe: *EmbeddedExecutable, name: []const u8, module: *Module) void {
exe.inner.addModule(name, module);
pub const AppDependencyOptions = struct {
depend_on_microzig: bool = false,
};
pub fn addAppDependency(exe: *EmbeddedExecutable, name: []const u8, module: *Module, options: AppDependencyOptions) void {
if (options.depend_on_microzig) {
const microzig_module = exe.inner.modules.get("microzig").?;
module.dependencies.put("microzig", microzig_module) catch @panic("OOM");
}
const app_module = exe.inner.modules.get("app").?;
app_module.dependencies.put(name, module) catch @panic("OOM");
}
pub fn install(exe: *EmbeddedExecutable) void {
@ -190,6 +200,13 @@ pub fn addEmbeddedExecutable(
else => {},
}
const app_module = builder.createModule(.{
.source_file = opts.source_file,
.dependencies = &.{
.{ .name = "microzig", .module = microzig_module },
},
});
const exe = builder.allocator.create(EmbeddedExecutable) catch unreachable;
exe.* = EmbeddedExecutable{
.inner = builder.addExecutable(.{
@ -199,6 +216,8 @@ pub fn addEmbeddedExecutable(
.optimize = opts.optimize,
}),
};
exe.inner.addModule("app", app_module);
exe.inner.addModule("microzig", microzig_module);
exe.inner.strip = false; // we always want debug symbols, stripping brings us no benefit on embedded
@ -218,13 +237,6 @@ pub fn addEmbeddedExecutable(
// - 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.inner.bundle_compiler_rt = (exe.inner.target.getCpuArch() != .avr); // don't bundle compiler_rt for AVR as it doesn't compile right now
exe.addModule("microzig", microzig_module);
exe.addModule("app", builder.createModule(.{
.source_file = opts.source_file,
.dependencies = &.{
.{ .name = "microzig", .module = microzig_module },
},
}));
return exe;
}

@ -2,65 +2,41 @@ const std = @import("std");
const MemoryRegion = @import("MemoryRegion.zig");
const Chip = @import("Chip.zig");
const Step = std.build.Step;
const Builder = std.build.Builder;
const Build = std.Build;
const GeneratedFile = std.build.GeneratedFile;
const LinkerscriptStep = @This();
step: Step,
generated_file: std.build.GeneratedFile,
builder: *Builder,
chip: Chip,
pub fn create(builder: *Builder, chip: Chip) !*LinkerscriptStep {
var hasher = std.hash.SipHash128(1, 2).init("abcdefhijklmnopq");
hasher.update(chip.name);
hasher.update(chip.source.getPath(builder));
hasher.update(chip.cpu.name);
hasher.update(chip.cpu.source.getPath(builder));
var mac: [16]u8 = undefined;
hasher.final(&mac);
const filename = try std.fmt.allocPrint(builder.allocator, "{}{s}", .{
std.fmt.fmtSliceHexLower(&mac),
".ld",
});
const path = try std.fs.path.join(builder.allocator, &.{
"zig-cache",
"microzig",
filename,
});
try std.fs.cwd().makePath(std.fs.path.dirname(path).?);
var ret = try builder.allocator.create(LinkerscriptStep);
ret.* = LinkerscriptStep{
pub fn create(owner: *Build, chip: Chip) !*LinkerscriptStep {
var linkerscript = try owner.allocator.create(LinkerscriptStep);
linkerscript.* = LinkerscriptStep{
.step = Step.init(.{
.id = .custom,
.name = "linkerscript",
.owner = builder,
.owner = owner,
.makeFn = make,
}),
.generated_file = .{
.step = &ret.step,
.path = path,
.step = &linkerscript.step,
},
.builder = builder,
.chip = chip,
};
return ret;
return linkerscript;
}
fn make(step: *Step, progress: *std.Progress.Node) !void {
_ = progress;
fn make(step: *Step, _: *std.Progress.Node) anyerror!void {
const linkerscript = @fieldParentPtr(LinkerscriptStep, "step", step);
const file = try std.fs.cwd().createFile(linkerscript.generated_file.path.?, .{});
defer file.close();
const owner = linkerscript.step.owner;
const target = linkerscript.chip.cpu.target;
const writer = file.writer();
var contents = std.ArrayList(u8).init(owner.allocator);
const writer = contents.writer();
try writer.print(
\\/*
\\ * This file was auto-generated by microzig
@ -162,4 +138,35 @@ fn make(step: *Step, progress: *std.Progress.Node) !void {
// \\ ASSERT( (SIZEOF(.text) + SIZEOF(.data) > LENGTH(flash0)), "Error: .text + .data is too large for flash!" );
// \\
// );
const filename = try std.fmt.allocPrint(owner.allocator, "{s}_{s}.ld", .{
linkerscript.chip.name,
linkerscript.chip.cpu.name,
});
var hash = owner.cache.hash;
hash.addBytes(linkerscript.chip.name);
hash.addBytes(linkerscript.chip.cpu.name);
// TODO: hash more information to reduce chance of collision
for (linkerscript.chip.memory_regions) |memory_region| {
hash.add(memory_region.offset);
hash.add(memory_region.length);
}
const digest = hash.final();
const dir_path = try owner.cache_root.join(owner.allocator, &.{
"microzig",
&digest,
});
var dir = try owner.cache_root.handle.makeOpenPath(dir_path, .{});
defer dir.close();
const file = try dir.createFile(filename, .{});
defer file.close();
try file.writeAll(contents.items);
const full_path = owner.pathJoin(&.{ dir_path, filename });
linkerscript.generated_file.path = full_path;
}

@ -135,7 +135,7 @@ fn create_interrupt_vector(
.C = struct {
fn wrapper() callconv(.C) void {
if (calling_convention == .Unspecified) // TODO: workaround for some weird stage1 bug
@call(.{ .modifier = .always_inline }, function, .{});
@call(.always_inline, function, .{});
}
}.wrapper,
},

Loading…
Cancel
Save