From 52693e7af3d3c7445761c8c0644ca437d2bf2df6 Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 8 Jan 2026 11:01:30 +0100 Subject: [PATCH] fix(build): more changes to make zig 0.16.0 work --- .github/workflows/test.yml | 6 +- .gitignore | 1 + build.zig | 135 ++++++++++---------------- build.zig.zon | 4 +- deps/unibilium/build.zig.zon | 3 +- deps/utf8proc/build.zig.zon | 3 +- runtime/doc/news.txt | 2 +- scripts/bump_deps.lua | 2 +- src/build_lua.zig | 2 +- src/nlua0.zig | 28 ++++-- test/functional/ex_cmds/make_spec.lua | 6 +- test/run_tests.zig | 4 +- 12 files changed, 87 insertions(+), 109 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f3c82e5948..ab3eb2f965 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -255,7 +255,7 @@ jobs: - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.16.0-dev.1912+0cbaaa5eb + version: 0.16.0 - run: sudo apt-get install -y inotify-tools - run: zig build $OPTS test_nlua0 @@ -278,7 +278,7 @@ jobs: - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.16.0-dev.1912+0cbaaa5eb + version: 0.16.0 - run: zig build test_nlua0 -Dluajit=false - run: zig build nvim_bin -Dluajit=false && ./zig-out/bin/nvim --version @@ -295,7 +295,7 @@ jobs: - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 with: - version: 0.16.0-dev.1912+0cbaaa5eb + version: 0.16.0 - run: zig build test_nlua0 - run: zig build nvim_bin diff --git a/.gitignore b/.gitignore index 9703749045..4da29eba7d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ compile_commands.json # Build/deps dir /.zig-cache/ /zig-out/ +/zig-pkg/ /.deps/ /tmp/ /.clangd/ diff --git a/build.zig b/build.zig index 7c2b9f6c00..b2b1c426f3 100644 --- a/build.zig +++ b/build.zig @@ -42,9 +42,7 @@ pub fn lazyArtifact(d: *std.Build.Dependency, name: []const u8) ?*std.Build.Step pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - var threaded: std.Io.Threaded = .init_single_threaded; - defer threaded.deinit(); - const io = threaded.io(); + const io = b.graph.io; const t = target.result; const os_tag = t.os.tag; @@ -69,7 +67,7 @@ pub fn build(b: *std.Build) !void { const host_use_luajit = if (cross_compiling) false else use_luajit; const E = enum { luajit, lua51 }; - const system_integration_options = SystemIntegrationOptions{ + const sys_opts = SystemIntegrationOptions{ .lpeg = b.systemIntegrationOption("lpeg", .{}), .lua = b.systemIntegrationOption("lua", .{}), .tree_sitter = b.systemIntegrationOption("tree-sitter", .{}), @@ -83,20 +81,20 @@ pub fn build(b: *std.Build) !void { .optimize = optimize_lua, .lang = if (use_luajit) E.luajit else E.lua51, .shared = false, - .system_lua = system_integration_options.lua, + .system_lua = sys_opts.lua, }); const ziglua_host = if (cross_compiling) b.dependency("zlua", .{ .target = target_host, .optimize = .ReleaseSmall, .lang = if (host_use_luajit) E.luajit else E.lua51, - .system_lua = system_integration_options.lua, + .system_lua = sys_opts.lua, .shared = false, }) else ziglua; var lua: ?*Compile = null; var libuv: ?*Compile = null; var libluv: ?*Compile = null; var libluv_host: ?*Compile = null; - if (!system_integration_options.lua) { + if (!sys_opts.lua) { // this is currently not necessary, as ziglua currently doesn't use lazy dependencies // to circumvent ziglua.artifact() failing in a bad way. lua = lazyArtifact(ziglua, "lua") orelse return; @@ -104,7 +102,7 @@ pub fn build(b: *std.Build) !void { _ = lazyArtifact(ziglua_host, "lua") orelse return; } } - if (!system_integration_options.uv) { + if (!sys_opts.uv) { // NOTE: libuv on Windows depends on Windows SDK when compiled with .Debug mode // https://github.com/neovim/neovim/issues/36889 const optimize_uv = if (optimize == .Debug and target.result.os.tag == .windows) .ReleaseSafe else optimize; @@ -130,25 +128,25 @@ pub fn build(b: *std.Build) !void { } } - const lpeg = if (system_integration_options.lpeg) null else b.lazyDependency("lpeg", .{}); + const lpeg = if (sys_opts.lpeg) null else b.lazyDependency("lpeg", .{}); const iconv = if (is_windows or is_darwin) b.lazyDependency("libiconv", .{ .target = target, .optimize = optimize, }) else null; - const utf8proc = if (system_integration_options.utf8proc) null else b.lazyDependency("utf8proc", .{ + const utf8proc = if (sys_opts.utf8proc) null else b.lazyDependency("utf8proc", .{ .target = target, .optimize = optimize, }); - const unibilium = if (use_unibilium and !system_integration_options.unibilium) b.lazyDependency("unibilium", .{ + const unibilium = if (use_unibilium and !sys_opts.unibilium) b.lazyDependency("unibilium", .{ .target = target, .optimize = optimize, }) else null; // TODO(bfredl): fix upstream bugs with UBSAN const optimize_ts = .ReleaseFast; - const treesitter = if (system_integration_options.tree_sitter) null else b.lazyDependency("treesitter", .{ + const treesitter = if (sys_opts.tree_sitter) null else b.lazyDependency("treesitter", .{ .target = target, .optimize = optimize_ts, }); @@ -162,7 +160,7 @@ pub fn build(b: *std.Build) !void { ziglua_host, lpeg, libluv_host, - system_integration_options, + sys_opts, ); // usual caveat emptor: might need to force a rebuild if the only change is @@ -340,7 +338,7 @@ pub fn build(b: *std.Build) !void { "-C", b.build_root.path orelse ".", // affects the --git-dir argument "--git-dir", ".git", // affected by the -C argument "describe", "--dirty", "--match", "v*.*.*", // - }, &code, .Ignore) catch { + }, &code, .ignore) catch { break :v version_string; }; const git_describe = std.mem.trim(u8, git_describe_untrimmed, " \n\r"); @@ -379,31 +377,31 @@ pub fn build(b: *std.Build) !void { var unittest_include_path: std.ArrayList(LazyPath) = try .initCapacity(b.allocator, 2); try unittest_include_path.append(b.allocator, b.path("src/")); try unittest_include_path.append(b.allocator, gen_config.getDirectory()); - if (system_integration_options.lua) { + if (sys_opts.lua) { try appendSystemIncludePath(b, &unittest_include_path, lualib_name); } else if (lua) |compile| { try unittest_include_path.append(b.allocator, compile.getEmittedIncludeTree()); } - if (system_integration_options.uv) { + if (sys_opts.uv) { try appendSystemIncludePath(b, &unittest_include_path, "libuv"); try appendSystemIncludePath(b, &unittest_include_path, "libluv"); } else { if (libuv) |compile| try unittest_include_path.append(b.allocator, compile.getEmittedIncludeTree()); if (libluv) |compile| try unittest_include_path.append(b.allocator, compile.getEmittedIncludeTree()); } - if (system_integration_options.utf8proc) { + if (sys_opts.utf8proc) { try appendSystemIncludePath(b, &unittest_include_path, "libutf8proc"); } else if (utf8proc) |dep| { try unittest_include_path.append(b.allocator, dep.artifact("utf8proc").getEmittedIncludeTree()); } if (use_unibilium) { - if (system_integration_options.unibilium) { + if (sys_opts.unibilium) { try appendSystemIncludePath(b, &unittest_include_path, "unibilium"); } else if (unibilium) |dep| { try unittest_include_path.append(b.allocator, dep.artifact("unibilium").getEmittedIncludeTree()); } } - if (system_integration_options.tree_sitter) { + if (sys_opts.tree_sitter) { try appendSystemIncludePath(b, &unittest_include_path, "tree-sitter"); } else if (treesitter) |dep| { try unittest_include_path.append(b.allocator, dep.artifact("tree-sitter").getEmittedIncludeTree()); @@ -439,63 +437,51 @@ pub fn build(b: *std.Build) !void { .install_subdir = "headers/", }).step); - var nvim_exe_module = b.createModule(.{ + var nvim_mod = b.createModule(.{ .target = target, .optimize = optimize, .link_libc = true, }); - const nvim_exe = b.addExecutable(.{ - .name = "nvim", - .root_module = nvim_exe_module, - }); + const nvim_exe = b.addExecutable(.{ .name = "nvim", .root_module = nvim_mod }); nvim_exe.rdynamic = true; // -E - if (system_integration_options.lua) { + if (sys_opts.lua) { nvim_exe.root_module.linkSystemLibrary(lualib_name, .{}); } else if (lua) |compile| { - nvim_exe_module.linkLibrary(compile); + nvim_mod.linkLibrary(compile); } - if (system_integration_options.uv) { - nvim_exe_module.linkSystemLibrary("libuv", .{}); - nvim_exe_module.linkSystemLibrary("libluv", .{}); + if (sys_opts.uv) { + nvim_mod.linkSystemLibrary("libuv", .{}); + nvim_mod.linkSystemLibrary("libluv", .{}); } else { - if (libuv) |compile| nvim_exe.root_module.linkLibrary(compile); - if (libluv) |compile| nvim_exe.root_module.linkLibrary(compile); + if (libuv) |compile| nvim_mod.linkLibrary(compile); + if (libluv) |compile| nvim_mod.linkLibrary(compile); } - if (iconv) |dep| nvim_exe_module.linkLibrary(dep.artifact("iconv")); - if (system_integration_options.utf8proc) { - nvim_exe_module.linkSystemLibrary("utf8proc", .{}); + if (iconv) |dep| nvim_mod.linkLibrary(dep.artifact("iconv")); + if (sys_opts.utf8proc) { + nvim_mod.linkSystemLibrary("utf8proc", .{}); } else if (utf8proc) |dep| { - nvim_exe_module.linkLibrary(dep.artifact("utf8proc")); + nvim_mod.linkLibrary(dep.artifact("utf8proc")); } if (use_unibilium) { - if (system_integration_options.unibilium) { - nvim_exe_module.linkSystemLibrary("unibilium", .{}); + if (sys_opts.unibilium) { + nvim_mod.linkSystemLibrary("unibilium", .{}); } else if (unibilium) |dep| { - nvim_exe_module.linkLibrary(dep.artifact("unibilium")); + nvim_mod.linkLibrary(dep.artifact("unibilium")); } } - if (system_integration_options.tree_sitter) { - nvim_exe_module.linkSystemLibrary("tree-sitter", .{}); + if (sys_opts.tree_sitter) { + nvim_mod.linkSystemLibrary("tree-sitter", .{}); } else if (treesitter) |dep| { - nvim_exe_module.linkLibrary(dep.artifact("tree-sitter")); + nvim_mod.linkLibrary(dep.artifact("tree-sitter")); } if (is_windows) { - nvim_exe_module.linkSystemLibrary("netapi32", .{}); + nvim_mod.linkSystemLibrary("netapi32", .{}); } - nvim_exe_module.addIncludePath(b.path("src")); - nvim_exe_module.addIncludePath(gen_config.getDirectory()); - nvim_exe_module.addIncludePath(gen_headers.getDirectory()); - try build_lua.add_lua_modules( - b, - io, - t, - nvim_exe_module, - lpeg, - use_luajit, - false, - system_integration_options, - ); + nvim_mod.addIncludePath(b.path("src")); + nvim_mod.addIncludePath(gen_config.getDirectory()); + nvim_mod.addIncludePath(gen_headers.getDirectory()); + try build_lua.add_lua_modules(b, io, t, nvim_mod, lpeg, use_luajit, false, sys_opts); var unit_test_sources = try std.ArrayList([]u8).initCapacity(b.allocator, 10); if (support_unittests) { @@ -527,9 +513,9 @@ pub fn build(b: *std.Build) !void { if (is_windows) "-DUTF8PROC_STATIC" else "", if (use_unibilium) "-DHAVE_UNIBILIUM" else "", }; - nvim_exe_module.addCSourceFiles(.{ .files = src_paths, .flags = &flags }); + nvim_mod.addCSourceFiles(.{ .files = src_paths, .flags = &flags }); - nvim_exe_module.addCSourceFiles(.{ .files = &.{ + nvim_mod.addCSourceFiles(.{ .files = &.{ "src/xdiff/xdiffi.c", "src/xdiff/xemit.c", "src/xdiff/xhistogram.c", @@ -542,7 +528,7 @@ pub fn build(b: *std.Build) !void { }, .flags = &flags }); if (is_windows) { - nvim_exe_module.addWin32ResourceFile(.{ .file = b.path("src/nvim/os/nvim.rc") }); + nvim_mod.addWin32ResourceFile(.{ .file = b.path("src/nvim/os/nvim.rc") }); } const nvim_exe_step = b.step("nvim_bin", "only the binary (not a fully working install!)"); @@ -595,29 +581,11 @@ pub fn build(b: *std.Build) !void { }); test_deps.dependOn(test_fixture(b, "shell-test", false, false, null, target, optimize, &flags)); - test_deps.dependOn(test_fixture( - b, - "tty-test", - true, - system_integration_options.uv, - libuv, - target, - optimize, - &flags, - )); + test_deps.dependOn(test_fixture(b, "tty-test", true, sys_opts.uv, libuv, target, optimize, &flags)); test_deps.dependOn(test_fixture(b, "pwsh-test", false, false, null, target, optimize, &flags)); test_deps.dependOn(test_fixture(b, "printargs-test", false, false, null, target, optimize, &flags)); test_deps.dependOn(test_fixture(b, "printenv-test", false, false, null, target, optimize, &flags)); - test_deps.dependOn(test_fixture( - b, - "streams-test", - true, - system_integration_options.uv, - libuv, - target, - optimize, - &flags, - )); + test_deps.dependOn(test_fixture(b, "streams-test", true, sys_opts.uv, libuv, target, optimize, &flags)); // tee: vendored in src/tee/ const tee_exe = b.addExecutable(.{ @@ -625,10 +593,10 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), }); - tee_exe.addCSourceFile(.{ .file = b.path("src/tee/tee.c") }); - tee_exe.linkLibC(); + tee_exe.root_module.addCSourceFile(.{ .file = b.path("src/tee/tee.c") }); test_deps.dependOn(&b.addInstallArtifact(tee_exe, .{}).step); // xxd - hex dump utility (vendored from Vim) @@ -698,10 +666,7 @@ pub fn test_fixture( .optimize = optimize, .link_libc = true, }); - const fixture = b.addExecutable(.{ - .name = name, - .root_module = root_module, - }); + const fixture = b.addExecutable(.{ .name = name, .root_module = root_module }); const source = if (std.mem.eql(u8, name, "pwsh-test")) "shell-test" else name; if (std.mem.eql(u8, name, "printenv-test")) { fixture.mingw_unicode_entry_point = true; // uses UNICODE on WINDOWS :scream: @@ -827,7 +792,7 @@ fn appendSystemIncludePath( const stdout = try b.runAllowFail( &[_][]const u8{ "pkg-config", system_name, "--cflags-only-I", "--keep-system-cflags" }, &code, - .Ignore, + .ignore, ); if (code != 0) return std.Build.PkgConfigError.PkgConfigFailed; var arg_it = std.mem.tokenizeAny(u8, stdout, " \r\n\t"); diff --git a/build.zig.zon b/build.zig.zon index fd1eba88df..c77cff1c5d 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -6,8 +6,8 @@ .dependencies = .{ .zlua = .{ - .url = "git+https://github.com/natecraddock/ziglua#a1cae53f6b841dd4fa108103f4bd0f515ca29cfb", - .hash = "zlua-0.1.0-hGRpCwxDBQD25I09a5dhcaNCEontuUsq2pgB34wjugHQ", + .url = "git+https://github.com/natecraddock/ziglua#c09d0cb9f8175c1c02fbeae51940cfab15f3e085", + .hash = "zlua-0.1.0-hGRpC1hWBQAhR6kPtfypQ1Awn09a9JWpIuErNKPCMwSq", }, .lpeg = .{ .url = "https://github.com/neovim/deps/raw/d495ee6f79e7962a53ad79670cb92488abe0b9b4/opt/lpeg-1.1.0.tar.gz", diff --git a/deps/unibilium/build.zig.zon b/deps/unibilium/build.zig.zon index 7fcf396b03..fddea8e696 100644 --- a/deps/unibilium/build.zig.zon +++ b/deps/unibilium/build.zig.zon @@ -1,5 +1,6 @@ .{ - .name = "unibilium", + .name = .unibilium, + .fingerprint = 0x1d1baa4896ad720, .version = "2.1.2", .paths = .{""}, diff --git a/deps/utf8proc/build.zig.zon b/deps/utf8proc/build.zig.zon index 96cb149f45..2ad44cddc2 100644 --- a/deps/utf8proc/build.zig.zon +++ b/deps/utf8proc/build.zig.zon @@ -1,5 +1,6 @@ .{ - .name = "utf8proc", + .name = .utf8proc, + .fingerprint = 0xdcddf08dbb8954c4, .version = "2.10.0", .paths = .{""}, diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index f287b68d29..9a45ab0350 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -111,7 +111,7 @@ API BUILD -• todo +• Building using "zig build" requires zig 0.16.x. DEFAULTS diff --git a/scripts/bump_deps.lua b/scripts/bump_deps.lua index a0ee55a723..3927492dcc 100755 --- a/scripts/bump_deps.lua +++ b/scripts/bump_deps.lua @@ -30,9 +30,9 @@ local zig_mode = { luajit = false, uncrustify = false, wasmtime = false, + libuv = false, unibilium = 'nested', utf8proc = 'nested', - libuv = 'nested', } local dependency_table = {} --- @type table diff --git a/src/build_lua.zig b/src/build_lua.zig index f1dce0f21c..a27fe01360 100644 --- a/src/build_lua.zig +++ b/src/build_lua.zig @@ -200,7 +200,7 @@ fn findLpeg(b: *std.Build, io: std.Io, target: std.Target) !?[]const u8 { "--variable=pc_system_libdirs", "--keep-system-cflags", "pkg-config", - }, &code, .Ignore), "\r\n"); + }, &code, .ignore), "\r\n"); var paths: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 0); var path_it = std.mem.tokenizeAny(u8, dirs_stdout, " ,"); while (path_it.next()) |dir| { diff --git a/src/nlua0.zig b/src/nlua0.zig index cdd30506b5..3222a58c52 100644 --- a/src/nlua0.zig +++ b/src/nlua0.zig @@ -22,7 +22,7 @@ extern "c" fn luaopen_lpeg(ptr: *anyopaque) c_int; extern "c" fn luaopen_bit(ptr: *anyopaque) c_int; extern "c" fn luaopen_luv(ptr: *anyopaque) c_int; -fn init() !*Lua { +fn init_lua() !*Lua { // Initialize the Lua vm var lua = try Lua.init(std.heap.c_allocator); lua.openLibs(); @@ -69,26 +69,34 @@ fn init() !*Lua { return lua; } -pub fn main() !void { - const argv = std.os.argv; +pub fn main(init: std.process.Init) !void { + const args = init.minimal.args; - const lua = try init(); + const lua = try init_lua(); defer lua.deinit(); - if (argv.len < 2) { + if (args.vector.len < 2) { std.debug.print("USAGE: nlua0 script.lua args...\n\n", .{}); return; } - lua.createTable(@intCast(argv.len - 2), 1); - for (0.., argv[1..]) |i, arg| { - _ = lua.pushString(std.mem.span(arg)); + lua.createTable(@intCast(args.vector.len - 2), 1); + + var iter = try init.minimal.args.iterateAllocator(init.arena.allocator()); + _ = iter.skip(); + var i: u32 = 0; + var firstarg: [:0]const u8 = undefined; + while (iter.next()) |val| : (i += 1) { + _ = lua.pushString(val); + if (i == 0) { + firstarg = try lua.toString(-1); // preserved on lua heap.. + } lua.rawSetIndex(-2, @intCast(i)); } lua.setGlobal("arg"); _ = try lua.getGlobal("debug"); _ = lua.getField(-1, "traceback"); - try lua.loadFile(std.mem.span(argv[1])); + try lua.loadFile(firstarg); lua.protectedCall(.{ .msg_handler = -2 }) catch |e| { if (e == error.LuaRuntime) { const msg = try lua.toString(-1); @@ -104,7 +112,7 @@ fn do_ret1(lua: *Lua, str: [:0]const u8) !void { } test "simple test" { - const lua = try init(); + const lua = try init_lua(); defer lua.deinit(); try do_ret1(lua, "return vim.isarray({2,3})"); diff --git a/test/functional/ex_cmds/make_spec.lua b/test/functional/ex_cmds/make_spec.lua index 87f9275199..106eefe290 100644 --- a/test/functional/ex_cmds/make_spec.lua +++ b/test/functional/ex_cmds/make_spec.lua @@ -5,6 +5,7 @@ local clear = n.clear local eval = n.eval local has_powershell = n.has_powershell local matches = t.matches +local not_matches = t.not_matches local api = n.api local testprg = n.testprg @@ -48,7 +49,7 @@ describe(':make', function() local out = eval('execute("make")') -- Error message is captured in the file and printed in the footer matches( - '[\r\n]+.*[\r\n]+.*Unknown first argument%: foo%^%[%[0m[\r\n]+shell returned 3[\r\n]+%(1 of 1%)%: Unknown first argument%: foo', + '[\r\n]+.*[\r\n]+.*Unknown first argument%: foo.*[\r\n]+shell returned 3[\r\n]+%(1 of 1%)%: Unknown first argument%: foo', out ) end) @@ -63,8 +64,9 @@ describe(':make', function() local out = eval('execute("make")') -- Ensure there are no "shell returned X" messages between -- command and last line (indicating zero exit) - matches('.*ready [$]%s+%^%[%[0m', out) + matches('.*ready [$]%s+', out) matches('\n.*%: ready [$]', out) + not_matches('shell returned', out) end) end) end) diff --git a/test/run_tests.zig b/test/run_tests.zig index 70d6688176..ebecdb5909 100644 --- a/test/run_tests.zig +++ b/test/run_tests.zig @@ -33,8 +33,8 @@ pub fn testStep(b: *std.Build, kind: []const u8, nvim_bin: *std.Build.Step.Compi try env.put("TMPDIR", b.fmt("{s}/Xtest_tmpdir", .{b.install_path})); try env.put("NVIM_LOG_FILE", b.fmt("{s}/Xtest_nvimlog", .{b.install_path})); - env.remove("NVIM"); - env.remove("XDG_DATA_DIRS"); + _ = env.swapRemove("NVIM"); + _ = env.swapRemove("XDG_DATA_DIRS"); return test_step; }