From dc6cf3add95ac80ad4cb31942972f01b31b8998d Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 17 Jul 2025 10:55:43 +0200 Subject: [PATCH] feat(build): build.zig windows support Tested using cross-compiling from linux: zig build -Dcross=true -Dtarget=x86_64-windows nvim_bin Note: not fully functional without a runtime, which still has to be fuddled with manually Macos and windows builds require a recent zig 0.15+dev version As this zig master branch is currently too much in flux, we can't make our CI depend on zig master. Revisit CI after zig 0.15 release or at least feature freeze. --- .github/workflows/test.yml | 2 +- build.zig | 20 ++- build.zig.zon | 11 +- deps/iconv_apple/build.zig | 93 ------------- deps/iconv_apple/build.zig.zon | 12 -- deps/iconv_apple/include/os/variant_private.h | 1 - deps/libuv/build.zig | 128 ------------------ deps/libuv/build.zig.zon | 12 -- deps/utf8proc/build.zig | 2 +- 9 files changed, 25 insertions(+), 256 deletions(-) delete mode 100644 deps/iconv_apple/build.zig delete mode 100644 deps/iconv_apple/build.zig.zon delete mode 100644 deps/iconv_apple/include/os/variant_private.h delete mode 100644 deps/libuv/build.zig delete mode 100644 deps/libuv/build.zig.zon diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fbb4271f99..48484facf6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -209,7 +209,7 @@ jobs: zig-build: runs-on: ubuntu-24.04 timeout-minutes: 45 - name: build using zig build + name: build using zig build (linux) steps: - uses: actions/checkout@v4 - uses: mlugg/setup-zig@v2 diff --git a/build.zig b/build.zig index 79c35e8907..68e693b296 100644 --- a/build.zig +++ b/build.zig @@ -70,11 +70,14 @@ pub fn build(b: *std.Build) !void { const lpeg = b.dependency("lpeg", .{}); - const iconv_apple = if (cross_compiling and is_darwin) b.lazyDependency("iconv_apple", .{ .target = target, .optimize = optimize }) else null; + const iconv = if (is_windows or is_darwin) b.lazyDependency("libiconv", .{ .target = target, .optimize = optimize }) else null; // this is currently not necessary, as ziglua currently doesn't use lazy dependencies // to circumvent ziglua.artifact() failing in a bad way. const lua = lazyArtifact(ziglua, "lua") orelse return; + if (cross_compiling) { + _ = lazyArtifact(ziglua_host, "lua") orelse return; + } // const lua = ziglua.artifact("lua"); const libuv_dep = b.dependency("libuv", .{ .target = target, .optimize = optimize }); @@ -234,7 +237,7 @@ pub fn build(b: *std.Build) !void { // TODO(zig): using getEmittedIncludeTree() is ugly af. we want unittests // to reuse the std.build.Module include_path thing - const include_path = [_]LazyPath{ + const unittest_include_path = [_]LazyPath{ b.path("src/"), gen_config.getDirectory(), lua.getEmittedIncludeTree(), @@ -243,6 +246,7 @@ pub fn build(b: *std.Build) !void { utf8proc.artifact("utf8proc").getEmittedIncludeTree(), unibilium.artifact("unibilium").getEmittedIncludeTree(), treesitter.artifact("tree-sitter").getEmittedIncludeTree(), + if (iconv) |dep| dep.artifact("iconv").getEmittedIncludeTree() else b.path("UNUSED_PATH/"), }; const gen_headers, const funcs_data = try gen.nvim_gen_sources(b, nlua0, &nvim_sources, &nvim_headers, &api_headers, versiondef_git, version_lua); @@ -267,12 +271,13 @@ pub fn build(b: *std.Build) !void { nvim_exe.linkLibrary(lua); nvim_exe.linkLibrary(libuv); nvim_exe.linkLibrary(libluv); - if (iconv_apple) |iconv| { - nvim_exe.linkLibrary(iconv.artifact("iconv")); - } + if (iconv) |dep| nvim_exe.linkLibrary(dep.artifact("iconv")); nvim_exe.linkLibrary(utf8proc.artifact("utf8proc")); nvim_exe.linkLibrary(unibilium.artifact("unibilium")); nvim_exe.linkLibrary(treesitter.artifact("tree-sitter")); + if (is_windows) { + nvim_exe.linkSystemLibrary("netapi32"); + } nvim_exe.addIncludePath(b.path("src")); nvim_exe.addIncludePath(gen_config.getDirectory()); nvim_exe.addIncludePath(gen_headers.getDirectory()); @@ -304,6 +309,9 @@ pub fn build(b: *std.Build) !void { "-D_GNU_SOURCE", if (support_unittests) "-DUNIT_TESTING" else "", if (use_luajit) "" else "-DNVIM_VENDOR_BIT", + if (is_windows) "-DMSWIN" else "", + if (is_windows) "-DWIN32_LEAN_AND_MEAN" else "", + if (is_windows) "-DUTF8PROC_STATIC" else "", }; nvim_exe.addCSourceFiles(.{ .files = src_paths, .flags = &flags }); @@ -359,7 +367,7 @@ pub fn build(b: *std.Build) !void { const parser_query = b.dependency("treesitter_query", .{ .target = target, .optimize = optimize }); test_deps.dependOn(add_ts_parser(b, "query", parser_query.path("."), false, target, optimize)); - const unit_headers: ?[]const LazyPath = if (support_unittests) &(include_path ++ .{gen_headers.getDirectory()}) else null; + const unit_headers: ?[]const LazyPath = if (support_unittests) &(unittest_include_path ++ .{gen_headers.getDirectory()}) else null; try tests.test_steps(b, nvim_exe, test_deps, lua_dev_deps.path("."), test_config_step.getDirectory(), unit_headers); } diff --git a/build.zig.zon b/build.zig.zon index 44a212bb63..21e4a39b39 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -25,10 +25,17 @@ .url = "git+https://github.com/tree-sitter/tree-sitter#d87921bb9c39b0b06c811f2082f9a9991cdca027", .hash = "tree_sitter-0.26.0-Tw2sRxO7CwC0NyDrSygSi7UXRHMNUFEF8GRq6dK81lRF", }, - .libuv = .{ .path = "./deps/libuv" }, + .libuv = .{ + .url = "git+https://github.com/allyourcodebase/libuv#a2dfd385bd2a00d6d290fda85a40a55a9d6cffc5", + .hash = "libuv-1.51.0-htqqv6liAADxBLIBCZT-qUh_3nRRwtNYsOFQOUmrd_sx", + }, .utf8proc = .{ .path = "./deps/utf8proc/" }, .unibilium = .{ .path = "./deps/unibilium/" }, - .iconv_apple = .{ .path = "./deps/iconv_apple/", .lazy = true }, + .libiconv = .{ + .url = "git+https://github.com/allyourcodebase/libiconv#9def4c8a1743380e85bcedb80f2c15b455e236f3", + .hash = "libiconv-1.18.0-p9sJwWnqAACzVYeWgXB5r5lOQ74XwTPlptixV0JPRO28", + .lazy = true, + }, .lua_dev_deps = .{ .url = "https://github.com/neovim/deps/raw/06ef2b58b0876f8de1a3f5a710473dcd7afff251/opt/lua-dev-deps.tar.gz", .hash = "N-V-__8AAGevEQCHAkCozca5AIdN9DFc3Luf3g3r2AcbyOrm", diff --git a/deps/iconv_apple/build.zig b/deps/iconv_apple/build.zig deleted file mode 100644 index 9c5d729562..0000000000 --- a/deps/iconv_apple/build.zig +++ /dev/null @@ -1,93 +0,0 @@ -const std = @import("std"); - -pub fn build(b: *std.Build) !void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - - const upstream = b.dependency("libiconv", .{}); - const lib = b.addLibrary(.{ - .name = "iconv", - .linkage = .static, - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - }), - }); - - lib.addIncludePath(b.path("include/")); - lib.addIncludePath(upstream.path("")); - lib.addIncludePath(upstream.path("citrus/")); - lib.addIncludePath(upstream.path("libcharset/")); - lib.addIncludePath(upstream.path("libiconv_modules/UTF8/")); - // zig any-macos-any headers already includes iconv, it just cannot link without a SDK - // lib.installHeader(upstream.path("iconv.h"), "iconv.h"); - - lib.linkLibC(); - - lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ - "citrus/bsd_iconv.c", - "citrus/citrus_bcs.c", - "citrus/citrus_bcs_strtol.c", - "citrus/citrus_bcs_strtoul.c", - "citrus/citrus_csmapper.c", - "citrus/citrus_db.c", - "citrus/citrus_db_factory.c", - "citrus/citrus_db_hash.c", - "citrus/citrus_esdb.c", - "citrus/citrus_hash.c", - "citrus/citrus_iconv.c", - "citrus/citrus_lookup.c", - "citrus/citrus_lookup_factory.c", - "citrus/citrus_mapper.c", - "citrus/citrus_memstream.c", - "citrus/citrus_mmap.c", - "citrus/citrus_module.c", - "citrus/citrus_none.c", - "citrus/citrus_pivot_factory.c", - "citrus/citrus_prop.c", - "citrus/citrus_stdenc.c", - "citrus/__iconv.c", - "citrus/iconv.c", - "citrus/iconv_canonicalize.c", - "citrus/iconv_close.c", - "citrus/iconv_compat.c", - "citrus/iconvctl.c", - "citrus/__iconv_free_list.c", - "citrus/__iconv_get_list.c", - "citrus/iconvlist.c", - "citrus/iconv_open.c", - "citrus/iconv_open_into.c", - "citrus/iconv_set_relocation_prefix.c", - "libcharset/libcharset.c", - "libiconv_modules/BIG5/citrus_big5.c", - "libiconv_modules/DECHanyu/citrus_dechanyu.c", - "libiconv_modules/DECKanji/citrus_deckanji.c", - "libiconv_modules/EUC/citrus_euc.c", - "libiconv_modules/EUCTW/citrus_euctw.c", - "libiconv_modules/GBK2K/citrus_gbk2k.c", - "libiconv_modules/HZ/citrus_hz.c", - "libiconv_modules/iconv_none/citrus_iconv_none.c", - "libiconv_modules/iconv_std/citrus_iconv_std.c", - "libiconv_modules/ISO2022/citrus_iso2022.c", - "libiconv_modules/JOHAB/citrus_johab.c", - "libiconv_modules/mapper_646/citrus_mapper_646.c", - "libiconv_modules/mapper_none/citrus_mapper_none.c", - "libiconv_modules/mapper_serial/citrus_mapper_serial.c", - "libiconv_modules/mapper_std/citrus_mapper_std.c", - "libiconv_modules/mapper_zone/citrus_mapper_zone.c", - "libiconv_modules/MSKanji/citrus_mskanji.c", - "libiconv_modules/UES/citrus_ues.c", - "libiconv_modules/UTF1632/citrus_utf1632.c", - "libiconv_modules/UTF7/citrus_utf7.c", - "libiconv_modules/UTF8/citrus_utf8.c", - "libiconv_modules/UTF8MAC/citrus_utf8mac.c", - "libiconv_modules/VIQR/citrus_viqr.c", - "libiconv_modules/ZW/citrus_zw.c", - }, .flags = &.{ - "-D_PATH_I18NMODULE=\"/usr/lib/i18n\"", - "-D_PATH_ESDB=\"/usr/share/i18n/esdb\"", - "-D_PATH_CSMAPPER=\"/usr/share/i18n/csmapper\"", - } }); - - b.installArtifact(lib); -} diff --git a/deps/iconv_apple/build.zig.zon b/deps/iconv_apple/build.zig.zon deleted file mode 100644 index e4c26c2728..0000000000 --- a/deps/iconv_apple/build.zig.zon +++ /dev/null @@ -1,12 +0,0 @@ -.{ - .name = "libiconv", - .version = "107.0.0", - .paths = .{""}, - - .dependencies = .{ - .libiconv = .{ - .url = "git+https://github.com/apple-oss-distributions/libiconv?ref=libiconv-107#a3f3b2c76dbf8ba11881debc6bcb4e309958d252", - .hash = "N-V-__8AAKce8wQq3Mp26YIvUGtazS8KPihcFS4vSGgzQf1x", - }, - }, -} diff --git a/deps/iconv_apple/include/os/variant_private.h b/deps/iconv_apple/include/os/variant_private.h deleted file mode 100644 index d3e074337d..0000000000 --- a/deps/iconv_apple/include/os/variant_private.h +++ /dev/null @@ -1 +0,0 @@ -#define os_variant_has_internal_content(sys) false diff --git a/deps/libuv/build.zig b/deps/libuv/build.zig deleted file mode 100644 index d26a974c91..0000000000 --- a/deps/libuv/build.zig +++ /dev/null @@ -1,128 +0,0 @@ -const std = @import("std"); - -// Based on mitchellh/zig-libuv, with changes. -pub fn build(b: *std.Build) !void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - - const upstream = b.dependency("libuv", .{}); - const lib = b.addLibrary(.{ - .name = "uv", - .linkage = .static, - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - }), - }); - - lib.addIncludePath(upstream.path("include")); - lib.addIncludePath(upstream.path("src")); - - lib.installHeadersDirectory(upstream.path("include"), ".", .{}); - - if (target.result.os.tag == .windows) { - lib.linkSystemLibrary("psapi"); - lib.linkSystemLibrary("user32"); - lib.linkSystemLibrary("advapi32"); - lib.linkSystemLibrary("iphlpapi"); - lib.linkSystemLibrary("userenv"); - lib.linkSystemLibrary("ws2_32"); - } - if (target.result.os.tag == .linux) { - lib.linkSystemLibrary("pthread"); - } - lib.linkLibC(); - - if (target.result.os.tag != .windows) { - lib.root_module.addCMacro("FILE_OFFSET_BITS", "64"); - lib.root_module.addCMacro("_LARGEFILE_SOURCE", ""); - } - - if (target.result.os.tag == .linux) { - lib.root_module.addCMacro("_GNU_SOURCE", ""); - lib.root_module.addCMacro("_POSIX_C_SOURCE", "200112"); - } - - if (target.result.os.tag.isDarwin()) { - lib.root_module.addCMacro("_DARWIN_UNLIMITED_SELECT", "1"); - lib.root_module.addCMacro("_DARWIN_USE_64_BIT_INODE", "1"); - } - - const root = upstream.path(""); - - // C files common to all platforms - lib.addCSourceFiles(.{ .root = root, .files = &.{ - "src/fs-poll.c", - "src/idna.c", - "src/inet.c", - "src/random.c", - "src/strscpy.c", - "src/strtok.c", - "src/threadpool.c", - "src/timer.c", - "src/uv-common.c", - "src/uv-data-getter-setters.c", - "src/version.c", - } }); - - if (target.result.os.tag != .windows) { - lib.addCSourceFiles(.{ .root = root, .files = &.{ - "src/unix/async.c", - "src/unix/core.c", - "src/unix/dl.c", - "src/unix/fs.c", - "src/unix/getaddrinfo.c", - "src/unix/getnameinfo.c", - "src/unix/loop-watcher.c", - "src/unix/loop.c", - "src/unix/pipe.c", - "src/unix/poll.c", - "src/unix/process.c", - "src/unix/random-devurandom.c", - "src/unix/signal.c", - "src/unix/stream.c", - "src/unix/tcp.c", - "src/unix/thread.c", - "src/unix/tty.c", - "src/unix/udp.c", - } }); - } - - if (target.result.os.tag == .linux or target.result.os.tag.isDarwin()) { - lib.addCSourceFiles(.{ .root = root, .files = &.{ - "src/unix/proctitle.c", - } }); - } - - if (target.result.os.tag == .linux) { - lib.addCSourceFiles(.{ .root = root, .files = &.{ - "src/unix/linux.c", - "src/unix/procfs-exepath.c", - "src/unix/random-getrandom.c", - "src/unix/random-sysctl-linux.c", - } }); - } - - if (target.result.os.tag.isBSD()) { - lib.addCSourceFiles(.{ .root = root, .files = &.{ - "src/unix/bsd-ifaddrs.c", - "src/unix/kqueue.c", - } }); - } - - if (target.result.os.tag.isDarwin() or target.result.os.tag == .openbsd) { - lib.addCSourceFiles(.{ .root = root, .files = &.{ - "src/unix/random-getentropy.c", - } }); - } - - if (target.result.os.tag.isDarwin()) { - lib.addCSourceFiles(.{ .root = root, .files = &.{ - "src/unix/darwin-proctitle.c", - "src/unix/darwin.c", - "src/unix/fsevents.c", - } }); - } - - b.installArtifact(lib); -} diff --git a/deps/libuv/build.zig.zon b/deps/libuv/build.zig.zon deleted file mode 100644 index 06bd25a5db..0000000000 --- a/deps/libuv/build.zig.zon +++ /dev/null @@ -1,12 +0,0 @@ -.{ - .name = "libuv", - .version = "1.51.0", - .paths = .{""}, - - .dependencies = .{ - .libuv = .{ - .url = "git+https://github.com/libuv/libuv?ref=v1.51.0#76fb3b73da3f8ddaeeb87d23fda04b9bda219f5e", - .hash = "N-V-__8AAExNRADXPh6GLMmWlqC2EVkp6hzH9wPuzjh_eSkE", - }, - }, -} diff --git a/deps/utf8proc/build.zig b/deps/utf8proc/build.zig index 1b6c55fb8c..0bdd4fa408 100644 --- a/deps/utf8proc/build.zig +++ b/deps/utf8proc/build.zig @@ -21,7 +21,7 @@ pub fn build(b: *std.Build) !void { lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ "utf8proc.c", - } }); + }, .flags = &.{"-DUTF8PROC_STATIC"} }); b.installArtifact(lib); }