mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
## Summary This PR introduces a CMake-generated header file containing all dependency versions, eliminating the need for C++ code to depend on Zig-exported version constants. ## Changes - **New CMake script**: `cmake/tools/GenerateDependencyVersions.cmake` that: - Reads versions from the existing `generated_versions_list.zig` file - Extracts semantic versions from header files where available (libdeflate, zlib) - Generates `bun_dependency_versions.h` with all dependency versions as compile-time constants - **Updated BunProcess.cpp**: - Now includes the CMake-generated `bun_dependency_versions.h` - Uses `BUN_VERSION_*` constants instead of `Bun__versions_*` - Removes dependency on Zig-exported version constants - **Build system updates**: - Added `GenerateDependencyVersions` to main CMakeLists.txt - Added build directory to include paths in BuildBun.cmake ## Benefits ✅ Single source of truth for dependency versions ✅ Versions accessible from C++ without Zig exports ✅ Automatic regeneration during CMake configuration ✅ Semantic versions shown where available (e.g., zlib 1.2.8 instead of commit hash) ✅ Debug output file for verification ## Test Results Verified that `process.versions` correctly shows all dependency versions: ```javascript $ bun -e "console.log(JSON.stringify(process.versions, null, 2))" { "node": "24.3.0", "bun": "1.2.22-debug", "boringssl": "29a2cd359458c9384694b75456026e4b57e3e567", "libarchive": "898dc8319355b7e985f68a9819f182aaed61b53a", "mimalloc": "4c283af60cdae205df5a872530c77e2a6a307d43", "webkit": "0ddf6f47af0a9782a354f61e06d7f83d097d9f84", "zlib": "1.2.8", "libdeflate": "1.24", // ... all versions present and correct } ``` ## Generated Files - `build/debug/bun_dependency_versions.h` - Header file with version constants - `build/debug/bun_dependency_versions_debug.txt` - Human-readable version list 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
230 lines
7.2 KiB
Zig
230 lines
7.2 KiB
Zig
const Global = @This();
|
|
|
|
/// Does not have the canary tag, because it is exposed in `Bun.version`
|
|
/// "1.0.0" or "1.0.0-debug"
|
|
pub const package_json_version = if (Environment.isDebug)
|
|
version_string ++ "-debug"
|
|
else
|
|
version_string;
|
|
|
|
/// This is used for `bun` without any arguments, it `package_json_version` but with canary if it is a canary build.
|
|
/// like "1.0.0-canary.12"
|
|
pub const package_json_version_with_canary = if (Environment.isDebug)
|
|
version_string ++ "-debug"
|
|
else if (Environment.is_canary)
|
|
std.fmt.comptimePrint("{s}-canary.{d}", .{ version_string, Environment.canary_revision })
|
|
else
|
|
version_string;
|
|
|
|
/// The version and a short hash in parenthesis.
|
|
pub const package_json_version_with_sha = if (Environment.git_sha.len == 0)
|
|
package_json_version
|
|
else if (Environment.isDebug)
|
|
std.fmt.comptimePrint("{s} ({s})", .{ version_string, Environment.git_sha[0..@min(Environment.git_sha.len, 8)] })
|
|
else if (Environment.is_canary)
|
|
std.fmt.comptimePrint("{s}-canary.{d} ({s})", .{ version_string, Environment.canary_revision, Environment.git_sha[0..@min(Environment.git_sha.len, 8)] })
|
|
else
|
|
std.fmt.comptimePrint("{s} ({s})", .{ version_string, Environment.git_sha[0..@min(Environment.git_sha.len, 8)] });
|
|
|
|
/// What is printed by `bun --revision`
|
|
/// "1.0.0+abcdefghi" or "1.0.0-canary.12+abcdefghi"
|
|
pub const package_json_version_with_revision = if (Environment.git_sha.len == 0)
|
|
package_json_version
|
|
else if (Environment.isDebug)
|
|
std.fmt.comptimePrint(version_string ++ "-debug+{s}", .{Environment.git_sha_short})
|
|
else if (Environment.is_canary)
|
|
std.fmt.comptimePrint(version_string ++ "-canary.{d}+{s}", .{ Environment.canary_revision, Environment.git_sha_short })
|
|
else
|
|
std.fmt.comptimePrint(version_string ++ "+{s}", .{Environment.git_sha_short});
|
|
|
|
pub const os_name = Environment.os.nameString();
|
|
|
|
// Bun v1.0.0 (Linux x64 baseline)
|
|
// Bun v1.0.0-debug (Linux x64)
|
|
// Bun v1.0.0-canary.0+44e09bb7f (Linux x64)
|
|
pub const unhandled_error_bun_version_string = "Bun v" ++
|
|
(if (Environment.is_canary) package_json_version_with_revision else package_json_version) ++
|
|
" (" ++ Environment.os.displayString() ++ " " ++ arch_name ++
|
|
(if (Environment.baseline) " baseline)" else ")");
|
|
|
|
pub const arch_name = if (Environment.isX64)
|
|
"x64"
|
|
else if (Environment.isX86)
|
|
"x86"
|
|
else if (Environment.isAarch64)
|
|
"arm64"
|
|
else
|
|
"unknown";
|
|
|
|
pub inline fn getStartTime() i128 {
|
|
return bun.start_time;
|
|
}
|
|
|
|
extern "kernel32" fn SetThreadDescription(thread: std.os.windows.HANDLE, name: [*:0]const u16) callconv(std.os.windows.WINAPI) std.os.windows.HRESULT;
|
|
|
|
pub fn setThreadName(name: [:0]const u8) void {
|
|
if (Environment.isLinux) {
|
|
_ = std.posix.prctl(.SET_NAME, .{@intFromPtr(name.ptr)}) catch 0;
|
|
} else if (Environment.isMac) {
|
|
_ = std.c.pthread_setname_np(name);
|
|
} else if (Environment.isWindows) {
|
|
// TODO: use SetThreadDescription or NtSetInformationThread with 0x26 (ThreadNameInformation)
|
|
// without causing exit code 0xC0000409 (stack buffer overrun) in child process
|
|
}
|
|
}
|
|
|
|
const ExitFn = *const fn () callconv(.C) void;
|
|
|
|
var on_exit_callbacks = std.ArrayListUnmanaged(ExitFn){};
|
|
export fn Bun__atexit(function: ExitFn) void {
|
|
if (std.mem.indexOfScalar(ExitFn, on_exit_callbacks.items, function) == null) {
|
|
on_exit_callbacks.append(bun.default_allocator, function) catch {};
|
|
}
|
|
}
|
|
|
|
pub fn addExitCallback(function: ExitFn) void {
|
|
Bun__atexit(function);
|
|
}
|
|
|
|
pub fn runExitCallbacks() void {
|
|
for (on_exit_callbacks.items) |callback| {
|
|
callback();
|
|
}
|
|
on_exit_callbacks.items.len = 0;
|
|
}
|
|
|
|
var is_exiting = std.atomic.Value(bool).init(false);
|
|
export fn bun_is_exiting() c_int {
|
|
return @intFromBool(isExiting());
|
|
}
|
|
pub fn isExiting() bool {
|
|
return is_exiting.load(.monotonic);
|
|
}
|
|
|
|
/// Flushes stdout and stderr (in exit/quick_exit callback) and exits with the given code.
|
|
pub fn exit(code: u32) noreturn {
|
|
is_exiting.store(true, .monotonic);
|
|
_ = @atomicRmw(usize, &bun.analytics.Features.exited, .Add, 1, .monotonic);
|
|
|
|
// If we are crashing, allow the crash handler to finish it's work.
|
|
bun.crash_handler.sleepForeverIfAnotherThreadIsCrashing();
|
|
|
|
if (Environment.isDebug) {
|
|
bun.assert(bun.debug_allocator_data.backing.?.deinit() == .ok);
|
|
bun.debug_allocator_data.backing = null;
|
|
}
|
|
|
|
switch (Environment.os) {
|
|
.mac => std.c.exit(@bitCast(code)),
|
|
.windows => {
|
|
Bun__onExit();
|
|
std.os.windows.kernel32.ExitProcess(code);
|
|
},
|
|
else => {
|
|
bun.c.quick_exit(@bitCast(code));
|
|
std.c.abort(); // quick_exit should be noreturn
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn raiseIgnoringPanicHandler(sig: bun.SignalCode) noreturn {
|
|
Output.flush();
|
|
Output.Source.Stdio.restore();
|
|
|
|
// clear segfault handler
|
|
bun.crash_handler.resetSegfaultHandler();
|
|
|
|
// clear signal handler
|
|
if (bun.Environment.os != .windows) {
|
|
var sa: std.c.Sigaction = .{
|
|
.handler = .{ .handler = std.posix.SIG.DFL },
|
|
.mask = std.posix.empty_sigset,
|
|
.flags = std.posix.SA.RESETHAND,
|
|
};
|
|
_ = std.c.sigaction(@intFromEnum(sig), &sa, null);
|
|
}
|
|
|
|
// kill self
|
|
_ = std.c.raise(@intFromEnum(sig));
|
|
std.c.abort();
|
|
}
|
|
|
|
pub const AllocatorConfiguration = struct {
|
|
verbose: bool = false,
|
|
long_running: bool = false,
|
|
};
|
|
|
|
pub inline fn mimalloc_cleanup(force: bool) void {
|
|
if (comptime use_mimalloc) {
|
|
Mimalloc.mi_collect(force);
|
|
}
|
|
}
|
|
// Versions are now handled by CMake-generated header (bun_dependency_versions.h)
|
|
|
|
// Enabling huge pages slows down bun by 8x or so
|
|
// Keeping this code for:
|
|
// 1. documentation that an attempt was made
|
|
// 2. if I want to configure allocator later
|
|
pub inline fn configureAllocator(_: AllocatorConfiguration) void {}
|
|
|
|
pub fn notimpl() noreturn {
|
|
@branchHint(.cold);
|
|
Output.panic("Not implemented yet!!!!!", .{});
|
|
}
|
|
|
|
// Make sure we always print any leftover
|
|
pub fn crash() noreturn {
|
|
@branchHint(.cold);
|
|
Global.exit(1);
|
|
}
|
|
|
|
pub const BunInfo = struct {
|
|
bun_version: string,
|
|
platform: analytics.GenerateHeader.GeneratePlatform.Platform,
|
|
|
|
const analytics = bun.analytics;
|
|
const JSON = bun.json;
|
|
const JSAst = bun.ast;
|
|
pub fn generate(comptime Bundler: type, _: Bundler, allocator: std.mem.Allocator) !JSAst.Expr {
|
|
const info = BunInfo{
|
|
.bun_version = Global.package_json_version,
|
|
.platform = analytics.GenerateHeader.GeneratePlatform.forOS(),
|
|
};
|
|
|
|
return try JSON.toAST(allocator, BunInfo, info);
|
|
}
|
|
};
|
|
|
|
pub const user_agent = "Bun/" ++ Global.package_json_version;
|
|
pub export const Bun__userAgent: [*:0]const u8 = Global.user_agent;
|
|
|
|
comptime {
|
|
_ = Bun__userAgent;
|
|
}
|
|
|
|
pub export fn Bun__onExit() void {
|
|
bun.jsc.Node.FSEvents.closeAndWait();
|
|
|
|
runExitCallbacks();
|
|
Output.flush();
|
|
std.mem.doNotOptimizeAway(&Bun__atexit);
|
|
|
|
Output.Source.Stdio.restore();
|
|
}
|
|
|
|
comptime {
|
|
_ = Bun__onExit;
|
|
}
|
|
|
|
const string = []const u8;
|
|
|
|
const Output = @import("./output.zig");
|
|
const std = @import("std");
|
|
|
|
const Environment = @import("./env.zig");
|
|
const version_string = Environment.version_string;
|
|
|
|
const bun = @import("bun");
|
|
const Mimalloc = bun.mimalloc;
|
|
const use_mimalloc = bun.use_mimalloc;
|