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 { pub const EmbeddedExecutable = struct {
inner: *LibExeObjStep, inner: *LibExeObjStep,
pub fn addModule(exe: *EmbeddedExecutable, name: []const u8, module: *Module) void { pub const AppDependencyOptions = struct {
exe.inner.addModule(name, module); 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 { pub fn install(exe: *EmbeddedExecutable) void {
@ -190,6 +200,13 @@ pub fn addEmbeddedExecutable(
else => {}, 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; const exe = builder.allocator.create(EmbeddedExecutable) catch unreachable;
exe.* = EmbeddedExecutable{ exe.* = EmbeddedExecutable{
.inner = builder.addExecutable(.{ .inner = builder.addExecutable(.{
@ -199,6 +216,8 @@ pub fn addEmbeddedExecutable(
.optimize = opts.optimize, .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 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. // - 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 // - 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.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; return exe;
} }

@ -2,65 +2,41 @@ const std = @import("std");
const MemoryRegion = @import("MemoryRegion.zig"); const MemoryRegion = @import("MemoryRegion.zig");
const Chip = @import("Chip.zig"); const Chip = @import("Chip.zig");
const Step = std.build.Step; const Step = std.build.Step;
const Builder = std.build.Builder; const Build = std.Build;
const GeneratedFile = std.build.GeneratedFile; const GeneratedFile = std.build.GeneratedFile;
const LinkerscriptStep = @This(); const LinkerscriptStep = @This();
step: Step, step: Step,
generated_file: std.build.GeneratedFile, generated_file: std.build.GeneratedFile,
builder: *Builder,
chip: Chip, chip: Chip,
pub fn create(builder: *Builder, chip: Chip) !*LinkerscriptStep { pub fn create(owner: *Build, chip: Chip) !*LinkerscriptStep {
var hasher = std.hash.SipHash128(1, 2).init("abcdefhijklmnopq"); var linkerscript = try owner.allocator.create(LinkerscriptStep);
linkerscript.* = LinkerscriptStep{
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{
.step = Step.init(.{ .step = Step.init(.{
.id = .custom, .id = .custom,
.name = "linkerscript", .name = "linkerscript",
.owner = builder, .owner = owner,
.makeFn = make, .makeFn = make,
}), }),
.generated_file = .{ .generated_file = .{
.step = &ret.step, .step = &linkerscript.step,
.path = path,
}, },
.builder = builder,
.chip = chip, .chip = chip,
}; };
return ret;
return linkerscript;
} }
fn make(step: *Step, progress: *std.Progress.Node) !void { fn make(step: *Step, _: *std.Progress.Node) anyerror!void {
_ = progress;
const linkerscript = @fieldParentPtr(LinkerscriptStep, "step", step); 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 target = linkerscript.chip.cpu.target;
const writer = file.writer();
var contents = std.ArrayList(u8).init(owner.allocator);
const writer = contents.writer();
try writer.print( try writer.print(
\\/* \\/*
\\ * This file was auto-generated by microzig \\ * 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!" ); // \\ 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 { .C = struct {
fn wrapper() callconv(.C) void { fn wrapper() callconv(.C) void {
if (calling_convention == .Unspecified) // TODO: workaround for some weird stage1 bug if (calling_convention == .Unspecified) // TODO: workaround for some weird stage1 bug
@call(.{ .modifier = .always_inline }, function, .{}); @call(.always_inline, function, .{});
} }
}.wrapper, }.wrapper,
}, },

Loading…
Cancel
Save