build_lua.zig (6668B)
1 const std = @import("std"); 2 const build = @import("../build.zig"); 3 const LazyPath = std.Build.LazyPath; 4 5 pub fn build_nlua0( 6 b: *std.Build, 7 target: std.Build.ResolvedTarget, 8 optimize: std.builtin.OptimizeMode, 9 use_luajit: bool, 10 ziglua: *std.Build.Dependency, 11 lpeg: ?*std.Build.Dependency, 12 libluv: ?*std.Build.Step.Compile, 13 system_integration_options: build.SystemIntegrationOptions, 14 ) !*std.Build.Step.Compile { 15 const options = b.addOptions(); 16 options.addOption(bool, "use_luajit", use_luajit); 17 18 const nlua0_exe = b.addExecutable(.{ 19 .name = "nlua0", 20 .root_module = b.createModule(.{ 21 .root_source_file = b.path("src/nlua0.zig"), 22 .target = target, 23 .optimize = optimize, 24 .link_libc = true, 25 }), 26 }); 27 const nlua0_mod = nlua0_exe.root_module; 28 29 const exe_unit_tests = b.addTest(.{ 30 .root_module = b.createModule(.{ 31 .root_source_file = b.path("src/nlua0.zig"), 32 .target = target, 33 .optimize = optimize, 34 .link_libc = true, 35 }), 36 }); 37 38 const embedded_data = b.addModule("embedded_data", .{ 39 .root_source_file = b.path("runtime/embedded_data.zig"), 40 }); 41 42 for ([2]*std.Build.Module{ nlua0_mod, exe_unit_tests.root_module }) |mod| { 43 mod.addImport("ziglua", ziglua.module("zlua")); 44 mod.addImport("embedded_data", embedded_data); 45 // addImport already links by itself. but we need headers as well.. 46 if (system_integration_options.lua) { 47 const system_lua_lib = if (use_luajit) "luajit" else "lua5.1"; 48 mod.linkSystemLibrary(system_lua_lib, .{}); 49 } else { 50 mod.linkLibrary(ziglua.artifact("lua")); 51 } 52 if (libluv) |luv| { 53 mod.linkLibrary(luv); 54 } else { 55 mod.linkSystemLibrary("luv", .{}); 56 } 57 58 mod.addOptions("options", options); 59 60 mod.addIncludePath(b.path("src")); 61 mod.addIncludePath(b.path("src/includes_fixmelater")); 62 try add_lua_modules(b, target.result, mod, lpeg, use_luajit, true, system_integration_options); 63 } 64 65 // for debugging the nlua0 environment 66 // like this: `zig build nlua0 -- script.lua {args}` 67 const run_cmd = b.addRunArtifact(nlua0_exe); 68 if (b.args) |args| { 69 run_cmd.addArgs(args); 70 } 71 const run_step = b.step("nlua0", "Run nlua0 build tool"); 72 run_step.dependOn(&run_cmd.step); 73 74 b.installArtifact(nlua0_exe); // DEBUG 75 76 const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); 77 78 const test_step = b.step("test_nlua0", "Run unit tests for nlua0"); 79 test_step.dependOn(&run_exe_unit_tests.step); 80 81 return nlua0_exe; 82 } 83 84 pub fn add_lua_modules( 85 b: *std.Build, 86 target: std.Target, 87 mod: *std.Build.Module, 88 lpeg_dep: ?*std.Build.Dependency, 89 use_luajit: bool, 90 is_nlua0: bool, 91 system_integration_options: build.SystemIntegrationOptions, 92 ) !void { 93 const flags = [_][]const u8{ 94 // Standard version used in Lua Makefile 95 "-std=gnu99", 96 if (is_nlua0) "-DNVIM_NLUA0" else "", 97 }; 98 99 if (lpeg_dep) |lpeg| { 100 mod.addIncludePath(lpeg.path("")); 101 } 102 mod.addCSourceFiles(.{ 103 .files = &.{ 104 "src/mpack/lmpack.c", 105 "src/mpack/mpack_core.c", 106 "src/mpack/object.c", 107 "src/mpack/conv.c", 108 "src/mpack/rpc.c", 109 }, 110 .flags = &flags, 111 }); 112 if (system_integration_options.lpeg) { 113 if (try findLpeg(b, target)) |lpeg_lib| { 114 mod.addLibraryPath(.{ .cwd_relative = std.fs.path.dirname(lpeg_lib).? }); 115 mod.addObjectFile(.{ .cwd_relative = lpeg_lib }); 116 } 117 } else if (lpeg_dep) |lpeg| { 118 mod.addCSourceFiles(.{ 119 .root = .{ .dependency = .{ .dependency = lpeg, .sub_path = "" } }, 120 .files = &.{ 121 "lpcap.c", 122 "lpcode.c", 123 "lpcset.c", 124 "lpprint.c", 125 "lptree.c", 126 "lpvm.c", 127 }, 128 .flags = &flags, 129 }); 130 } 131 132 if (!use_luajit) { 133 mod.addCSourceFiles(.{ 134 .files = &.{ 135 "src/bit.c", 136 }, 137 .flags = &flags, 138 }); 139 } 140 } 141 142 pub fn build_libluv( 143 b: *std.Build, 144 target: std.Build.ResolvedTarget, 145 optimize: std.builtin.OptimizeMode, 146 lua: ?*std.Build.Step.Compile, 147 libuv: *std.Build.Step.Compile, 148 use_luajit: bool, 149 ) !*std.Build.Step.Compile { 150 const upstream = b.lazyDependency("luv", .{}); 151 const compat53 = b.lazyDependency("lua_compat53", .{}); 152 const lib = b.addLibrary(.{ 153 .name = "luv", 154 .linkage = .static, 155 .root_module = b.createModule(.{ 156 .target = target, 157 .optimize = optimize, 158 }), 159 }); 160 161 if (lua) |lua_lib| { 162 lib.root_module.linkLibrary(lua_lib); 163 } else { 164 const system_lua_lib = if (use_luajit) "luajit" else "lua5.1"; 165 lib.root_module.linkSystemLibrary(system_lua_lib, .{}); 166 } 167 lib.linkLibrary(libuv); 168 169 if (upstream) |dep| { 170 lib.addIncludePath(dep.path("src")); 171 lib.installHeader(dep.path("src/luv.h"), "luv/luv.h"); 172 lib.addCSourceFiles(.{ .root = dep.path("src/"), .files = &.{ 173 "luv.c", 174 } }); 175 } 176 if (compat53) |dep| { 177 lib.addIncludePath(dep.path("c-api")); 178 lib.addCSourceFiles(.{ .root = dep.path("c-api"), .files = &.{ 179 "compat-5.3.c", 180 } }); 181 } 182 183 return lib; 184 } 185 186 fn findLpeg(b: *std.Build, target: std.Target) !?[]const u8 { 187 const filenames = [_][]const u8{ 188 "lpeg_a", 189 "lpeg", 190 "liblpeg_a", 191 "lpeg.so", 192 b.fmt("lpeg{s}", .{target.dynamicLibSuffix()}), 193 }; 194 var code: u8 = 0; 195 const dirs_stdout = std.mem.trimEnd(u8, try b.runAllowFail(&[_][]const u8{ 196 "pkg-config", 197 "--variable=pc_system_libdirs", 198 "--keep-system-cflags", 199 "pkg-config", 200 }, &code, .Ignore), "\r\n"); 201 var paths: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 0); 202 var path_it = std.mem.tokenizeAny(u8, dirs_stdout, " ,"); 203 while (path_it.next()) |dir| { 204 try paths.append(b.allocator, dir); 205 try paths.append(b.allocator, b.fmt("{s}/lua/5.1", .{dir})); 206 } 207 for (paths.items) |path| { 208 var dir = std.fs.openDirAbsolute(path, .{}) catch continue; 209 defer dir.close(); 210 for (filenames) |filename| { 211 dir.access(filename, .{}) catch continue; 212 return b.fmt("{s}/{s}", .{ path, filename }); 213 } 214 } 215 return null; 216 }