From 1014f89d3dfc141f3baf895dbab5ed3628910d25 Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Mon, 18 Sep 2023 11:37:30 -0700 Subject: [PATCH] solve problem of finding paths for anonymous modules --- src/universal_lambda_build.zig | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/universal_lambda_build.zig b/src/universal_lambda_build.zig index 498cbd2..43fbc07 100644 --- a/src/universal_lambda_build.zig +++ b/src/universal_lambda_build.zig @@ -20,8 +20,10 @@ pub fn configureBuild(b: *std.Build, exe: *std.Build.Step.Compile) !void { // type of interface is necessary // Add module + const file_location = try findFileLocation(b); exe.addAnonymousModule("universal_lambda_handler", .{ - .source_file = .{ .path = "upstream/src/universal_lambda.zig" }, + // Source file can be anywhere on disk, does not need to be a subdirectory + .source_file = .{ .path = b.pathJoin(&[_][]const u8{ file_location, "universal_lambda.zig" }) }, .dependencies = &[_]std.Build.ModuleDependency{.{ .name = "build_options", .module = try createOptionsModule(b, exe), @@ -29,6 +31,41 @@ pub fn configureBuild(b: *std.Build, exe: *std.Build.Step.Compile) !void { }); } +/// This function relies on internal implementation of the build runner +/// When a developer launches "zig build", a program is compiled, with the +/// main entrypoint existing in build_runner.zig (this can be overridden by +/// by command line). +/// +/// The code we see in build.zig is compiled into that program. The program +/// is named 'build' and stuck in the zig cache, then it is run. There are +/// two phases to the build. +/// +/// Build phase, where a graph is established of the steps that need to be run, +/// then the "make phase", where the steps are actually executed. Steps have +/// a make function that is called. +/// +/// This function is reaching into the struct that is the build_runner.zig, and +/// finding the location of the dependency for ourselves to determine the +/// location of our own file. This is, of course, brittle, but there does not +/// seem to be a better way at the moment, and we need this to be able to import +/// modules appropriately. +/// +/// For development of this process directly, we'll allow a build option to +/// override this process completely, because during development it's easier +/// for the example build.zig to simply import the file directly than it is +/// to pull from a download location and update hashes every time we change +fn findFileLocation(b: *std.Build) ![]const u8 { + const build_root = b.option([]const u8, "universal_lambda_build_root", "Build root for universal lambda (development of universal lambda only)"); + if (build_root) |br| { + return b.pathJoin(&[_][]const u8{ br, "src" }); + } + const build_runner = @import("root"); + const deps = build_runner.dependencies; + const build_roots = deps.build_root; + if (!@hasField(build_roots, "universal_lambda_build")) + @panic("Dependency in build.zig.zon must be named 'universal_lambda_build'"); + return b.pathJoin(&[_][]const u8{ @field(build_roots, "universal_lambda_build"), "src" }); +} /// Make our target platform visible to runtime through an import /// called "build_options". This will also be available to the consuming /// executable if needed