Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,11 @@ overflow-checks = false
# back to "warn" (their priority 0 beats the group's -1) where a warning level
# is intentional.
warnings = { level = "deny", priority = -1 }
# `bun_asan` / `bun_debug` / `socket_fault_injection` are set via RUSTFLAGS
# (`--cfg=...` + `--check-cfg=cfg(...)`) by scripts/build/rust.ts; register
# them here so a plain `cargo build` / `cargo check` (without those flags)
# doesn't warn.
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bun_asan)', 'cfg(bun_debug)', 'cfg(socket_fault_injection)'] }
# `bun_asan` / `bun_debug` / `bun_logs` / `socket_fault_injection` are set via
# RUSTFLAGS (`--cfg=...` + `--check-cfg=cfg(...)`) by scripts/build/rust.ts;
# register them here so a plain `cargo build` / `cargo check` (without those
# flags) doesn't warn.
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bun_asan)', 'cfg(bun_debug)', 'cfg(bun_logs)', 'cfg(socket_fault_injection)'] }
# link.exe unconditionally prints "Creating library X.dll.lib and object
# X.dll.exp" to stdout when linking each proc-macro DLL on Windows hosts;
# there is no linker flag to suppress it. The lint already exempts itself
Expand Down
12 changes: 7 additions & 5 deletions scripts/build/buildOptionsRs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
* keeps the mtime stable so a reconfigure with the same sha doesn't
* recompile `bun_core` and its dependents.
*
* Target-dependent constants (`ENABLE_TINYCC`, `ENABLE_ASAN`, `ENABLE_LOGS`)
* Target-dependent constants (`ENABLE_TINYCC`) and the ones mirroring a
* `--cfg` that `rust.ts` passes in RUSTFLAGS (`ENABLE_ASAN`, `ENABLE_LOGS`)
* stay as `cfg!()` expressions inside the generated file rather than literals
* so a `cargo check --target <other-triple>` against the same generated file
* still evaluates them per-target.
* so a `cargo check --target <other-triple>`, or a bare `cargo check` / `cargo
* miri test` with no RUSTFLAGS at all, against the same generated file still
* evaluates them per invocation.
*
* Written at configure time alongside `depVersionsHeader.ts` /
* `cargo-config.ts` — it's a constant manifest, not a build edge.
Expand Down Expand Up @@ -61,10 +63,10 @@ export function generateBuildOptionsRs(cfg: Config): string {
"",
"// Target/profile-derived — kept as `cfg!()` so cross-target",
"// `cargo check` evaluates per-triple. Values agree with `Config`:",
"// rust.ts sets `--cfg=bun_debug` ⇔ `cfg.debug`, `--cfg=bun_asan` ⇔",
"// rust.ts sets `--cfg=bun_logs` ⇔ `cfg.logs`, `--cfg=bun_asan` ⇔",
"// `cfg.asan`, and `cfg.tinycc`'s default (config.ts) is the negation",
"// of this predicate.",
"pub const ENABLE_LOGS: bool = cfg!(bun_debug);",
"pub const ENABLE_LOGS: bool = cfg!(bun_logs);",
"pub const ENABLE_ASAN: bool = cfg!(bun_asan);",
"pub const ENABLE_TINYCC: bool = !cfg!(any(",
` target_os = "android",`,
Expand Down
22 changes: 17 additions & 5 deletions scripts/build/rust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,8 @@ export function cargoBuildInvocation(cfg: Config): CargoInvocation {
rustflags.push("--cfg=bun_asan");
}
// `bun_debug`: the cargo profile is `dev` (a Debug-buildtype build).
// `bun_core::env::IS_DEBUG` and `build_options::ENABLE_LOGS` key on this
// instead of `cfg!(debug_assertions)` so that release-asan /
// `bun_core::env::IS_DEBUG` keys on this instead of
// `cfg!(debug_assertions)` so that release-asan /
// release-assertions (which enable `debug-assertions` below for
// `debug_assert!()` coverage) don't also flip on Debug-only conveniences:
// `DUMP_SOURCE` (per-module writes to /tmp/bun-debug-src/), `debug_warn!`
Expand All @@ -467,6 +467,17 @@ export function cargoBuildInvocation(cfg: Config): CargoInvocation {
if (cfg.debug) {
rustflags.push("--cfg=bun_debug");
}
// `bun_logs`: `build_options::ENABLE_LOGS`, the compile-time gate on
// `scoped_log!`. Follows `cfg.logs`, which `release-assertions` / `--logs`
// set independently of `cfg.debug`. A cfg rather than a literal in
// build_options.rs so that bare `cargo check` / `cargo miri test` (no
// RUSTFLAGS, reading build/debug's file) keep the log bodies dead like
// `bun_debug` does; live, `ScopedLogger::is_visible()` would scan the
// environment through the Highway FFI, which Miri can't call.
rustflags.push("--check-cfg=cfg(bun_logs)");
if (cfg.logs) {
rustflags.push("--cfg=bun_logs");
}
// `bun_codegen_embed`: embed codegen-output `.js` (`include_bytes!`) instead
// of reading them from `BUN_CODEGEN_DIR` at runtime. Mirrors Zig
// `BunBuildOptions.shouldEmbedCode() = optimize != .Debug or codegen_embed`.
Expand Down Expand Up @@ -497,9 +508,10 @@ export function cargoBuildInvocation(cfg: Config): CargoInvocation {
// file:line server-side, so the panic call site is recoverable from the trace
// without embedding the location in the binary — same as the Zig build, which
// had ~0 embedded source paths. Kept off for debug and `release-assertions`
// where panic messages are read locally. Nightly-only; the pinned toolchain
// is nightly.
if (cfg.release && !cfg.assertions) {
// where panic messages are read locally, and for logs builds, whose
// `mark_binding()`-style loggers print `Location::caller()` (`<redacted>:0`
// under this flag). Nightly-only; the pinned toolchain is nightly.
if (cfg.release && !cfg.assertions && !cfg.logs) {
rustflags.push("-Zlocation-detail=none");
}
// Path remapping (CI reproducibility) — rustc equivalent of the C/C++
Expand Down
8 changes: 3 additions & 5 deletions src/bun_core/Global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,11 +435,9 @@ macro_rules! mark_binding {
$crate::mark_binding!(::core::panic::Location::caller().file())
};
($fn_name:expr) => {
// Opt-in via BUN_DEBUG_JSC=1. The `JSC` scope is owned by bun_core. Gate on
// `env::IS_DEBUG` (== `Environment::ENABLE_LOGS`) — never on a Cargo
// feature, since `cfg!(feature = ..)` is resolved against the *calling*
// crate and would warn (or silently no-op) in crates without it.
if $crate::env::IS_DEBUG && $crate::Global::JSC_SCOPE.is_visible() {
// Opt-in via BUN_DEBUG_JSC=1. Same gate as `scoped_log!`; not a Cargo
// feature, which `cfg!` would resolve against the *calling* crate.
Comment thread
robobun marked this conversation as resolved.
if $crate::env::ENABLE_LOGS && $crate::Global::JSC_SCOPE.is_visible() {
$crate::Global::JSC_SCOPE.log(::core::format_args!(
"[JSC] {} ({}:{})\n",
$fn_name,
Expand Down
2 changes: 2 additions & 0 deletions src/bun_core/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ pub(crate) const CANARY_REVISION: &str = if IS_CANARY {
};
pub const DUMP_SOURCE: bool = IS_DEBUG && !IS_TEST;
pub const BASE_PATH: &[u8] = build_options::BASE_PATH;
/// The build's `logs` option (`--cfg=bun_logs` from scripts/build/rust.ts; defaults
/// to `IS_DEBUG`, `release-assertions` and `--logs=on|off` override). Gates `scoped_log!`.
Comment thread
robobun marked this conversation as resolved.
pub const ENABLE_LOGS: bool = build_options::ENABLE_LOGS;
pub const ENABLE_ASAN: bool = build_options::ENABLE_ASAN;
pub const ENABLE_FUZZILLI: bool = build_options::ENABLE_FUZZILLI;
Expand Down
19 changes: 9 additions & 10 deletions src/bun_core/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1540,14 +1540,15 @@ macro_rules! declare_scope {

/// `bun.Output.scoped(.X, vis)("fmt", .{args})` → `scoped_log!(X, "fmt", args...)`
///
/// MUST gate arg evaluation: expands to a dead branch in release builds.
/// MUST gate arg evaluation: expands to a dead branch in builds without logs.
#[macro_export]
macro_rules! scoped_log {
($scope:path, $fmt:expr $(, $arg:expr)* $(,)?) => {
// Gate on `env::IS_DEBUG` (== `Environment::ENABLE_LOGS`) so release
// builds dead-strip the body. Do NOT gate on a Cargo feature — there
// is no `debug_logs` feature and §Forbidden bans silent no-ops.
if $crate::env::IS_DEBUG && $scope.is_visible() {
// Gate on `env::ENABLE_LOGS` (the build's `logs` option, which the
// `--logs` / `release-assertions` configs set independently of
// `IS_DEBUG`) so builds without logs dead-strip the body. Do NOT gate
// on a Cargo feature: there is none and §Forbidden bans silent no-ops.
Comment thread
robobun marked this conversation as resolved.
if $crate::env::ENABLE_LOGS && $scope.is_visible() {
const __NL: &str = $crate::output::_needs_nl($crate::pretty_fmt!($fmt, false));
// Branch on ANSI *before* `format_args!` so each `$arg` evaluates
// exactly once.
Expand Down Expand Up @@ -2591,13 +2592,11 @@ fn init_scoped_debug_writer_at_startup() {
}

fn scoped_writer() -> QuietWriter {
// All callers are already gated on `Environment::ENABLE_LOGS`; this is a
// Debug-build self-check (release-asan/release-assertions enable
// `debug_assertions` with `ENABLE_LOGS == false`, so keying on
// `debug_assertions` would turn it into a guaranteed abort there).
// Callers are gated on `ENABLE_LOGS`; this self-check is `bun_debug`, not
// `debug_assertions`, which release-asan enables with logs off.
Comment thread
robobun marked this conversation as resolved.
#[cfg(bun_debug)]
if !Environment::ENABLE_LOGS {
unreachable!("scopedWriter() should only be called in debug mode");
unreachable!("scopedWriter() should only be called when logs are enabled");
}
// SAFETY: initialized in init_scoped_debug_writer_at_startup; QuietWriter is Copy POD.
unsafe { scoped_debug_writer::SCOPED_FILE_WRITER.read() }
Expand Down
2 changes: 1 addition & 1 deletion src/bundler/bundle_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1978,7 +1978,7 @@ pub mod bv2_impl {
}
}

if bun_core::env::IS_DEBUG && ReachableFiles.is_visible() {
if bun_core::env::ENABLE_LOGS && ReachableFiles.is_visible() {
bun_core::scoped_log!(
ReachableFiles,
"Reachable count: {} / {}",
Expand Down
4 changes: 2 additions & 2 deletions src/jsc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,7 @@ pub use self::Node as node;
#[track_caller]
#[inline]
pub fn mark_binding() {
if bun_core::env::IS_DEBUG && bun_core::Global::JSC_SCOPE.is_visible() {
if bun_core::env::ENABLE_LOGS && bun_core::Global::JSC_SCOPE.is_visible() {
let loc = core::panic::Location::caller();
bun_core::Global::JSC_SCOPE.log(format_args!("[jsc] ({}:{})\n", loc.file(), loc.line()));
}
Expand All @@ -1390,7 +1390,7 @@ pub fn mark_binding() {
/// Like [`mark_binding`], with a class-name prefix.
#[inline]
pub(crate) fn mark_member_binding(class: &'static str, src: &core::panic::Location<'static>) {
if bun_core::env::IS_DEBUG && bun_core::Global::JSC_SCOPE.is_visible() {
if bun_core::env::ENABLE_LOGS && bun_core::Global::JSC_SCOPE.is_visible() {
bun_core::Global::JSC_SCOPE.log(format_args!(
"[jsc] {} ({}:{})\n",
class,
Expand Down
4 changes: 2 additions & 2 deletions src/output/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
// bun_output::scoped_log!(X, "fmt {} {}", a, b);
//
// `declare_scope!` expands to a `pub static X: ScopedLogger`; `scoped_log!`
// gates arg evaluation behind `env::IS_DEBUG` so release builds pay zero
// cost (see PORTING.md args MUST sit inside the dead branch).
// gates arg evaluation behind `env::ENABLE_LOGS` so builds without logs pay
// zero cost (see PORTING.md: args MUST sit inside the dead branch).
Comment thread
robobun marked this conversation as resolved.
pub use bun_core::declare_scope;
pub use bun_core::define_scoped_log;
pub use bun_core::scoped_log;
Expand Down
6 changes: 3 additions & 3 deletions src/sys/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4925,9 +4925,9 @@ pub type EnvMap = std::collections::HashMap<String, String>;
#[macro_export]
macro_rules! syslog {
($fmt:literal $(, $arg:expr)* $(,)?) => {
// Gate on `env::IS_DEBUG` (== `Environment::ENABLE_LOGS`) — matches
// bun_core::scoped_log!; there is no `debug_logs` Cargo feature.
if ::bun_core::env::IS_DEBUG && $crate::fd::SYS.is_visible() {
// Gate on `env::ENABLE_LOGS`, matching bun_core::scoped_log!; there is
// no `debug_logs` Cargo feature.
Comment thread
robobun marked this conversation as resolved.
if ::bun_core::env::ENABLE_LOGS && $crate::fd::SYS.is_visible() {
const __NL: &str =
::bun_core::output::_needs_nl(::bun_core::pretty_fmt!($fmt, false));
// Branch on ANSI *before* `format_args!` so each `$arg` evaluates
Expand Down
2 changes: 1 addition & 1 deletion src/sys/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ unsafe extern "system" {

pub fn GetFileType(hFile: HANDLE) -> DWORD {
let rc = GetFileType_raw(hFile);
// `syslog!` self-gates on `env::IS_DEBUG` (see lib.rs); no extra feature
// `syslog!` self-gates on `env::ENABLE_LOGS` (see lib.rs); no extra feature
// flag needed (there is no `debug_logs` feature in bun_sys).
bun_sys::syslog!("GetFileType({}) = {}", Fd::from_system(hFile), rc);
rc
Expand Down
Loading
Loading