From 427d62c43404c3da8f267a44849c3dc8bc4254f8 Mon Sep 17 00:00:00 2001 From: Chinmay Dalal Date: Mon, 5 Jan 2026 15:35:47 -0500 Subject: [PATCH] feat(build.zig): update to zig 0.16 --- .github/workflows/test.yml | 6 +- build.zig | 116 ++++++++++++++++++++----------------- build.zig.zon | 2 +- deps/unibilium/build.zig | 7 ++- deps/utf8proc/build.zig | 7 ++- src/build_lua.zig | 37 ++++++------ src/gen/gen_steps.zig | 7 ++- 7 files changed, 99 insertions(+), 83 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 45e44416fe..f3c82e5948 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.15.2 + version: 0.16.0-dev.1912+0cbaaa5eb - 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.15.2 + version: 0.16.0-dev.1912+0cbaaa5eb - 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.15.2 + version: 0.16.0-dev.1912+0cbaaa5eb - run: zig build test_nlua0 - run: zig build nvim_bin diff --git a/build.zig b/build.zig index 8743b66e56..7c2b9f6c00 100644 --- a/build.zig +++ b/build.zig @@ -42,6 +42,9 @@ 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 t = target.result; const os_tag = t.os.tag; @@ -152,6 +155,7 @@ pub fn build(b: *std.Build) !void { const nlua0 = try build_lua.build_nlua0( b, + io, target_host, optimize_host, host_use_luajit, @@ -201,12 +205,12 @@ pub fn build(b: *std.Build) !void { const src_dir = b.build_root.handle; for (subdirs) |s| { - var dir = try src_dir.openDir(b.fmt("src/nvim/{s}", .{s}), .{ .iterate = true }); - defer dir.close(); + var dir = try src_dir.openDir(io, b.fmt("src/nvim/{s}", .{s}), .{ .iterate = true }); + defer dir.close(io); var it = dir.iterateAssumeFirstIteration(); const api_export = std.mem.eql(u8, s, "api/"); const os_check = std.mem.eql(u8, s, "os/"); - entries: while (try it.next()) |entry| { + entries: while (try it.next(io)) |entry| { if (entry.name.len < 3) continue; if (entry.name[0] < 'a' or entry.name[0] > 'z') continue; if (os_check) { @@ -257,7 +261,7 @@ pub fn build(b: *std.Build) !void { .VERSION_STRING = "TODO", // TODO(bfredl): not sure what to put here. summary already in "config_str" .CONFIG = config_str, }); - _ = gen_config.addCopyFile(versiondef_step.getOutput(), "auto/versiondef.h"); // run_preprocessor() workaronnd + _ = gen_config.addCopyFile(versiondef_step.getOutputFile(), "auto/versiondef.h"); // run_preprocessor() workaronnd const ptrwidth = t.ptrBitWidth() / 8; const sysconfig_step = b.addConfigHeader(.{ @@ -310,7 +314,7 @@ pub fn build(b: *std.Build) !void { const system_install_path = b.option([]const u8, "install-path", "Install path (for packagers)"); const install_path = system_install_path orelse b.install_path; const lib_dir = if (system_install_path) |path| b.fmt("{s}/lib", .{path}) else b.lib_dir; - _ = gen_config.addCopyFile(sysconfig_step.getOutput(), "auto/config.h"); // run_preprocessor() workaronnd + _ = gen_config.addCopyFile(sysconfig_step.getOutputFile(), "auto/config.h"); // run_preprocessor() workaronnd _ = gen_config.add("auto/pathdef.h", b.fmt( \\char *default_vim_dir = "{s}/share/nvim"; @@ -410,6 +414,7 @@ pub fn build(b: *std.Build) !void { const gen_headers, const funcs_data = try gen.nvim_gen_sources( b, + io, nlua0, &nvim_sources, &nvim_headers, @@ -419,7 +424,7 @@ pub fn build(b: *std.Build) !void { ); const test_config_step = b.addWriteFiles(); - _ = test_config_step.add("test/cmakeconfig/paths.lua", try test_config(b)); + _ = test_config_step.add("test/cmakeconfig/paths.lua", try test_config(b, io)); const test_gen_step = b.step("gen_headers", "debug: output generated headers"); const config_install = b.addInstallDirectory(.{ @@ -434,56 +439,58 @@ pub fn build(b: *std.Build) !void { .install_subdir = "headers/", }).step); + var nvim_exe_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + }); const nvim_exe = b.addExecutable(.{ .name = "nvim", - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - .link_libc = true, - }), + .root_module = nvim_exe_module, }); nvim_exe.rdynamic = true; // -E if (system_integration_options.lua) { nvim_exe.root_module.linkSystemLibrary(lualib_name, .{}); } else if (lua) |compile| { - nvim_exe.root_module.linkLibrary(compile); + nvim_exe_module.linkLibrary(compile); } if (system_integration_options.uv) { - nvim_exe.root_module.linkSystemLibrary("libuv", .{}); - nvim_exe.root_module.linkSystemLibrary("libluv", .{}); + nvim_exe_module.linkSystemLibrary("libuv", .{}); + nvim_exe_module.linkSystemLibrary("libluv", .{}); } else { if (libuv) |compile| nvim_exe.root_module.linkLibrary(compile); if (libluv) |compile| nvim_exe.root_module.linkLibrary(compile); } - if (iconv) |dep| nvim_exe.linkLibrary(dep.artifact("iconv")); + if (iconv) |dep| nvim_exe_module.linkLibrary(dep.artifact("iconv")); if (system_integration_options.utf8proc) { - nvim_exe.root_module.linkSystemLibrary("utf8proc", .{}); + nvim_exe_module.linkSystemLibrary("utf8proc", .{}); } else if (utf8proc) |dep| { - nvim_exe.root_module.linkLibrary(dep.artifact("utf8proc")); + nvim_exe_module.linkLibrary(dep.artifact("utf8proc")); } if (use_unibilium) { if (system_integration_options.unibilium) { - nvim_exe.root_module.linkSystemLibrary("unibilium", .{}); + nvim_exe_module.linkSystemLibrary("unibilium", .{}); } else if (unibilium) |dep| { - nvim_exe.root_module.linkLibrary(dep.artifact("unibilium")); + nvim_exe_module.linkLibrary(dep.artifact("unibilium")); } } if (system_integration_options.tree_sitter) { - nvim_exe.root_module.linkSystemLibrary("tree-sitter", .{}); + nvim_exe_module.linkSystemLibrary("tree-sitter", .{}); } else if (treesitter) |dep| { - nvim_exe.root_module.linkLibrary(dep.artifact("tree-sitter")); + nvim_exe_module.linkLibrary(dep.artifact("tree-sitter")); } if (is_windows) { - nvim_exe.linkSystemLibrary("netapi32"); + nvim_exe_module.linkSystemLibrary("netapi32", .{}); } - nvim_exe.addIncludePath(b.path("src")); - nvim_exe.addIncludePath(gen_config.getDirectory()); - nvim_exe.addIncludePath(gen_headers.getDirectory()); + 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.root_module, + nvim_exe_module, lpeg, use_luajit, false, @@ -492,10 +499,10 @@ pub fn build(b: *std.Build) !void { var unit_test_sources = try std.ArrayList([]u8).initCapacity(b.allocator, 10); if (support_unittests) { - var unit_test_fixtures = try src_dir.openDir("test/unit/fixtures/", .{ .iterate = true }); - defer unit_test_fixtures.close(); + var unit_test_fixtures = try src_dir.openDir(io, "test/unit/fixtures/", .{ .iterate = true }); + defer unit_test_fixtures.close(io); var it = unit_test_fixtures.iterateAssumeFirstIteration(); - while (try it.next()) |entry| { + while (try it.next(io)) |entry| { if (entry.name.len < 3) continue; if (std.mem.eql(u8, ".c", entry.name[entry.name.len - 2 ..])) { try unit_test_sources.append(b.allocator, b.fmt("test/unit/fixtures/{s}", .{entry.name})); @@ -520,9 +527,9 @@ pub fn build(b: *std.Build) !void { if (is_windows) "-DUTF8PROC_STATIC" else "", if (use_unibilium) "-DHAVE_UNIBILIUM" else "", }; - nvim_exe.addCSourceFiles(.{ .files = src_paths, .flags = &flags }); + nvim_exe_module.addCSourceFiles(.{ .files = src_paths, .flags = &flags }); - nvim_exe.addCSourceFiles(.{ .files = &.{ + nvim_exe_module.addCSourceFiles(.{ .files = &.{ "src/xdiff/xdiffi.c", "src/xdiff/xemit.c", "src/xdiff/xhistogram.c", @@ -535,7 +542,7 @@ pub fn build(b: *std.Build) !void { }, .flags = &flags }); if (is_windows) { - nvim_exe.addWin32ResourceFile(.{ .file = b.path("src/nvim/os/nvim.rc") }); + nvim_exe_module.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!)"); @@ -630,10 +637,10 @@ pub fn build(b: *std.Build) !void { .root_module = b.createModule(.{ .target = target, .optimize = optimize, + .link_libc = true, }), }); - xxd_exe.addCSourceFile(.{ .file = b.path("src/xxd/xxd.c") }); - xxd_exe.linkLibC(); + xxd_exe.root_module.addCSourceFile(.{ .file = b.path("src/xxd/xxd.c") }); test_deps.dependOn(&b.addInstallArtifact(xxd_exe, .{}).step); const parser_c = b.dependency("treesitter_c", .{ .target = target, .optimize = optimize_ts }); @@ -686,28 +693,29 @@ pub fn test_fixture( optimize: std.builtin.OptimizeMode, flags: []const []const u8, ) *std.Build.Step { + var root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + }); const fixture = b.addExecutable(.{ .name = name, - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - }), + .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: } - fixture.addCSourceFile(.{ + root_module.addCSourceFile(.{ .file = b.path(b.fmt("./test/functional/fixtures/{s}.c", .{source})), .flags = flags, }); - fixture.linkLibC(); if (use_libuv) { if (use_system_libuv) { - fixture.root_module.linkSystemLibrary("libuv", .{}); + root_module.linkSystemLibrary("libuv", .{}); } else if (libuv) |uv| { - fixture.linkLibrary(uv); + root_module.linkLibrary(uv); } } return &b.addInstallArtifact(fixture, .{}).step; @@ -722,18 +730,19 @@ pub fn add_ts_parser( optimize: std.builtin.OptimizeMode, path: enum { test_, install }, ) *std.Build.Step { + var root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + }); const parser = b.addLibrary(.{ .name = name, - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - }), .linkage = .dynamic, + .root_module = root_module, }); - parser.addCSourceFile(.{ .file = parser_dir.path(b, "src/parser.c") }); - if (scanner) parser.addCSourceFile(.{ .file = parser_dir.path(b, "src/scanner.c") }); - parser.addIncludePath(parser_dir.path(b, "src")); - parser.linkLibC(); + root_module.addCSourceFile(.{ .file = parser_dir.path(b, "src/parser.c") }); + if (scanner) root_module.addCSourceFile(.{ .file = parser_dir.path(b, "src/scanner.c") }); + root_module.addIncludePath(parser_dir.path(b, "src")); switch (path) { .install => { @@ -784,9 +793,10 @@ fn replace_backslashes(b: *std.Build, input: []const u8) ![]const u8 { input; } -pub fn test_config(b: *std.Build) ![]u8 { - var buf: [std.fs.max_path_bytes]u8 = undefined; - const src_path = try b.build_root.handle.realpath(".", &buf); +pub fn test_config(b: *std.Build, io: std.Io) ![]u8 { + var buf: [std.fs.max_path_bytes]u8 = std.mem.zeroes([std.fs.max_path_bytes]u8); + _ = try b.build_root.handle.realPath(io, &buf); + const src_path = std.mem.span(@as([*:0]u8, @ptrCast(&buf))); // we don't use test/cmakeconfig/paths.lua.in because it contains cmake specific logic return b.fmt( diff --git a/build.zig.zon b/build.zig.zon index 3e88ac7d59..ffea829cc4 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .neovim, .fingerprint = 0x66eb090879307a38, .version = "0.13.0", - .minimum_zig_version = "0.15.2", + .minimum_zig_version = "0.16.0", .dependencies = .{ .zlua = .{ diff --git a/deps/unibilium/build.zig b/deps/unibilium/build.zig index c7da82efaf..d3707d2ae5 100644 --- a/deps/unibilium/build.zig +++ b/deps/unibilium/build.zig @@ -14,13 +14,14 @@ pub fn build(b: *std.Build) !void { }); if (b.lazyDependency("unibilium", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); + var root_module = lib.root_module; + root_module.addIncludePath(upstream.path("")); lib.installHeader(upstream.path("unibilium.h"), "unibilium.h"); - lib.linkLibC(); + root_module.link_libc = true; - lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ + root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "unibilium.c", "uninames.c", "uniutil.c", diff --git a/deps/utf8proc/build.zig b/deps/utf8proc/build.zig index f88209987d..c9be9f3c7e 100644 --- a/deps/utf8proc/build.zig +++ b/deps/utf8proc/build.zig @@ -14,12 +14,13 @@ pub fn build(b: *std.Build) !void { }); if (b.lazyDependency("utf8proc", .{})) |upstream| { - lib.addIncludePath(upstream.path("")); + var root_module = lib.root_module; + root_module.addIncludePath(upstream.path("")); lib.installHeader(upstream.path("utf8proc.h"), "utf8proc.h"); - lib.linkLibC(); + root_module.link_libc = true; - lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ + root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "utf8proc.c", }, .flags = &.{"-DUTF8PROC_STATIC"} }); } diff --git a/src/build_lua.zig b/src/build_lua.zig index 3d9b634ab1..f1dce0f21c 100644 --- a/src/build_lua.zig +++ b/src/build_lua.zig @@ -4,6 +4,7 @@ const LazyPath = std.Build.LazyPath; pub fn build_nlua0( b: *std.Build, + io: std.Io, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, use_luajit: bool, @@ -59,7 +60,7 @@ pub fn build_nlua0( mod.addIncludePath(b.path("src")); mod.addIncludePath(b.path("src/includes_fixmelater")); - try add_lua_modules(b, target.result, mod, lpeg, use_luajit, true, system_integration_options); + try add_lua_modules(b, io, target.result, mod, lpeg, use_luajit, true, system_integration_options); } // for debugging the nlua0 environment @@ -83,6 +84,7 @@ pub fn build_nlua0( pub fn add_lua_modules( b: *std.Build, + io: std.Io, target: std.Target, mod: *std.Build.Module, lpeg_dep: ?*std.Build.Dependency, @@ -110,7 +112,7 @@ pub fn add_lua_modules( .flags = &flags, }); if (system_integration_options.lpeg) { - if (try findLpeg(b, target)) |lpeg_lib| { + if (try findLpeg(b, io, target)) |lpeg_lib| { mod.addLibraryPath(.{ .cwd_relative = std.fs.path.dirname(lpeg_lib).? }); mod.addObjectFile(.{ .cwd_relative = lpeg_lib }); } @@ -149,33 +151,34 @@ pub fn build_libluv( ) !*std.Build.Step.Compile { const upstream = b.lazyDependency("luv", .{}); const compat53 = b.lazyDependency("lua_compat53", .{}); + var root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + }); const lib = b.addLibrary(.{ .name = "luv", .linkage = .static, - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - }), + .root_module = root_module, }); if (lua) |lua_lib| { - lib.root_module.linkLibrary(lua_lib); + root_module.linkLibrary(lua_lib); } else { const system_lua_lib = if (use_luajit) "luajit" else "lua5.1"; - lib.root_module.linkSystemLibrary(system_lua_lib, .{}); + root_module.linkSystemLibrary(system_lua_lib, .{}); } - lib.linkLibrary(libuv); + root_module.linkLibrary(libuv); if (upstream) |dep| { - lib.addIncludePath(dep.path("src")); + root_module.addIncludePath(dep.path("src")); lib.installHeader(dep.path("src/luv.h"), "luv/luv.h"); - lib.addCSourceFiles(.{ .root = dep.path("src/"), .files = &.{ + root_module.addCSourceFiles(.{ .root = dep.path("src/"), .files = &.{ "luv.c", } }); } if (compat53) |dep| { - lib.addIncludePath(dep.path("c-api")); - lib.addCSourceFiles(.{ .root = dep.path("c-api"), .files = &.{ + root_module.addIncludePath(dep.path("c-api")); + root_module.addCSourceFiles(.{ .root = dep.path("c-api"), .files = &.{ "compat-5.3.c", } }); } @@ -183,7 +186,7 @@ pub fn build_libluv( return lib; } -fn findLpeg(b: *std.Build, target: std.Target) !?[]const u8 { +fn findLpeg(b: *std.Build, io: std.Io, target: std.Target) !?[]const u8 { const filenames = [_][]const u8{ "lpeg_a", "lpeg", @@ -205,10 +208,10 @@ fn findLpeg(b: *std.Build, target: std.Target) !?[]const u8 { try paths.append(b.allocator, b.fmt("{s}/lua/5.1", .{dir})); } for (paths.items) |path| { - var dir = std.fs.openDirAbsolute(path, .{}) catch continue; - defer dir.close(); + var dir = std.Io.Dir.openDirAbsolute(io, path, .{}) catch continue; + defer dir.close(io); for (filenames) |filename| { - dir.access(filename, .{}) catch continue; + dir.access(io, filename, .{}) catch continue; return b.fmt("{s}/{s}", .{ path, filename }); } } diff --git a/src/gen/gen_steps.zig b/src/gen/gen_steps.zig index 794beb8df7..e0f4037641 100644 --- a/src/gen/gen_steps.zig +++ b/src/gen/gen_steps.zig @@ -5,6 +5,7 @@ pub const SourceItem = struct { name: []u8, api_export: bool }; pub fn nvim_gen_sources( b: *std.Build, + io: std.Io, nlua0: *std.Build.Step.Compile, nvim_sources: *std.ArrayList(SourceItem), nvim_headers: *std.ArrayList([]u8), @@ -85,15 +86,15 @@ pub fn nvim_gen_sources( } // Dynamically add all Lua _core/ modules (like CMakeLists.txt does) - if (b.build_root.handle.openDir("runtime/lua/vim/_core", .{ .iterate = true })) |core_dir_handle| { + if (b.build_root.handle.openDir(io, "runtime/lua/vim/_core", .{ .iterate = true })) |core_dir_handle| { var core_dir = core_dir_handle; - defer core_dir.close(); + defer core_dir.close(io); var iter = core_dir.iterate(); var core_files = try std.ArrayList([]const u8).initCapacity(b.allocator, 0); defer core_files.deinit(b.allocator); - while (try iter.next()) |entry| { + while (try iter.next(io)) |entry| { if (entry.kind == .file and std.mem.endsWith(u8, entry.name, ".lua")) { const module_name = try b.allocator.dupe(u8, entry.name[0 .. entry.name.len - 4]); try core_files.append(b.allocator, module_name);