const std = @import("std"); const digits2 = std.fmt.digits2; pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const tracy_enable = b.option(bool, "tracy_enable", "Enable profiling") orelse true; const tracy_on_demand = b.option(bool, "tracy_on_demand", "On-demand profiling") orelse false; const tracy_callstack: ?u8 = b.option(u8, "tracy_callstack", "Enforce callstack collection for tracy regions"); const tracy_no_callstack = b.option(bool, "tracy_no_callstack", "Disable all callstack related functionality") orelse false; const tracy_no_callstack_inlines = b.option(bool, "tracy_no_callstack_inlines", "Disables the inline functions in callstacks") orelse false; const tracy_only_localhost = b.option(bool, "tracy_only_localhost", "Only listen on the localhost interface") orelse false; const tracy_no_broadcast = b.option(bool, "tracy_no_broadcast", "Disable client discovery by broadcast to local network") orelse false; const tracy_only_ipv4 = b.option(bool, "tracy_only_ipv4", "Tracy will only accept connections on IPv4 addresses (disable IPv6)") orelse false; const tracy_no_code_transfer = b.option(bool, "tracy_no_code_transfer", "Disable collection of source code") orelse false; const tracy_no_context_switch = b.option(bool, "tracy_no_context_switch", "Disable capture of context switches") orelse false; const tracy_no_exit = b.option(bool, "tracy_no_exit", "Client executable does not exit until all profile data is sent to server") orelse false; const tracy_no_sampling = b.option(bool, "tracy_no_sampling", "Disable call stack sampling") orelse false; const tracy_no_verify = b.option(bool, "tracy_no_verify", "Disable zone validation for C API") orelse false; const tracy_no_vsync_capture = b.option(bool, "tracy_no_vsync_capture", "Disable capture of hardware Vsync events") orelse false; const tracy_no_frame_image = b.option(bool, "tracy_no_frame_image", "Disable the frame image support and its thread") orelse false; // NOTE For some reason system tracing on zig projects crashes tracy, will need to investigate const tracy_no_system_tracing = b.option(bool, "tracy_no_system_tracing", "Disable systrace sampling") orelse true; const tracy_delayed_init = b.option(bool, "tracy_delayed_init", "Enable delayed initialization of the library (init on first call)") orelse false; const tracy_manual_lifetime = b.option(bool, "tracy_manual_lifetime", "Enable the manual lifetime management of the profile") orelse false; const tracy_fibers = b.option(bool, "tracy_fibers", "Enable fibers support") orelse false; const tracy_no_crash_handler = b.option(bool, "tracy_no_crash_handler", "Disable crash handling") orelse false; const tracy_timer_fallback = b.option(bool, "tracy_timer_fallback", "Use lower resolution timers") orelse false; const shared = b.option(bool, "shared", "Build the tracy client as a shared libary") orelse false; const dep_src = b.dependency("src", .{}); const is_windows = target.result.os.tag == .windows; const arena = b.graph.arena; var defines: std.ArrayList(CDefine) = .empty; inline for (.{ .{ tracy_enable , "TRACY_ENABLE" , "1" }, .{ tracy_on_demand , "TRACY_ON_DEMAND" , "1" }, .{ tracy_no_callstack , "TRACY_NO_CALLSTACK" , "1" }, .{ tracy_no_callstack_inlines, "TRACY_NO_CALLSTACK_INLINES", "1" }, .{ tracy_only_localhost , "TRACY_ONLY_LOCALHOST" , "1" }, .{ tracy_no_broadcast , "TRACY_NO_BROADCAST" , "1" }, .{ tracy_only_ipv4 , "TRACY_ONLY_IPV4" , "1" }, .{ tracy_no_code_transfer , "TRACY_NO_CODE_TRANSFER" , "1" }, .{ tracy_no_context_switch , "TRACY_NO_CONTEXT_SWITCH" , "1" }, .{ tracy_no_exit , "TRACY_NO_EXIT" , "1" }, .{ tracy_no_sampling , "TRACY_NO_SAMPLING" , "1" }, .{ tracy_no_verify , "TRACY_NO_VERIFY" , "1" }, .{ tracy_no_vsync_capture , "TRACY_NO_VSYNC_CAPTURE" , "1" }, .{ tracy_no_frame_image , "TRACY_NO_FRAME_IMAGE" , "1" }, .{ tracy_no_system_tracing , "TRACY_NO_SYSTEM_TRACING" , "1" }, .{ tracy_delayed_init , "TRACY_DELAYED_INIT" , "1" }, .{ tracy_manual_lifetime , "TRACY_MANUAL_LIFETIME" , "1" }, .{ tracy_fibers , "TRACY_FIBERS" , "1" }, .{ tracy_no_crash_handler , "TRACY_NO_CRASH_HANDLER" , "1" }, .{ tracy_timer_fallback , "TRACY_TIMER_FALLBACK" , "1" }, }) |entry| { const condition = entry[0]; const name = entry[1]; const value = entry[2]; if (condition) { try defines.append(arena, .{ .name = name, .value = value }); } } if (tracy_callstack) |depth| { try defines.append(arena, .{ .name = "TRACY_CALLSTACK", .value = "\"" ++ digits2(depth) ++ "\"" }); } { const tracy_module = b.addModule("tracy", .{ .root_source_file = b.path("src/root.zig"), .target = target, .optimize = optimize, }); const options = b.addOptions(); options.addOption(bool, "tracy_enable", tracy_enable); options.addOption(?u8, "tracy_callstack", tracy_callstack); options.addOption(bool, "tracy_no_callstack", tracy_no_callstack); options.addOption(bool, "tracy_fibers", tracy_fibers); tracy_module.addImport("options", options.createModule()); const write_file_step = b.addWriteFiles(); const translate_c = b.addTranslateC(.{ .root_source_file = write_file_step.add("c.h", "#include "), .target = target, .optimize = optimize, }); translate_c.addIncludePath(dep_src.path("./public")); if (shared and is_windows) { translate_c.defineCMacro("TRACY_IMPORTS", "1"); } for (defines.items) |define| { translate_c.defineCMacro(define.name, define.value); } tracy_module.addImport("c", translate_c.createModule()); } { const mod = b.createModule(.{ .target = target, .optimize = optimize, }); if (is_windows) { mod.linkSystemLibrary("dbghelp", .{}); mod.linkSystemLibrary("ws2_32", .{}); } if (target.result.abi != .msvc) { mod.link_libcpp = true; } else { mod.link_libc = true; } mod.addCSourceFile(.{ .file = dep_src.path("./public/TracyClient.cpp"), .flags = if (is_windows) &.{"-fms-extensions"} else &.{}, }); if (shared and is_windows) { mod.addCMacro("TRACY_EXPORTS", "1"); } for (defines.items) |define| { mod.addCMacro(define.name, define.value); } const tracy_client = b.addLibrary(.{ .linkage = if (shared) .dynamic else .static, .name = "tracy", .root_module = mod }); tracy_client.installHeadersDirectory(dep_src.path("public"), "", .{ .include_extensions = &.{".h", ".hpp"}, }); b.installArtifact(tracy_client); } } const CDefine = struct { name: []const u8, value: []const u8, };