const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const options = b.addOptions(); const tracy_enable = option(b, options, bool, "tracy_enable", "Enable profiling", true); const tracy_on_demand = option(b, options, bool, "tracy_on_demand", "On-demand profiling", false); const tracy_callstack = callstack: { const opt = b.option(u8, "tracy_callstack", "Enforce callstack collection for tracy regions"); options.addOption(?u8, "tracy_callstack", opt); break :callstack opt; }; const tracy_no_callstack = option(b, options, bool, "tracy_no_callstack", "Disable all callstack related functionality", false); const tracy_no_callstack_inlines = option(b, options, bool, "tracy_no_callstack_inlines", "Disables the inline functions in callstacks", false); const tracy_only_localhost = option(b, options, bool, "tracy_only_localhost", "Only listen on the localhost interface", false); const tracy_no_broadcast = option(b, options, bool, "tracy_no_broadcast", "Disable client discovery by broadcast to local network", false); const tracy_only_ipv4 = option(b, options, bool, "tracy_only_ipv4", "Tracy will only accept connections on IPv4 addresses (disable IPv6)", false); const tracy_no_code_transfer = option(b, options, bool, "tracy_no_code_transfer", "Disable collection of source code", false); const tracy_no_context_switch = option(b, options, bool, "tracy_no_context_switch", "Disable capture of context switches", false); const tracy_no_exit = option(b, options, bool, "tracy_no_exit", "Client executable does not exit until all profile data is sent to server", false); const tracy_no_sampling = option(b, options, bool, "tracy_no_sampling", "Disable call stack sampling", false); const tracy_no_verify = option(b, options, bool, "tracy_no_verify", "Disable zone validation for C API", false); const tracy_no_vsync_capture = option(b, options, bool, "tracy_no_vsync_capture", "Disable capture of hardware Vsync events", false); const tracy_no_frame_image = option(b, options, bool, "tracy_no_frame_image", "Disable the frame image support and its thread", false); // @FIXME: For some reason system tracing crashes the program, will need to investigate // panics during some drawf thing within libbacktrace (c++) const tracy_no_system_tracing = option(b, options, bool, "tracy_no_system_tracing", "Disable systrace sampling", true); const tracy_delayed_init = option(b, options, bool, "tracy_delayed_init", "Enable delayed initialization of the library (init on first call)", false); const tracy_manual_lifetime = option(b, options, bool, "tracy_manual_lifetime", "Enable the manual lifetime management of the profile", false); const tracy_fibers = option(b, options, bool, "tracy_fibers", "Enable fibers support", false); const tracy_no_crash_handler = option(b, options, bool, "tracy_no_crash_handler", "Disable crash handling", false); const tracy_timer_fallback = option(b, options, bool, "tracy_timer_fallback", "Use lower resolution timers", false); const shared = option(b, options, bool, "shared", "Build the tracy client as a shared libary", false); const tracy_source_dep = b.dependency("tracy_source", .{}); const mod = b.addModule("tracy", .{ .target = target, .optimize = optimize, }); // Avoid building Tracy completely if it is disabled. mod.addIncludePath(tracy_source_dep.path("public")); if (target.result.os.tag == .windows) { mod.linkSystemLibrary("dbghelp", .{ .needed = true }); mod.linkSystemLibrary("ws2_32", .{ .needed = true }); } mod.link_libcpp = true; const config_header = b.addConfigHeader(.{ .include_path = "TracyConfig.h" }, .{}); inline for (.{ .{ tracy_enable, "TRACY_ENABLE", "" }, .{ tracy_on_demand, "TRACY_ON_DEMAND", "" }, .{ tracy_callstack != null, "TRACY_CALLSTACK", b.fmt("{?d}", .{tracy_callstack}) }, .{ tracy_no_callstack, "TRACY_NO_CALLSTACK", "" }, .{ tracy_no_callstack_inlines, "TRACY_NO_CALLSTACK_INLINES", "" }, .{ tracy_only_localhost, "TRACY_ONLY_LOCALHOST", "" }, .{ tracy_no_broadcast, "TRACY_NO_BROADCAST", "" }, .{ tracy_only_ipv4, "TRACY_ONLY_IPV4", "" }, .{ tracy_no_code_transfer, "TRACY_NO_CODE_TRANSFER", "" }, .{ tracy_no_context_switch, "TRACY_NO_CONTEXT_SWITCH", "" }, .{ tracy_no_exit, "TRACY_NO_EXIT", "" }, .{ tracy_no_sampling, "TRACY_NO_SAMPLING", "" }, .{ tracy_no_verify, "TRACY_NO_VERIFY", "" }, .{ tracy_no_vsync_capture, "TRACY_NO_VSYNC_CAPTURE", ""}, .{ tracy_no_frame_image, "TRACY_NO_FRAME_IMAGE", ""}, .{ tracy_no_system_tracing, "TRACY_NO_SYSTEM_TRACING", ""}, .{ tracy_delayed_init, "TRACY_DELAYED_INIT", ""}, .{ tracy_manual_lifetime, "TRACY_MANUAL_LIFETIME", ""}, .{ tracy_fibers, "TRACY_FIBERS", "" }, .{ tracy_no_crash_handler, "TRACY_NO_CRASH_HANDLER", "" }, .{ tracy_timer_fallback, "TRACY_TIMER_FALLBACK", "" }, .{ shared and target.result.os.tag == .windows, "TRACY_EXPORTS", "" } }) |triplet| { const enabled, const name, const value = triplet; if (enabled) { mod.addCMacro(name, value); config_header.addValue(name, []const u8, value); } } mod.addCSourceFile(.{ .file = tracy_source_dep.path("public/TracyClient.cpp"), .flags = &.{} }); const lib = b.addLibrary(.{ .linkage = if (shared) .dynamic else .static, .name = "tracy", .root_module = mod, }); const include_extensions = &.{".h",".hpp"}; lib.installHeadersDirectory(tracy_source_dep.path("public/tracy"), "tracy", .{ .include_extensions = include_extensions, }); lib.installHeadersDirectory(tracy_source_dep.path("public/common"), "common", .{ .include_extensions = include_extensions, }); lib.installHeadersDirectory(tracy_source_dep.path("public/client"), "client", .{ .include_extensions = include_extensions, }); lib.installConfigHeader(config_header); b.installArtifact(lib); } pub fn option( b: *std.Build, options: *std.Build.Step.Options, comptime T: type, name_raw: []const u8, description_raw: []const u8, default: T, ) T { const opt = b.option(T, name_raw, description_raw) orelse default; options.addOption(T, name_raw, opt); return opt; }