From fe9cf6a26691fb7dbfc260eb169a801ca4b9790f Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Fri, 11 Sep 2026 09:08:05 -0700 Subject: [PATCH] build: fully transition away from cImport/addTranslateC This migrates all remaining uses of cImport (and addTranslateC for good measure) to using translate-c for C translation, ensuring that we are ready for when cImport is removed from the language, and also that all sources of C translation are using the same snapshot of the external package (when can then be updated when we need to fix something). A couple of notes: * A few options have been added to support the new translations, namely the ability to link libraries (passed through to linkLibrary on the Translator side) and whether or not to initialize default values (looks like cImport did this without a way to control it, but translate-c does not do it by default). * Using the new library linking option actually simplifies the process of translating a number of the C packages as we have been shipping the necessary headers for these packages already with the applicable libraries. For some of the more complex translation processes though, we still include the appropriate directories directly. --- pkg/dcimgui/build.zig | 79 ++++++++++++++++------------- pkg/dcimgui/build.zig.zon | 1 + pkg/dcimgui/main.zig | 16 ++---- pkg/fontconfig/build.zig | 55 ++++++++++---------- pkg/fontconfig/build.zig.zon | 1 + pkg/fontconfig/c.zig | 4 +- pkg/freetype/build.zig | 62 +++++++++++------------ pkg/freetype/build.zig.zon | 1 + pkg/freetype/c.zig | 4 +- pkg/glslang/build.zig | 27 ++++++---- pkg/glslang/build.zig.zon | 1 + pkg/glslang/c.zig | 5 +- pkg/gtk4-layer-shell/build.zig | 57 ++++++++------------- pkg/gtk4-layer-shell/src/main.zig | 2 +- pkg/harfbuzz/build.zig | 29 +++++------ pkg/oniguruma/build.zig | 49 ++++++++---------- pkg/oniguruma/build.zig.zon | 1 + pkg/oniguruma/c.zig | 4 +- pkg/opengl/Buffer.zig | 2 +- pkg/opengl/Framebuffer.zig | 2 +- pkg/opengl/Program.zig | 2 +- pkg/opengl/Renderbuffer.zig | 2 +- pkg/opengl/Sampler.zig | 2 +- pkg/opengl/Shader.zig | 2 +- pkg/opengl/Texture.zig | 2 +- pkg/opengl/VertexArray.zig | 2 +- pkg/opengl/build.zig | 21 +++++--- pkg/opengl/build.zig.zon | 10 ++++ pkg/opengl/draw.zig | 2 +- pkg/opengl/egl.zig | 2 +- pkg/opengl/errors.zig | 2 +- pkg/opengl/extensions.zig | 2 +- pkg/opengl/gl.c | 2 - pkg/opengl/glad.zig | 2 +- pkg/opengl/main.zig | 2 +- pkg/opengl/primitives.zig | 2 +- pkg/sentry/build.zig | 11 +++- pkg/sentry/build.zig.zon | 1 + pkg/sentry/c.zig | 4 +- pkg/spirv-cross/build.zig | 51 ++++++++++--------- pkg/spirv-cross/build.zig.zon | 1 + pkg/spirv-cross/c.zig | 4 +- pkg/translate-c/build.zig | 12 +++++ src/apprt/gtk/winproto/x11.zig | 6 +-- src/build/SharedDeps.zig | 84 +++++++++++++++++-------------- src/config/Config.zig | 4 +- src/os/desktop.zig | 4 +- src/os/passwd.zig | 6 +-- src/stb/main.zig | 5 +- src/termio/Exec.zig | 6 +-- 50 files changed, 327 insertions(+), 333 deletions(-) create mode 100644 pkg/opengl/build.zig.zon delete mode 100644 pkg/opengl/gl.c diff --git a/pkg/dcimgui/build.zig b/pkg/dcimgui/build.zig index f74d3673b..72ddd4355 100644 --- a/pkg/dcimgui/build.zig +++ b/pkg/dcimgui/build.zig @@ -1,5 +1,6 @@ const std = @import("std"); const NativeTargetInfo = std.zig.system.NativeTargetInfo; +const translate_c = @import("translate_c"); pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); @@ -50,37 +51,41 @@ pub fn build(b: *std.Build) !void { } } - // Flags for C compilation, common to all. - var flags: std.ArrayList([]const u8) = .empty; - defer flags.deinit(b.allocator); - try flags.appendSlice(b.allocator, &.{ + // Split -D flags off from the rest of the flags, so that we can use them + // in C translation. + var define_flags: std.ArrayList([]const u8) = .empty; + defer define_flags.deinit(b.allocator); + try define_flags.appendSlice(b.allocator, &.{ "-DIMGUI_HAS_DOCK=1", "-DIMGUI_USE_WCHAR32=1", "-DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1", }); + if (freetype) try define_flags.appendSlice(b.allocator, &.{ + "-DIMGUI_ENABLE_FREETYPE=1", + }); + if (backend_opengl3) try define_flags.appendSlice(b.allocator, &.{ + "-DZIGPKG_IMGUI_ENABLE_OPENGL3=1", + }); + if (target.result.os.tag == .windows) { + try define_flags.appendSlice(b.allocator, &.{ + "-DIMGUI_IMPL_API=extern\t\"C\"\t__declspec(dllexport)", + }); + } else { + try define_flags.appendSlice(b.allocator, &.{ + "-DIMGUI_IMPL_API=extern\t\"C\"", + }); + } + + var all_flags: std.ArrayList([]const u8) = .empty; + try all_flags.appendSlice(b.allocator, define_flags.items); if (target.result.abi == .msvc) { - try flags.appendSlice(b.allocator, &.{ + try all_flags.appendSlice(b.allocator, &.{ "-fno-sanitize=undefined", "-fno-sanitize-trap=undefined", }); } - if (freetype) try flags.appendSlice(b.allocator, &.{ - "-DIMGUI_ENABLE_FREETYPE=1", - }); - if (backend_opengl3) try flags.appendSlice(b.allocator, &.{ - "-DZIGPKG_IMGUI_ENABLE_OPENGL3=1", - }); - if (target.result.os.tag == .windows) { - try flags.appendSlice(b.allocator, &.{ - "-DIMGUI_IMPL_API=extern\t\"C\"\t__declspec(dllexport)", - }); - } else { - try flags.appendSlice(b.allocator, &.{ - "-DIMGUI_IMPL_API=extern\t\"C\"", - }); - } if (target.result.os.tag == .freebsd or target.result.abi == .musl) { - try flags.append(b.allocator, "-fPIC"); + try all_flags.append(b.allocator, "-fPIC"); } // Add the core Dear Imgui source files @@ -95,7 +100,7 @@ pub fn build(b: *std.Build) !void { "imgui_widgets.cpp", "imgui.cpp", }, - .flags = flags.items, + .flags = all_flags.items, }); lib.installHeadersDirectory( @@ -107,7 +112,7 @@ pub fn build(b: *std.Build) !void { if (freetype) { lib.root_module.addCSourceFile(.{ .file = upstream.path("misc/freetype/imgui_freetype.cpp"), - .flags = flags.items, + .flags = all_flags.items, }); if (b.systemIntegrationOption("freetype", .{})) { @@ -119,12 +124,6 @@ pub fn build(b: *std.Build) !void { .@"enable-libpng" = true, }); lib.root_module.linkLibrary(freetype_dep.artifact("freetype")); - if (freetype_dep.builder.lazyDependency( - "freetype", - .{}, - )) |freetype_upstream| { - mod.addIncludePath(freetype_upstream.path("include")); - } } } @@ -132,7 +131,7 @@ pub fn build(b: *std.Build) !void { lib.root_module.addCSourceFiles(.{ .root = upstream.path("backends"), .files = &.{"imgui_impl_metal.mm"}, - .flags = flags.items, + .flags = all_flags.items, }); lib.installHeadersDirectory( upstream.path("backends"), @@ -144,7 +143,7 @@ pub fn build(b: *std.Build) !void { lib.root_module.addCSourceFiles(.{ .root = upstream.path("backends"), .files = &.{"imgui_impl_osx.mm"}, - .flags = flags.items, + .flags = all_flags.items, }); lib.installHeadersDirectory( upstream.path("backends"), @@ -156,7 +155,7 @@ pub fn build(b: *std.Build) !void { lib.root_module.addCSourceFiles(.{ .root = upstream.path("backends"), .files = &.{"imgui_impl_opengl3.cpp"}, - .flags = flags.items, + .flags = all_flags.items, }); lib.installHeadersDirectory( upstream.path("backends"), @@ -175,12 +174,12 @@ pub fn build(b: *std.Build) !void { "dcimgui.cpp", "dcimgui_internal.cpp", }, - .flags = flags.items, + .flags = all_flags.items, }); lib.root_module.addCSourceFiles(.{ .root = b.path(""), .files = &.{"ext.cpp"}, - .flags = flags.items, + .flags = all_flags.items, }); lib.installHeadersDirectory( @@ -190,6 +189,18 @@ pub fn build(b: *std.Build) !void { ); } + // C translation + try translate_c.addImportToModule(b, "dcimgui_c", mod, .{ + .source = .{ .includes = .{ + .files = &.{.{ .path = "dcimgui.h" }}, + } }, + .target = target, + .optimize = optimize, + .link_libs = &.{lib}, + .default_init = true, + .extra_args = define_flags.items, + }); + const test_exe = b.addTest(.{ .name = "test", .root_module = b.createModule(.{ diff --git a/pkg/dcimgui/build.zig.zon b/pkg/dcimgui/build.zig.zon index c488e6122..90eb0057d 100644 --- a/pkg/dcimgui/build.zig.zon +++ b/pkg/dcimgui/build.zig.zon @@ -22,5 +22,6 @@ .apple_sdk = .{ .path = "../apple-sdk" }, .freetype = .{ .path = "../freetype" }, + .translate_c = .{ .path = "../translate-c" }, }, } diff --git a/pkg/dcimgui/main.zig b/pkg/dcimgui/main.zig index 40a4325c0..7f85d495b 100644 --- a/pkg/dcimgui/main.zig +++ b/pkg/dcimgui/main.zig @@ -1,14 +1,6 @@ pub const build_options = @import("build_options"); -pub const c = @cImport({ - // This is set during the build so it also has to be set - // during import time to get the right types. Without this - // you get stack size mismatches on some structs. - @cDefine("IMGUI_USE_WCHAR32", "1"); - - @cDefine("IMGUI_HAS_DOCK", "1"); - @cInclude("dcimgui.h"); -}); +pub const c = @import("dcimgui_c"); // OpenGL3 backend pub extern fn ImGui_ImplOpenGL3_Init(glsl_version: ?[*:0]const u8) callconv(.c) bool; @@ -31,9 +23,9 @@ pub extern fn ImGui_ImplOSX_Init(*anyopaque) callconv(.c) bool; pub extern fn ImGui_ImplOSX_Shutdown() callconv(.c) void; pub extern fn ImGui_ImplOSX_NewFrame(*anyopaque) callconv(.c) void; -// Internal API types and functions from dcimgui_internal.h -// We declare these manually because the internal header contains bitfields -// that Zig's cImport cannot translate. +// Internal API types and functions from dcimgui_internal.h We declare these +// manually because the internal header contains bitfields that translate-c has +// trouble with. pub const ImGuiDockNodeFlagsPrivate = struct { pub const DockSpace: c.ImGuiDockNodeFlags = 1 << 10; pub const CentralNode: c.ImGuiDockNodeFlags = 1 << 11; diff --git a/pkg/fontconfig/build.zig b/pkg/fontconfig/build.zig index a1f43eac7..53322e5c4 100644 --- a/pkg/fontconfig/build.zig +++ b/pkg/fontconfig/build.zig @@ -1,5 +1,6 @@ const std = @import("std"); const build_zon = @import("build.zig.zon"); +const translate_c = @import("translate_c"); const NativeTargetInfo = std.zig.system.NativeTargetInfo; // NOTE: This build is becoming more and more complex; we need to continually @@ -62,46 +63,41 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); - // For dynamic linking, we prefer dynamic linking and to search by - // mode first. Mode first will search all paths for a dynamic library - // before falling back to static. - const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ - .preferred_link_mode = .dynamic, - .search_strategy = .mode_first, - }; - const test_exe = b.addTest(.{ .name = "test", - .root_module = b.createModule(.{ - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, - }), + .root_module = module, }); const tests_run = b.addRunArtifact(test_exe); const test_step = b.step("test", "Run tests"); test_step.dependOn(&tests_run.step); - if (b.systemIntegrationOption("fontconfig", .{})) { - module.linkSystemLibrary("fontconfig", dynamic_link_opts); - test_exe.root_module.linkSystemLibrary("fontconfig", dynamic_link_opts); - } else { - const lib = try buildLib(b, module, .{ + const lib: union(enum) { + system, + static: *std.Build.Step.Compile, + } = if (b.systemIntegrationOption("fontconfig", .{})) + .system + else + .{ .static = try buildLib(b, .{ .target = target, .optimize = optimize, .libxml2_enabled = libxml2_enabled, .libxml2_iconv_enabled = libxml2_iconv_enabled, .freetype_enabled = freetype_enabled, + }) }; - .dynamic_link_opts = dynamic_link_opts, - }); - - test_exe.root_module.linkLibrary(lib); - } + try translate_c.addImportToModule(b, "fontconfig_c", module, .{ + .source = .{ .includes = .{ + .files = &.{.{ .path = "fontconfig/fontconfig.h" }}, + } }, + .target = target, + .optimize = optimize, + .link_system_libs = if (lib == .system) &.{"fontconfig"} else &.{}, + .link_libs = if (lib == .static) &.{lib.static} else &.{}, + }); } -fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Build.Step.Compile { +fn buildLib(b: *std.Build, options: anytype) !*std.Build.Step.Compile { const target = options.target; const optimize = options.optimize; @@ -119,7 +115,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu .linkage = .static, }); - const dynamic_link_opts = options.dynamic_link_opts; + // For dynamic linking, we prefer dynamic linking and to search by + // mode first. Mode first will search all paths for a dynamic library + // before falling back to static. + const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ + .preferred_link_mode = .dynamic, + .search_strategy = .mode_first, + }; if (target.result.os.tag != .windows) { lib.root_module.linkSystemLibrary("pthread", dynamic_link_opts); @@ -138,7 +140,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu "override/src", }) |override_dir| { lib.root_module.addIncludePath(b.path(override_dir)); - module.addIncludePath(b.path(override_dir)); } var flags: std.ArrayList([]const u8) = .empty; @@ -310,7 +311,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu if (b.lazyDependency("fontconfig", .{})) |upstream| { lib.root_module.addIncludePath(upstream.path("")); - module.addIncludePath(upstream.path("")); lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, @@ -337,7 +337,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu } b.installArtifact(lib); - return lib; } diff --git a/pkg/fontconfig/build.zig.zon b/pkg/fontconfig/build.zig.zon index 5249219c6..fcb2af487 100644 --- a/pkg/fontconfig/build.zig.zon +++ b/pkg/fontconfig/build.zig.zon @@ -12,5 +12,6 @@ .freetype = .{ .path = "../freetype", .lazy = true }, .libxml2 = .{ .path = "../libxml2", .lazy = true }, + .translate_c = .{ .path = "../translate-c" }, }, } diff --git a/pkg/fontconfig/c.zig b/pkg/fontconfig/c.zig index 6e8ae76bc..26a5e775f 100644 --- a/pkg/fontconfig/c.zig +++ b/pkg/fontconfig/c.zig @@ -1,3 +1 @@ -pub const c = @cImport({ - @cInclude("fontconfig/fontconfig.h"); -}); +pub const c = @import("fontconfig_c"); diff --git a/pkg/freetype/build.zig b/pkg/freetype/build.zig index c1f4535c7..827270040 100644 --- a/pkg/freetype/build.zig +++ b/pkg/freetype/build.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const translate_c = @import("translate_c"); pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); @@ -11,53 +12,43 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); - // For dynamic linking, we prefer dynamic linking and to search by - // mode first. Mode first will search all paths for a dynamic library - // before falling back to static. - const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ - .preferred_link_mode = .dynamic, - .search_strategy = .mode_first, - }; - var test_exe: ?*std.Build.Step.Compile = null; if (target.query.isNative()) { test_exe = b.addTest(.{ .name = "test", - .root_module = b.createModule(.{ - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, - }), + .root_module = module, }); const tests_run = b.addRunArtifact(test_exe.?); const test_step = b.step("test", "Run tests"); test_step.dependOn(&tests_run.step); } - module.addIncludePath(b.path("")); - - if (b.systemIntegrationOption("freetype", .{})) { - module.linkSystemLibrary("freetype2", dynamic_link_opts); - if (test_exe) |exe| { - exe.root_module.linkSystemLibrary("freetype2", dynamic_link_opts); - } - } else { - const lib = try buildLib(b, module, .{ + const lib: union(enum) { + system, + static: *std.Build.Step.Compile, + } = if (b.systemIntegrationOption("freetype", .{})) + .system + else + .{ .static = try buildLib(b, .{ .target = target, .optimize = optimize, - .libpng_enabled = libpng_enabled, + }) }; - .dynamic_link_opts = dynamic_link_opts, - }); - - if (test_exe) |exe| { - exe.root_module.linkLibrary(lib); - } - } + try translate_c.addImportToModule(b, "freetype_c", module, .{ + .source = .{ .includes = .{ + .files = &.{.{ .path = "freetype-zig.h" }}, + } }, + .target = target, + .optimize = optimize, + .link_system_libs = if (lib == .system) &.{"freetype2"} else &.{}, + .link_libs = if (lib == .static) &.{lib.static} else &.{}, + .include_paths = &.{b.path("")}, + .default_init = true, + }); } -fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Build.Step.Compile { +fn buildLib(b: *std.Build, options: anytype) !*std.Build.Step.Compile { const target = options.target; const optimize = options.optimize; @@ -97,7 +88,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu try flags.append(b.allocator, "-fPIC"); } - const dynamic_link_opts = options.dynamic_link_opts; + // For dynamic linking, we prefer dynamic linking and to search by + // mode first. Mode first will search all paths for a dynamic library + // before falling back to static. + const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ + .preferred_link_mode = .dynamic, + .search_strategy = .mode_first, + }; // Zlib if (b.systemIntegrationOption("zlib", .{})) { @@ -125,7 +122,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu if (b.lazyDependency("freetype", .{})) |upstream| { lib.root_module.addIncludePath(upstream.path("include")); - module.addIncludePath(upstream.path("include")); lib.root_module.addCSourceFiles(.{ .root = upstream.path(""), .files = srcs, diff --git a/pkg/freetype/build.zig.zon b/pkg/freetype/build.zig.zon index 8ed1516b1..b0244365d 100644 --- a/pkg/freetype/build.zig.zon +++ b/pkg/freetype/build.zig.zon @@ -13,6 +13,7 @@ .apple_sdk = .{ .path = "../apple-sdk" }, .libpng = .{ .path = "../libpng" }, + .translate_c = .{ .path = "../translate-c" }, .zlib = .{ .path = "../zlib" }, }, } diff --git a/pkg/freetype/c.zig b/pkg/freetype/c.zig index 9431abeb6..bfe064019 100644 --- a/pkg/freetype/c.zig +++ b/pkg/freetype/c.zig @@ -1,3 +1 @@ -pub const c = @cImport({ - @cInclude("freetype-zig.h"); -}); +pub const c = @import("freetype_c"); diff --git a/pkg/glslang/build.zig b/pkg/glslang/build.zig index 92e614b1c..3a494fe03 100644 --- a/pkg/glslang/build.zig +++ b/pkg/glslang/build.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const translate_c = @import("translate_c"); pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); @@ -10,23 +11,27 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); - const upstream = b.lazyDependency("glslang", .{}); - const lib = try buildGlslang(b, upstream, target, optimize); + const lib = try buildGlslang(b, target, optimize); b.installArtifact(lib); - if (upstream) |v| module.addIncludePath(v.path("")); - module.addIncludePath(b.path("override")); + try translate_c.addImportToModule(b, "glslang_c", module, .{ + .source = .{ .includes = .{ + .files = &.{ + .{ .path = "glslang/Include/glslang_c_interface.h" }, + .{ .path = "glslang/Public/resource_limits_c.h" }, + }, + } }, + .target = target, + .optimize = optimize, + .link_libs = &.{lib}, + .default_init = true, + }); if (target.query.isNative()) { const test_exe = b.addTest(.{ .name = "test", - .root_module = b.createModule(.{ - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, - }), + .root_module = module, }); - test_exe.root_module.linkLibrary(lib); const tests_run = b.addRunArtifact(test_exe); const test_step = b.step("test", "Run tests"); test_step.dependOn(&tests_run.step); @@ -38,10 +43,10 @@ pub fn build(b: *std.Build) !void { fn buildGlslang( b: *std.Build, - upstream_: ?*std.Build.Dependency, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, ) !*std.Build.Step.Compile { + const upstream_ = b.lazyDependency("glslang", .{}); const lib = b.addLibrary(.{ .name = "glslang", .root_module = b.createModule(.{ diff --git a/pkg/glslang/build.zig.zon b/pkg/glslang/build.zig.zon index 252237e58..1582d1011 100644 --- a/pkg/glslang/build.zig.zon +++ b/pkg/glslang/build.zig.zon @@ -12,5 +12,6 @@ }, .apple_sdk = .{ .path = "../apple-sdk" }, + .translate_c = .{ .path = "../translate-c" }, }, } diff --git a/pkg/glslang/c.zig b/pkg/glslang/c.zig index c00108463..1abfaa721 100644 --- a/pkg/glslang/c.zig +++ b/pkg/glslang/c.zig @@ -1,4 +1 @@ -pub const c = @cImport({ - @cInclude("glslang/Include/glslang_c_interface.h"); - @cInclude("glslang/Public/resource_limits_c.h"); -}); +pub const c = @import("glslang_c"); diff --git a/pkg/gtk4-layer-shell/build.zig b/pkg/gtk4-layer-shell/build.zig index 59fcf6a81..65c10e649 100644 --- a/pkg/gtk4-layer-shell/build.zig +++ b/pkg/gtk4-layer-shell/build.zig @@ -3,11 +3,6 @@ const translate_c = @import("translate_c"); const version = @import("build.zig.zon").version; -const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ - .preferred_link_mode = .dynamic, - .search_strategy = .mode_first, -}; - pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -19,38 +14,23 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); - translate: { - const link_system_libs: []const []const u8, const include_paths = - if (b.systemIntegrationOption("gtk4-layer-shell", .{})) - .{ &.{ "gtk4", "gtk4-layer-shell-0" }, &.{} } - else - .{ - &.{"gtk4"}, - paths: { - // local deps (non-system layer-shell/wayland) - const deps = try LocalDeps.get(b) orelse break :translate; - break :paths &.{ - deps.upstream.path("include"), - deps.upstream.path("src"), - deps.client_header_directory, - }; - }, - }; + const lib: union(enum) { + system, + static: *std.Build.Step.Compile, + } = if (b.systemIntegrationOption("gtk4-layer-shell", .{})) + .system + else + .{ .static = try buildLib(b, .{ .target = target, .optimize = optimize }) }; - try translate_c.addImportToModule(b, "c", module, .{ - .source = .{ .includes = .{ - .files = &.{.{ .path = "gtk4-layer-shell.h" }}, - } }, - .target = target, - .optimize = optimize, - .link_system_libs = link_system_libs, - .include_paths = include_paths, - }); - } - - if (!b.systemIntegrationOption("gtk4-layer-shell", .{})) { - _ = try buildLib(b, .{ .target = target, .optimize = optimize }); - } + try translate_c.addImportToModule(b, "gtk4_layer_shell_c", module, .{ + .source = .{ .includes = .{ + .files = &.{.{ .path = "gtk4-layer-shell.h" }}, + } }, + .target = target, + .optimize = optimize, + .link_system_libs = if (lib == .system) &.{ "gtk4", "gtk4-layer-shell-0" } else &.{"gtk4"}, + .link_libs = if (lib == .static) &.{lib.static} else &.{}, + }); } fn buildLib(b: *std.Build, options: anytype) !*std.Build.Step.Compile { @@ -71,7 +51,10 @@ fn buildLib(b: *std.Build, options: anytype) !*std.Build.Step.Compile { b.installArtifact(lib); // GTK - lib.root_module.linkSystemLibrary("gtk4", dynamic_link_opts); + lib.root_module.linkSystemLibrary("gtk4", .{ + .preferred_link_mode = .dynamic, + .search_strategy = .mode_first, + }); // local deps (non-system layer-shell/wayland) const deps = try LocalDeps.get(b) orelse return lib; diff --git a/pkg/gtk4-layer-shell/src/main.zig b/pkg/gtk4-layer-shell/src/main.zig index 04e0f0f35..3931e53af 100644 --- a/pkg/gtk4-layer-shell/src/main.zig +++ b/pkg/gtk4-layer-shell/src/main.zig @@ -1,6 +1,6 @@ const std = @import("std"); -const c = @import("c"); +const c = @import("gtk4_layer_shell_c"); const gdk = @import("gdk"); const gtk = @import("gtk"); diff --git a/pkg/harfbuzz/build.zig b/pkg/harfbuzz/build.zig index 4652c8565..2810daef2 100644 --- a/pkg/harfbuzz/build.zig +++ b/pkg/harfbuzz/build.zig @@ -11,14 +11,6 @@ pub fn build(b: *std.Build) !void { const coretext_enabled = b.option(bool, "enable-coretext", "Build coretext") orelse false; const freetype_enabled = b.option(bool, "enable-freetype", "Build freetype") orelse true; - // For dynamic linking, we prefer dynamic linking and to search by - // mode first. Mode first will search all paths for a dynamic library - // before falling back to static. - const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ - .preferred_link_mode = .dynamic, - .search_strategy = .mode_first, - }; - const freetype_dep = b.dependency("freetype", .{ .target = target, .optimize = optimize, @@ -31,17 +23,14 @@ pub fn build(b: *std.Build) !void { .target = target, .optimize = optimize, .harfbuzz = if (b.systemIntegrationOption("harfbuzz", .{})) - .{ .dynamic = dynamic_link_opts } + .dynamic else .static, .coretext = coretext_enabled, .freetype = if (freetype_enabled) .{ .dependency = freetype_dep, - .link_mode = if (b.systemIntegrationOption("freetype", .{})) - .{ .dynamic = dynamic_link_opts } - else - .static, + .link_mode = if (b.systemIntegrationOption("freetype", .{})) .dynamic else .static, } else null, @@ -93,10 +82,18 @@ pub fn build(b: *std.Build) !void { } const HarfBuzzC = struct { + // For dynamic linking, we prefer dynamic linking and to search by + // mode first. Mode first will search all paths for a dynamic library + // before falling back to static. + const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ + .preferred_link_mode = .dynamic, + .search_strategy = .mode_first, + }; + const AddImportToModuleOptions = struct { - const LinkMode = union(enum) { + const LinkMode = enum { static, - dynamic: std.Build.Module.LinkSystemLibraryOptions, + dynamic, }; target: std.Build.ResolvedTarget, @@ -262,7 +259,7 @@ const HarfBuzzC = struct { // Freetype if (self.options.freetype) |ft| { switch (ft.link_mode) { - .dynamic => |opts| lib.root_module.linkSystemLibrary("freetype2", opts), + .dynamic => lib.root_module.linkSystemLibrary("freetype2", dynamic_link_opts), .static => { lib.root_module.linkLibrary(ft.dependency.artifact("freetype")); }, diff --git a/pkg/oniguruma/build.zig b/pkg/oniguruma/build.zig index f7df86e1b..58182553c 100644 --- a/pkg/oniguruma/build.zig +++ b/pkg/oniguruma/build.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const translate_c = @import("translate_c"); const NativeTargetInfo = std.zig.system.NativeTargetInfo; pub fn build(b: *std.Build) !void { @@ -11,23 +12,11 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); - // For dynamic linking, we prefer dynamic linking and to search by - // mode first. Mode first will search all paths for a dynamic library - // before falling back to static. - const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ - .preferred_link_mode = .dynamic, - .search_strategy = .mode_first, - }; - var test_exe: ?*std.Build.Step.Compile = null; if (target.query.isNative()) { test_exe = b.addTest(.{ .name = "test", - .root_module = b.createModule(.{ - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, - }), + .root_module = module, }); const tests_run = b.addRunArtifact(test_exe.?); const test_step = b.step("test", "Run tests"); @@ -37,25 +26,29 @@ pub fn build(b: *std.Build) !void { b.installArtifact(test_exe.?); } - if (b.systemIntegrationOption("oniguruma", .{})) { - module.linkSystemLibrary("oniguruma", dynamic_link_opts); - - if (test_exe) |exe| { - exe.root_module.linkSystemLibrary("oniguruma", dynamic_link_opts); - } - } else { - const lib = try buildLib(b, module, .{ + const lib: union(enum) { + system, + static: *std.Build.Step.Compile, + } = if (b.systemIntegrationOption("oniguruma", .{})) + .system + else + .{ .static = try buildLib(b, .{ .target = target, .optimize = optimize, - }); + }) }; - if (test_exe) |exe| { - exe.root_module.linkLibrary(lib); - } - } + try translate_c.addImportToModule(b, "oniguruma_c", module, .{ + .source = .{ .includes = .{ + .files = &.{.{ .path = "oniguruma.h" }}, + } }, + .target = target, + .optimize = optimize, + .link_system_libs = if (lib == .system) &.{"oniguruma"} else &.{}, + .link_libs = if (lib == .static) &.{lib.static} else &.{}, + }); } -fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Build.Step.Compile { +fn buildLib(b: *std.Build, options: anytype) !*std.Build.Step.Compile { const target = options.target; const optimize = options.optimize; @@ -78,8 +71,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu if (b.lazyDependency("oniguruma", .{})) |upstream| { lib.root_module.addIncludePath(upstream.path("src")); - module.addIncludePath(upstream.path("src")); - lib.root_module.addConfigHeader(b.addConfigHeader(.{ .style = .{ .cmake = upstream.path("src/config.h.cmake.in") }, }, .{ diff --git a/pkg/oniguruma/build.zig.zon b/pkg/oniguruma/build.zig.zon index 10ec786cb..f90caa5fa 100644 --- a/pkg/oniguruma/build.zig.zon +++ b/pkg/oniguruma/build.zig.zon @@ -12,5 +12,6 @@ }, .apple_sdk = .{ .path = "../apple-sdk" }, + .translate_c = .{ .path = "../translate-c" }, }, } diff --git a/pkg/oniguruma/c.zig b/pkg/oniguruma/c.zig index 73732f903..eb038f924 100644 --- a/pkg/oniguruma/c.zig +++ b/pkg/oniguruma/c.zig @@ -1,3 +1 @@ -pub const c = @cImport({ - @cInclude("oniguruma.h"); -}); +pub const c = @import("oniguruma_c"); diff --git a/pkg/opengl/Buffer.zig b/pkg/opengl/Buffer.zig index bb04b75dd..04f80c6c8 100644 --- a/pkg/opengl/Buffer.zig +++ b/pkg/opengl/Buffer.zig @@ -1,7 +1,7 @@ const Buffer = @This(); const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); diff --git a/pkg/opengl/Framebuffer.zig b/pkg/opengl/Framebuffer.zig index f1bca9da1..78b4eace6 100644 --- a/pkg/opengl/Framebuffer.zig +++ b/pkg/opengl/Framebuffer.zig @@ -1,7 +1,7 @@ const Framebuffer = @This(); const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); const Texture = @import("Texture.zig"); diff --git a/pkg/opengl/Program.zig b/pkg/opengl/Program.zig index c563aebdb..91dd60e0f 100644 --- a/pkg/opengl/Program.zig +++ b/pkg/opengl/Program.zig @@ -4,7 +4,7 @@ const std = @import("std"); const assert = std.debug.assert; const log = std.log.scoped(.opengl); -const c = @import("c"); +const c = @import("opengl_c"); const Shader = @import("Shader.zig"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); diff --git a/pkg/opengl/Renderbuffer.zig b/pkg/opengl/Renderbuffer.zig index 2f4647d60..cbe432d91 100644 --- a/pkg/opengl/Renderbuffer.zig +++ b/pkg/opengl/Renderbuffer.zig @@ -1,7 +1,7 @@ const Renderbuffer = @This(); const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); diff --git a/pkg/opengl/Sampler.zig b/pkg/opengl/Sampler.zig index c4fad658f..8e1a1951a 100644 --- a/pkg/opengl/Sampler.zig +++ b/pkg/opengl/Sampler.zig @@ -1,7 +1,7 @@ const Sampler = @This(); const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); const Texture = @import("Texture.zig"); diff --git a/pkg/opengl/Shader.zig b/pkg/opengl/Shader.zig index 0084c8729..b797de771 100644 --- a/pkg/opengl/Shader.zig +++ b/pkg/opengl/Shader.zig @@ -4,7 +4,7 @@ const std = @import("std"); const assert = std.debug.assert; const log = std.log.scoped(.opengl); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); diff --git a/pkg/opengl/Texture.zig b/pkg/opengl/Texture.zig index 06a454df6..4c535add1 100644 --- a/pkg/opengl/Texture.zig +++ b/pkg/opengl/Texture.zig @@ -1,7 +1,7 @@ const Texture = @This(); const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); diff --git a/pkg/opengl/VertexArray.zig b/pkg/opengl/VertexArray.zig index 3817f8fa0..44087687f 100644 --- a/pkg/opengl/VertexArray.zig +++ b/pkg/opengl/VertexArray.zig @@ -1,6 +1,6 @@ const VertexArray = @This(); -const c = @import("c"); +const c = @import("opengl_c"); const glad = @import("glad.zig"); const errors = @import("errors.zig"); diff --git a/pkg/opengl/build.zig b/pkg/opengl/build.zig index e63313a99..5e09e0c3e 100644 --- a/pkg/opengl/build.zig +++ b/pkg/opengl/build.zig @@ -1,16 +1,23 @@ const std = @import("std"); +const translate_c = @import("translate_c"); pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - - const c = b.addTranslateC(.{ - .root_source_file = b.path("gl.c"), + const module = b.addModule("opengl", .{ + .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize, }); - c.addIncludePath(b.path("../../vendor/glad/include")); - - const module = b.addModule("opengl", .{ .root_source_file = b.path("main.zig") }); - module.addImport("c", c.createModule()); + try translate_c.addImportToModule(b, "opengl_c", module, .{ + .source = .{ .includes = .{ + .files = &.{ + .{ .path = "glad/gl.h" }, + .{ .path = "glad/glad_egl.h" }, + }, + } }, + .target = target, + .optimize = optimize, + .include_paths = &.{b.path("../../vendor/glad/include")}, + }); } diff --git a/pkg/opengl/build.zig.zon b/pkg/opengl/build.zig.zon new file mode 100644 index 000000000..24a998af5 --- /dev/null +++ b/pkg/opengl/build.zig.zon @@ -0,0 +1,10 @@ +.{ + .name = .opengl, + .version = "0.0.1", + .minimum_zig_version = "0.16.0", + .paths = .{""}, + .fingerprint = 0x91bbcdeb77b8f007, + .dependencies = .{ + .translate_c = .{ .path = "../translate-c" }, + }, +} diff --git a/pkg/opengl/draw.zig b/pkg/opengl/draw.zig index e932baca4..85fd5f8fc 100644 --- a/pkg/opengl/draw.zig +++ b/pkg/opengl/draw.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); const Primitive = @import("primitives.zig").Primitive; diff --git a/pkg/opengl/egl.zig b/pkg/opengl/egl.zig index 53aacd10a..08d258af2 100644 --- a/pkg/opengl/egl.zig +++ b/pkg/opengl/egl.zig @@ -8,7 +8,7 @@ //! Call `load()` once before using any EGL extension functions. const std = @import("std"); -pub const c = @import("c"); +pub const c = @import("opengl_c"); const log = std.log.scoped(.opengl_egl); diff --git a/pkg/opengl/errors.zig b/pkg/opengl/errors.zig index cfae2c276..98123dbd6 100644 --- a/pkg/opengl/errors.zig +++ b/pkg/opengl/errors.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const glad = @import("glad.zig"); pub const Error = error{ diff --git a/pkg/opengl/extensions.zig b/pkg/opengl/extensions.zig index 1c49bdbce..381953c5f 100644 --- a/pkg/opengl/extensions.zig +++ b/pkg/opengl/extensions.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); const errors = @import("errors.zig"); const glad = @import("glad.zig"); diff --git a/pkg/opengl/gl.c b/pkg/opengl/gl.c deleted file mode 100644 index 94e25eb70..000000000 --- a/pkg/opengl/gl.c +++ /dev/null @@ -1,2 +0,0 @@ -#include -#include diff --git a/pkg/opengl/glad.zig b/pkg/opengl/glad.zig index d766a60b6..6da620089 100644 --- a/pkg/opengl/glad.zig +++ b/pkg/opengl/glad.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const c = @import("c"); +const c = @import("opengl_c"); pub const Context = c.GladGLContext; diff --git a/pkg/opengl/main.zig b/pkg/opengl/main.zig index c99909eb2..6ee8c5d05 100644 --- a/pkg/opengl/main.zig +++ b/pkg/opengl/main.zig @@ -10,7 +10,7 @@ //! //! WARNING: Lots of performance improvements that we can make with Zig //! comptime help. I'm deferring this until later but have some fun ideas. -pub const c = @import("c"); +pub const c = @import("opengl_c"); pub const glad = @import("glad.zig"); pub const egl = @import("egl.zig"); pub const ext = @import("extensions.zig"); diff --git a/pkg/opengl/primitives.zig b/pkg/opengl/primitives.zig index 52ef2a1ad..ce120b23d 100644 --- a/pkg/opengl/primitives.zig +++ b/pkg/opengl/primitives.zig @@ -1,4 +1,4 @@ -const c = @import("c"); +const c = @import("opengl_c"); pub const Primitive = enum(c_int) { point = c.GL_POINTS, diff --git a/pkg/sentry/build.zig b/pkg/sentry/build.zig index 7eb755f65..f1f912569 100644 --- a/pkg/sentry/build.zig +++ b/pkg/sentry/build.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const translate_c = @import("translate_c"); pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); @@ -26,6 +27,15 @@ pub fn build(b: *std.Build) !void { try apple_sdk.addPaths(b, lib); } + try translate_c.addImportToModule(b, "sentry_c", module, .{ + .source = .{ .includes = .{ + .files = &.{.{ .path = "sentry.h" }}, + } }, + .target = target, + .optimize = optimize, + .link_libs = &.{lib}, + }); + var flags: std.ArrayList([]const u8) = .empty; defer flags.deinit(b.allocator); if (target.result.os.tag == .windows) { @@ -45,7 +55,6 @@ pub fn build(b: *std.Build) !void { } if (b.lazyDependency("sentry", .{})) |upstream| { - module.addIncludePath(upstream.path("include")); lib.root_module.addIncludePath(upstream.path("include")); lib.root_module.addIncludePath(upstream.path("src")); lib.root_module.addCSourceFiles(.{ diff --git a/pkg/sentry/build.zig.zon b/pkg/sentry/build.zig.zon index 9c8ed0e24..63035e894 100644 --- a/pkg/sentry/build.zig.zon +++ b/pkg/sentry/build.zig.zon @@ -13,5 +13,6 @@ .apple_sdk = .{ .path = "../apple-sdk" }, .breakpad = .{ .path = "../breakpad", .lazy = true }, + .translate_c = .{ .path = "../translate-c" }, }, } diff --git a/pkg/sentry/c.zig b/pkg/sentry/c.zig index 4a0184a8d..d3a7d43d8 100644 --- a/pkg/sentry/c.zig +++ b/pkg/sentry/c.zig @@ -1,3 +1 @@ -pub const c = @cImport({ - @cInclude("sentry.h"); -}); +pub const c = @import("sentry_c"); diff --git a/pkg/spirv-cross/build.zig b/pkg/spirv-cross/build.zig index 3b85e8f49..d324b7476 100644 --- a/pkg/spirv-cross/build.zig +++ b/pkg/spirv-cross/build.zig @@ -1,28 +1,21 @@ const std = @import("std"); +const translate_c = @import("translate_c"); pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const module = b.addModule("spirv_cross", .{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize }); - - // For dynamic linking, we prefer dynamic linking and to search by - // mode first. Mode first will search all paths for a dynamic library - // before falling back to static. - const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ - .preferred_link_mode = .dynamic, - .search_strategy = .mode_first, - }; + const module = b.addModule("spirv_cross", .{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = optimize, + }); var test_exe: ?*std.Build.Step.Compile = null; if (target.query.isNative()) { test_exe = b.addTest(.{ .name = "test", - .root_module = b.createModule(.{ - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, - }), + .root_module = module, }); const tests_run = b.addRunArtifact(test_exe.?); const test_step = b.step("test", "Run tests"); @@ -31,16 +24,24 @@ pub fn build(b: *std.Build) !void { // Uncomment this if we're debugging tests // b.installArtifact(test_exe.?); } - if (b.systemIntegrationOption("spirv-cross", .{})) { - module.linkSystemLibrary("spirv-cross-c-shared", dynamic_link_opts); - if (test_exe) |exe| { - exe.root_module.linkSystemLibrary("spirv-cross-c-shared", dynamic_link_opts); - } - } else { - const lib = try buildSpirvCross(b, module, target, optimize); - b.installArtifact(lib); - if (test_exe) |exe| exe.root_module.linkLibrary(lib); - } + + const lib: union(enum) { + system, + static: *std.Build.Step.Compile, + } = if (b.systemIntegrationOption("spirv-cross", .{})) + .system + else + .{ .static = try buildSpirvCross(b, module, target, optimize) }; + + try translate_c.addImportToModule(b, "spirv_cross_c", module, .{ + .source = .{ .includes = .{ + .files = &.{.{ .path = "spirv_cross_c.h" }}, + } }, + .target = target, + .optimize = optimize, + .link_system_libs = if (lib == .system) &.{"spirv-cross-c-shared"} else &.{}, + .link_libs = if (lib == .static) &.{lib.static} else &.{}, + }); } fn buildSpirvCross( @@ -114,5 +115,7 @@ fn buildSpirvCross( ); } + b.installArtifact(lib); + return lib; } diff --git a/pkg/spirv-cross/build.zig.zon b/pkg/spirv-cross/build.zig.zon index 30eea9501..5320c78a0 100644 --- a/pkg/spirv-cross/build.zig.zon +++ b/pkg/spirv-cross/build.zig.zon @@ -12,5 +12,6 @@ }, .apple_sdk = .{ .path = "../apple-sdk" }, + .translate_c = .{ .path = "../translate-c" }, }, } diff --git a/pkg/spirv-cross/c.zig b/pkg/spirv-cross/c.zig index 08a999a3b..21522718c 100644 --- a/pkg/spirv-cross/c.zig +++ b/pkg/spirv-cross/c.zig @@ -1,3 +1 @@ -pub const c = @cImport({ - @cInclude("spirv_cross_c.h"); -}); +pub const c = @import("spirv_cross_c"); diff --git a/pkg/translate-c/build.zig b/pkg/translate-c/build.zig index 01cff419b..71919377d 100644 --- a/pkg/translate-c/build.zig +++ b/pkg/translate-c/build.zig @@ -64,6 +64,11 @@ pub const Options = struct { /// a fallback to static. link_system_libs: []const []const u8 = &.{}, + /// The libraries that you want to link against using `linkLibrary`. These + /// will likely be C/C++ libraries compiled with the Zig build system that + /// install headers alongside their other artifacts. + link_libs: []const *std.Build.Step.Compile = &.{}, + /// Any additional include paths. These will be added using `-I` to the /// translation process, and made available to the translated code, in the /// order they are specified. @@ -82,6 +87,11 @@ pub const Options = struct { /// platform. link_frameworks: []const []const u8 = &.{}, + /// Whether or not struct fields should be initialized by default. This + /// passes the `default-init` flag directly to the translate-c process in + /// its literal form (null means no flag added). + default_init: ?bool = null, + /// Supply an external libc file. The expected format here is exactly what /// you would get if you ran `zig libc` and can be used if the toolchain on /// a particular target has a hard time auto-detecting these paths. @@ -136,6 +146,7 @@ pub fn addImportToModule( /// `addImportToModule`. pub fn init(b: *std.Build, options: Options) !Translator { const translated = try initTranslator(b, options); + for (options.link_libs) |lib| translated.linkLibrary(lib); for (options.include_paths) |path| translated.addIncludePath(path); for (options.system_include_paths) |path| translated.addSystemIncludePath(path); for (options.link_frameworks) |framework| translated.mod.linkFramework(framework, .{}); @@ -161,6 +172,7 @@ pub fn initTranslator(b: *std.Build, options: Options) !Translator { .optimize = options.optimize, .link_libc = options.link_libc, .link_system_libs = try marshalSystemLibs(b, options.link_system_libs), + .default_init = options.default_init, .libc_file = switch (options.libc_file) { .detect_darwin => if (options.target.result.os.tag.isDarwin()) libc_file: { switch (try apple_sdk.pathsForTarget(this_dep.builder, options.target.result)) { diff --git a/src/apprt/gtk/winproto/x11.zig b/src/apprt/gtk/winproto/x11.zig index fe0e6f613..11cce2457 100644 --- a/src/apprt/gtk/winproto/x11.zig +++ b/src/apprt/gtk/winproto/x11.zig @@ -10,11 +10,7 @@ const gobject = @import("gobject"); const gtk = @import("gtk"); const xlib = @import("xlib"); -pub const c = @cImport({ - @cInclude("X11/Xlib.h"); - @cInclude("X11/Xatom.h"); - @cInclude("X11/XKBlib.h"); -}); +pub const c = @import("x11_c"); const input = @import("../../../input.zig"); const Config = @import("../../../config.zig").Config; diff --git a/src/build/SharedDeps.zig b/src/build/SharedDeps.zig index 36daf8eb3..e81007422 100644 --- a/src/build/SharedDeps.zig +++ b/src/build/SharedDeps.zig @@ -192,26 +192,11 @@ pub fn add( step.root_module.addImport("uucode", self.uucode_mod); // C imports for locale constants and functions - { - const c = b.addTranslateC(.{ - .root_source_file = b.path("src/os/locale.c"), - .target = target, - .optimize = optimize, - }); - if (target.result.os.tag.isDarwin()) { - const libc = try std.zig.LibCInstallation.findNative( - b.allocator, - b.graph.io, - .{ - .environ_map = &b.graph.environ_map, - .target = &target.result, - .verbose = false, - }, - ); - c.addSystemIncludePath(.{ .cwd_relative = libc.sys_include_dir.? }); - } - step.root_module.addImport("locale-c", c.createModule()); - } + try translate_c.addImportToModule(b, "locale-c", step.root_module, .{ + .source = .{ .file = b.path("src/os/locale.c") }, + .target = target, + .optimize = optimize, + }); // C imports needed to manage/create PTYs switch (target.result.os.tag) { @@ -219,31 +204,30 @@ pub fn add( .linux, .macos, => { - const c = b.addTranslateC(.{ - .root_source_file = b.path("src/pty.c"), + try translate_c.addImportToModule(b, "pty-c", step.root_module, .{ + .source = .{ .file = b.path("src/pty.c") }, .target = target, .optimize = optimize, }); - switch (target.result.os.tag) { - .macos => { - const libc = try std.zig.LibCInstallation.findNative( - b.allocator, - b.graph.io, - .{ - .environ_map = &b.graph.environ_map, - .target = &target.result, - .verbose = false, - }, - ); - c.addSystemIncludePath(.{ .cwd_relative = libc.sys_include_dir.? }); - }, - else => {}, - } - step.root_module.addImport("pty-c", c.createModule()); }, else => {}, } + // POSIX C imports that are used throughout Ghostty on a general basis. + // (note: errno is C stdlib but we just include it here because that's + // where it's generally included otherwise) + try translate_c.addImportToModule(b, "posix_c", step.root_module, .{ + .source = .{ .includes = .{ .files = &.{ + .{ .path = "errno.h" }, + .{ .path = "pwd.h" }, + .{ .path = "signal.h" }, + .{ .path = "sys/types.h" }, + .{ .path = "unistd.h" }, + } } }, + .target = target, + .optimize = optimize, + }); + // Freetype. We always include this even if our font backend doesn't // use it because Dear Imgui uses Freetype. _ = b.systemIntegrationOption("freetype", .{}); // Shows it in help @@ -473,6 +457,17 @@ pub fn add( } else |_| {} } + // nothings/stb headers + try translate_c.addImportToModule(b, "stb_c", step.root_module, .{ + .source = .{ .includes = .{ .files = &.{ + .{ .path = "stb_image.h" }, + .{ .path = "stb_image_resize.h" }, + } } }, + .target = target, + .optimize = optimize, + .include_paths = &.{b.path("src/stb")}, + }); + // C files step.root_module.link_libc = true; step.root_module.addIncludePath(b.path("src/stb")); @@ -753,7 +748,18 @@ fn addGtkNg( }); if (self.config.x11) { - step.root_module.linkSystemLibrary("X11", dynamic_link_opts); + // X11 headers + try translate_c.addImportToModule(b, "x11_c", step.root_module, .{ + .source = .{ .includes = .{ .files = &.{ + .{ .path = "X11/Xlib.h" }, + .{ .path = "X11/Xatom.h" }, + .{ .path = "X11/XKBlib.h" }, + } } }, + .target = target, + .optimize = optimize, + .link_system_libs = &.{"X11"}, + }); + if (gobject_) |gobject| { step.root_module.addImport( "gdk_x11", diff --git a/src/config/Config.zig b/src/config/Config.zig index 877c43724..0db3d3b44 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -57,9 +57,7 @@ const terminal = struct { const log = std.log.scoped(.config); /// Used on Unixes for some defaults. -const c = @cImport({ - @cInclude("unistd.h"); -}); +const c = @import("posix_c"); pub const compatibility = std.StaticStringMap( cli.CompatibilityHandler(Config), diff --git a/src/os/desktop.zig b/src/os/desktop.zig index 60ec51a5c..9de265a65 100644 --- a/src/os/desktop.zig +++ b/src/os/desktop.zig @@ -3,9 +3,7 @@ const builtin = @import("builtin"); const build_config = @import("../build_config.zig"); const global = @import("../global.zig"); -const c = @cImport({ - @cInclude("unistd.h"); -}); +const c = @import("posix_c"); /// Returns true if the program was launched from a desktop environment. /// diff --git a/src/os/passwd.zig b/src/os/passwd.zig index 7c16e54ec..ac00491e9 100644 --- a/src/os/passwd.zig +++ b/src/os/passwd.zig @@ -17,11 +17,7 @@ comptime { } /// Used to determine the default shell and directory on Unixes. -const c = if (builtin.os.tag != .windows) @cImport({ - @cInclude("sys/types.h"); - @cInclude("unistd.h"); - @cInclude("pwd.h"); -}) else {}; +const c = if (builtin.os.tag != .windows) @import("posix_c") else {}; // Entry that is retrieved from the passwd API. This only contains the fields // we care about. diff --git a/src/stb/main.zig b/src/stb/main.zig index adc594aff..3aba88e34 100644 --- a/src/stb/main.zig +++ b/src/stb/main.zig @@ -1,7 +1,4 @@ -const c = @cImport({ - @cInclude("stb_image.h"); - @cInclude("stb_image_resize.h"); -}); +const c = @import("stb_c"); // We'll just add the exports of the functions or types we actually use // here, no need to export everything from the C lib if we don't use it. diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 016291712..8c7123f02 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -581,11 +581,7 @@ pub const Config = struct { }; const Subprocess = struct { - const c = @cImport({ - @cInclude("errno.h"); - @cInclude("signal.h"); - @cInclude("unistd.h"); - }); + const c = @import("posix_c"); arena: std.heap.ArenaAllocator, cwd: ?[:0]const u8,