diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0e7dce5..ee63b42 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,3 +26,23 @@ jobs: - name: Run tests run: make test + + test_cross: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + zig: ["0.14.0", "0.15.0-dev.441+c1649d586"] + + runs-on: ${{matrix.os}} + + steps: + - name: Clone Ziglua + uses: actions/checkout@v3 + + - name: Setup Zig + uses: mlugg/setup-zig@v1 + with: + version: ${{ matrix.zig }} + + - name: Run tests + run: make test_cross \ No newline at end of file diff --git a/build/lua.zig b/build/lua.zig index 59c4594..d7a2b61 100644 --- a/build/lua.zig +++ b/build/lua.zig @@ -3,6 +3,8 @@ const std = @import("std"); const Build = std.Build; const Step = std.Build.Step; +const applyPatchToFile = @import("utils.zig").applyPatchToFile; + pub const Language = enum { lua51, lua52, @@ -98,8 +100,11 @@ pub fn configure( // Patch ldo.c for Lua 5.1 if (lang == .lua51) { - const patched = patchFile(b, target, lib, upstream.path("src/ldo.c"), b.path("build/lua-5.1.patch")); - lib.addCSourceFile(.{ .file = patched, .flags = &flags }); + const patched = applyPatchToFile(b, b.graph.host, upstream.path("src/ldo.c"), b.path("build/lua-5.1.patch"), "ldo.c"); + + lib.step.dependOn(&patched.run.step); + + lib.addCSourceFile(.{ .file = patched.output, .flags = &flags }); } lib.linkLibC(); @@ -117,29 +122,6 @@ pub fn configure( return lib; } -fn patchFile( - b: *Build, - target: Build.ResolvedTarget, - lib: *Step.Compile, - file: Build.LazyPath, - patch_file: Build.LazyPath, -) Build.LazyPath { - const patch = b.addExecutable(.{ - .name = "patch", - .root_source_file = b.path("build/patch.zig"), - .target = target, - }); - - const patch_run = b.addRunArtifact(patch); - patch_run.addFileArg(file); - patch_run.addFileArg(patch_file); - const out = patch_run.addOutputFileArg("ldo.c"); - - lib.step.dependOn(&patch_run.step); - - return out; -} - const lua_base_source_files = [_][]const u8{ "src/lapi.c", "src/lcode.c", diff --git a/build/luajit.patch b/build/luajit.patch new file mode 100644 index 0000000..dfd2748 --- /dev/null +++ b/build/luajit.patch @@ -0,0 +1,18 @@ +# Patch for cross build on windows +# C:\Users\runneradmin\AppData\Local\zig\o\2f9fc57e5a283abd5bd9f55a5d990f42/buildvm_arch.h:8:12: error: \U used with no following hex digits +# #line 1 "C:\Users\runneradmin\AppData\Local\zig\p\N-V-__8AACcgQgCuLYTPzCp6pnBmFJHyG77RAtM13hjOfTaG\src\vm_arm64.dasc" +# ^~~ +# C:\Users\runneradmin\AppData\Local\zig\p\N-V-__8AACcgQgCuLYTPzCp6pnBmFJHyG77RAtM13hjOfTaG\src/host/buildvm.c:75:10: note: in file included from C:\Users\runneradmin\AppData\Local\zig\p\N-V-__8AACcgQgCuLYTPzCp6pnBmFJHyG77RAtM13hjOfTaG\src/host/buildvm.c:75: +# #include "buildvm_arch.h" +--- a/dynasm/dynasm.lua ++++ b/dynasm/dynasm.lua +@@ -85,7 +85,8 @@ end + -- Resync CPP line numbers. + local function wsync() + if g_synclineno ~= g_lineno and g_opt.cpp then +- wline("#line "..g_lineno..' "'..g_fname..'"') ++ local fname = gsub(g_fname, "\\", "/") ++ wline("#line "..g_lineno..' "'..fname..'"') + g_synclineno = g_lineno + end + end \ No newline at end of file diff --git a/build/luajit.zig b/build/luajit.zig index 636113e..f355ebd 100644 --- a/build/luajit.zig +++ b/build/luajit.zig @@ -3,6 +3,8 @@ const std = @import("std"); const Build = std.Build; const Step = std.Build.Step; +const applyPatchToFile = @import("utils.zig").applyPatchToFile; + pub fn configure(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, upstream: *Build.Dependency, shared: bool) *Step.Compile { // TODO: extract this to the main build function because it is shared between all specialized build functions @@ -24,7 +26,7 @@ pub fn configure(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin. // Compile minilua interpreter used at build time to generate files const minilua = b.addExecutable(.{ .name = "minilua", - .target = target, // TODO ensure this is the host + .target = b.graph.host, // Use host target for cross build .optimize = .ReleaseSafe, }); minilua.linkLibC(); @@ -39,7 +41,28 @@ pub fn configure(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin. // Generate the buildvm_arch.h file using minilua const dynasm_run = b.addRunArtifact(minilua); - dynasm_run.addFileArg(upstream.path("dynasm/dynasm.lua")); + + if (b.graph.host.result.os.tag == .windows) { + // Patch windows cross build for LuaJIT + const sourceDynasmFile = upstream.path("dynasm/dynasm.lua"); + const destDynasmFile = upstream.path("dynasm/dynasm-patched.lua"); + const patchDynasm = applyPatchToFile(b, b.graph.host, sourceDynasmFile, b.path("build/luajit.patch"), "dynasm-patched.lua"); + + const copyPatchedDynasm = b.addSystemCommand(&[_][]const u8{ + "cmd", + }); + copyPatchedDynasm.addArgs(&.{ "/q", "/c", "copy" }); + copyPatchedDynasm.step.dependOn(&patchDynasm.run.step); + copyPatchedDynasm.addFileArg(patchDynasm.output); + copyPatchedDynasm.addFileArg(destDynasmFile); + + dynasm_run.step.dependOn(&patchDynasm.run.step); + dynasm_run.step.dependOn(©PatchedDynasm.step); + + dynasm_run.addFileArg(destDynasmFile); + } else { + dynasm_run.addFileArg(upstream.path("dynasm/dynasm.lua")); + } // TODO: Many more flags to figure out if (target.result.cpu.arch.endian() == .little) { @@ -55,6 +78,10 @@ pub fn configure(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin. dynasm_run.addArgs(&.{ "-D", "FPU", "-D", "HFABI" }); } + if (target.result.cpu.arch == .aarch64 or target.result.cpu.arch == .aarch64_be) { + dynasm_run.addArgs(&.{ "-D", "DUALNUM" }); + } + if (target.result.os.tag == .windows) dynasm_run.addArgs(&.{ "-D", "WIN" }); dynasm_run.addArg("-o"); @@ -81,7 +108,7 @@ pub fn configure(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin. // Compile the buildvm executable used to generate other files const buildvm = b.addExecutable(.{ .name = "buildvm", - .target = target, // TODO ensure this is the host + .target = b.graph.host, // Use host target for cross build .optimize = .ReleaseSafe, }); buildvm.linkLibC(); @@ -96,12 +123,18 @@ pub fn configure(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin. buildvm.step.dependOn(&dynasm_run.step); buildvm.step.dependOn(&genversion_run.step); + const buildvm_c_flags: []const []const u8 = switch (target.result.cpu.arch) { + .aarch64, .aarch64_be => &.{ "-DLUAJIT_TARGET=LUAJIT_ARCH_arm64", "-DLJ_ARCH_HASFPU=1", "-DLJ_ABI_SOFTFP=0" }, + else => &.{}, + }; + buildvm.addCSourceFiles(.{ .root = .{ .dependency = .{ .dependency = upstream, .sub_path = "", } }, .files = &.{ "src/host/buildvm_asm.c", "src/host/buildvm_fold.c", "src/host/buildvm_lib.c", "src/host/buildvm_peobj.c", "src/host/buildvm.c" }, + .flags = buildvm_c_flags, }); buildvm.addIncludePath(upstream.path("src")); @@ -156,7 +189,7 @@ pub fn configure(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin. buildvm_ljvm.addArg("-o"); if (target.result.os.tag == .windows) { - const ljvm_ob = buildvm_ljvm.addOutputFileArg("lj_vm. o"); + const ljvm_ob = buildvm_ljvm.addOutputFileArg("lj_vm.o"); lib.addObjectFile(ljvm_ob); } else { const ljvm_asm = buildvm_ljvm.addOutputFileArg("lj_vm.S"); diff --git a/build/utils.zig b/build/utils.zig new file mode 100644 index 0000000..eddf5ce --- /dev/null +++ b/build/utils.zig @@ -0,0 +1,34 @@ +const std = @import("std"); + +const Build = std.Build; +const Step = std.Build.Step; + +const PatchFile = struct { + run: *Step.Run, + output: Build.LazyPath, +}; + +pub fn applyPatchToFile( + b: *Build, + target: Build.ResolvedTarget, + file: Build.LazyPath, + patch_file: Build.LazyPath, + output_file: []const u8, +) PatchFile { + const patch = b.addExecutable(.{ + .name = "patch", + .root_source_file = b.path("build/patch.zig"), + .target = target, + }); + + const patch_run = b.addRunArtifact(patch); + patch_run.addFileArg(file); + patch_run.addFileArg(patch_file); + + const out = patch_run.addOutputFileArg(output_file); + + return .{ + .run = patch_run, + .output = out, + }; +} diff --git a/makefile b/makefile index 0cc9bd9..d796925 100644 --- a/makefile +++ b/makefile @@ -11,5 +11,15 @@ test: zig build install-example-zig-function zig build -Dlang=luau install-example-luau-bytecode + zig build -Dlang=luajit + +test_cross: + zig build -Dlang=lua51 -Dtarget=aarch64-linux + zig build -Dlang=lua51 -Dtarget=aarch64-linux-gnu + zig build -Dlang=luajit -Dtarget=aarch64-linux + zig build -Dlang=luajit -Dtarget=aarch64-linux-gnu + + zig build -Dlang=luajit -Dtarget=aarch64-macos + docs: zig build docs