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.
This commit is contained in:
Chris Marchesi
2026-09-11 09:08:05 -07:00
parent d4c88d8069
commit fe9cf6a266
50 changed files with 327 additions and 333 deletions

View File

@@ -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(.{

View File

@@ -22,5 +22,6 @@
.apple_sdk = .{ .path = "../apple-sdk" },
.freetype = .{ .path = "../freetype" },
.translate_c = .{ .path = "../translate-c" },
},
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -12,5 +12,6 @@
.freetype = .{ .path = "../freetype", .lazy = true },
.libxml2 = .{ .path = "../libxml2", .lazy = true },
.translate_c = .{ .path = "../translate-c" },
},
}

View File

@@ -1,3 +1 @@
pub const c = @cImport({
@cInclude("fontconfig/fontconfig.h");
});
pub const c = @import("fontconfig_c");

View File

@@ -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,

View File

@@ -13,6 +13,7 @@
.apple_sdk = .{ .path = "../apple-sdk" },
.libpng = .{ .path = "../libpng" },
.translate_c = .{ .path = "../translate-c" },
.zlib = .{ .path = "../zlib" },
},
}

View File

@@ -1,3 +1 @@
pub const c = @cImport({
@cInclude("freetype-zig.h");
});
pub const c = @import("freetype_c");

View File

@@ -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(.{

View File

@@ -12,5 +12,6 @@
},
.apple_sdk = .{ .path = "../apple-sdk" },
.translate_c = .{ .path = "../translate-c" },
},
}

View File

@@ -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");

View File

@@ -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;

View File

@@ -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");

View File

@@ -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"));
},

View File

@@ -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") },
}, .{

View File

@@ -12,5 +12,6 @@
},
.apple_sdk = .{ .path = "../apple-sdk" },
.translate_c = .{ .path = "../translate-c" },
},
}

View File

@@ -1,3 +1 @@
pub const c = @cImport({
@cInclude("oniguruma.h");
});
pub const c = @import("oniguruma_c");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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")},
});
}

10
pkg/opengl/build.zig.zon Normal file
View File

@@ -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" },
},
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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{

View File

@@ -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");

View File

@@ -1,2 +0,0 @@
#include <glad/gl.h>
#include <glad/glad_egl.h>

View File

@@ -1,5 +1,5 @@
const std = @import("std");
const c = @import("c");
const c = @import("opengl_c");
pub const Context = c.GladGLContext;

View File

@@ -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");

View File

@@ -1,4 +1,4 @@
const c = @import("c");
const c = @import("opengl_c");
pub const Primitive = enum(c_int) {
point = c.GL_POINTS,

View File

@@ -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(.{

View File

@@ -13,5 +13,6 @@
.apple_sdk = .{ .path = "../apple-sdk" },
.breakpad = .{ .path = "../breakpad", .lazy = true },
.translate_c = .{ .path = "../translate-c" },
},
}

View File

@@ -1,3 +1 @@
pub const c = @cImport({
@cInclude("sentry.h");
});
pub const c = @import("sentry_c");

View File

@@ -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;
}

View File

@@ -12,5 +12,6 @@
},
.apple_sdk = .{ .path = "../apple-sdk" },
.translate_c = .{ .path = "../translate-c" },
},
}

View File

@@ -1,3 +1 @@
pub const c = @cImport({
@cInclude("spirv_cross_c.h");
});
pub const c = @import("spirv_cross_c");

View File

@@ -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)) {

View File

@@ -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;

View File

@@ -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",

View File

@@ -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),

View File

@@ -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.
///

View File

@@ -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.

View File

@@ -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.

View File

@@ -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,