diff --git a/recipes/firefox-patches/abseil-cpp.patch b/recipes/firefox-patches/abseil-cpp.patch new file mode 100644 index 00000000..07ca8640 --- /dev/null +++ b/recipes/firefox-patches/abseil-cpp.patch @@ -0,0 +1,66 @@ +Patch-Source: https://github.com/void-linux/void-packages/blob/master/srcpkgs/mozc/patches/abseil.patch + +Ported from grpc's patches + +An all-in-one patch that fixes several issues: + +1) UnscaledCycleClock not fully implemented for ppc*-musl (disabled on musl) +2) powerpc stacktrace implementation only works on glibc (disabled on musl) +4) examine_stack.cpp makes glibc assumptions on powerpc (fixed) + +2025-03-08: adapted from main/abseil-cpp to work with Firefox + +diff -Nurp a/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h b/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h +diff --git a/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h b/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h +index 43a3dab..cc0db72 100644 +--- a/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h ++++ b/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h +@@ -21,7 +21,7 @@ + + // The following platforms have an implementation of a hardware counter. + #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \ +- defined(__powerpc__) || defined(__ppc__) || defined(_M_IX86) || \ ++ ((defined(__powerpc__) || defined(__ppc__)) && defined(__GLIBC)) || defined(_M_IX86) || \ + (defined(_M_X64) && !defined(_M_ARM64EC)) + #define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1 + #else +diff --git a/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc b/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc +index 3dd6ba1..bfe798d 100644 +--- a/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc ++++ b/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc +@@ -36,6 +36,10 @@ + #include + #include + ++#if defined(__powerpc__) ++#include ++#endif ++ + #include "absl/base/attributes.h" + #include "absl/base/internal/raw_logging.h" + #include "absl/base/macros.h" +@@ -177,8 +181,10 @@ void* GetProgramCounter(void* const vuc) { + return reinterpret_cast(context->uc_mcontext.pc); + #elif defined(__powerpc64__) + return reinterpret_cast(context->uc_mcontext.gp_regs[32]); ++#elif defined(__powerpc__) && defined(__GLIBC__) ++ return reinterpret_cast(context->uc_mcontext.regs->nip); + #elif defined(__powerpc__) +- return reinterpret_cast(context->uc_mcontext.uc_regs->gregs[32]); ++ return reinterpret_cast(((struct pt_regs *)context->uc_regs)->nip); + #elif defined(__riscv) + return reinterpret_cast(context->uc_mcontext.__gregs[REG_PC]); + #elif defined(__s390__) && !defined(__s390x__) +diff --git a/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h b/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +index 88949fe..4e26a6b 100644 +--- a/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h ++++ b/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +@@ -67,7 +67,7 @@ + #elif defined(__i386__) || defined(__x86_64__) + #define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_x86-inl.inc" +-#elif defined(__ppc__) || defined(__PPC__) ++#elif (defined(__ppc__) || defined(__PPC__)) && defined(__GLIBC__) + #define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_powerpc-inl.inc" + #elif defined(__aarch64__) diff --git a/recipes/firefox-patches/fix-fortify-system-wrappers.patch b/recipes/firefox-patches/fix-fortify-system-wrappers.patch new file mode 100644 index 00000000..a1a89c65 --- /dev/null +++ b/recipes/firefox-patches/fix-fortify-system-wrappers.patch @@ -0,0 +1,11 @@ +The wrapper features.h gets pulled in by system headers causing thigns to +break. We work around it by simply not wrap features.h + +diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild +index 07d48e7..d2ce2b2 100644 +--- a/config/system-headers.mozbuild ++++ b/config/system-headers.mozbuild +@@ -227,3 +227,2 @@ system_headers = [ + "fcntl.h", +- "features.h", + "fenv.h", diff --git a/recipes/firefox-patches/fix-rust-target.patch b/recipes/firefox-patches/fix-rust-target.patch new file mode 100644 index 00000000..9342063c --- /dev/null +++ b/recipes/firefox-patches/fix-rust-target.patch @@ -0,0 +1,31 @@ +Allow us to just set RUST_TARGEt ourselves instead of hacking around in mozilla's +weird custom build system... + +--- a/build/moz.configure/rust.configure ++++ b/build/moz.configure/rust.configure +@@ -225,7 +225,9 @@ + data.setdefault(key, []).append(namespace(rust_target=t, target=info)) + return data + +- ++@imports('os') ++@imports(_from='mozbuild.util', _import='ensure_unicode') ++@imports(_from='mozbuild.util', _import='system_encoding') + def detect_rustc_target( + host_or_target, compiler_info, arm_target, rust_supported_targets + ): +@@ -340,13 +342,13 @@ + + return None + +- rustc_target = find_candidate(candidates) ++ rustc_target = os.environ['RUST_TARGET'] + + if rustc_target is None: + die("Don't know how to translate {} for rustc".format(host_or_target.alias)) + +- return rustc_target ++ return ensure_unicode(rustc_target, system_encoding) + + + @imports('os') diff --git a/recipes/firefox-patches/glean-stub.patch b/recipes/firefox-patches/glean-stub.patch new file mode 100644 index 00000000..d3253e2a --- /dev/null +++ b/recipes/firefox-patches/glean-stub.patch @@ -0,0 +1,292 @@ +From: Patrycja Rosa +Date: Mon, 1 Jun 2026 19:20:39 +0200 +Subject: [PATCH] stub out some glean metrics + +play stupid games, win `rustc-LLVM ERROR: out of memory` + +--- + .../components/glean/api/src/ffi/boolean.rs | 11 +- + .../components/glean/api/src/ffi/counter.rs | 8 +- + toolkit/components/glean/api/src/ffi/event.rs | 127 +----------------- + .../components/glean/api/src/ffi/string.rs | 14 +- + .../build_scripts/glean_parser_ext/rust.py | 19 +++ + 5 files changed, 34 insertions(+), 145 deletions(-) + +diff --git a/toolkit/components/glean/api/src/ffi/boolean.rs b/toolkit/components/glean/api/src/ffi/boolean.rs +index 9184b23c0098e..fa13206627272 100644 +--- a/toolkit/components/glean/api/src/ffi/boolean.rs ++++ b/toolkit/components/glean/api/src/ffi/boolean.rs +@@ -8,21 +8,18 @@ use nsstring::nsACString; + + #[no_mangle] + pub extern "C" fn fog_boolean_test_has_value(id: u32, ping_name: &nsACString) -> bool { +- with_metric!(BOOLEAN_MAP, id, metric, test_has!(metric, ping_name)) ++ false + } + + #[no_mangle] + pub extern "C" fn fog_boolean_test_get_value(id: u32, ping_name: &nsACString) -> bool { +- with_metric!(BOOLEAN_MAP, id, metric, test_get!(metric, ping_name)) ++ false + } + + #[no_mangle] + pub extern "C" fn fog_boolean_test_get_error(id: u32, error_str: &mut nsACString) -> bool { +- let err = with_metric!(BOOLEAN_MAP, id, metric, test_get_errors!(metric)); +- err.map(|err_str| error_str.assign(&err_str)).is_some() ++ false + } + + #[no_mangle] +-pub extern "C" fn fog_boolean_set(id: u32, value: bool) { +- with_metric!(BOOLEAN_MAP, id, metric, metric.set(value)); +-} ++pub extern "C" fn fog_boolean_set(id: u32, value: bool) {} +diff --git a/toolkit/components/glean/api/src/ffi/counter.rs b/toolkit/components/glean/api/src/ffi/counter.rs +index cf24d79d7dd8e..06a7017a7718c 100644 +--- a/toolkit/components/glean/api/src/ffi/counter.rs ++++ b/toolkit/components/glean/api/src/ffi/counter.rs +@@ -8,23 +8,21 @@ use nsstring::nsACString; + + #[no_mangle] + pub unsafe extern "C" fn fog_counter_add(id: u32, amount: i32) { +- with_metric!(COUNTER_MAP, id, metric, metric.add(amount)); + } + + #[no_mangle] + pub unsafe extern "C" fn fog_counter_test_has_value(id: u32, ping_name: &nsACString) -> bool { +- with_metric!(COUNTER_MAP, id, metric, test_has!(metric, ping_name)) ++ true + } + + #[no_mangle] + pub unsafe extern "C" fn fog_counter_test_get_value(id: u32, ping_name: &nsACString) -> i32 { +- with_metric!(COUNTER_MAP, id, metric, test_get!(metric, ping_name)) ++ 0 + } + + #[no_mangle] + pub extern "C" fn fog_counter_test_get_error(id: u32, error_str: &mut nsACString) -> bool { +- let err = with_metric!(COUNTER_MAP, id, metric, test_get_errors!(metric)); +- err.map(|err_str| error_str.assign(&err_str)).is_some() ++ false + } + + #[no_mangle] +diff --git a/toolkit/components/glean/api/src/ffi/event.rs b/toolkit/components/glean/api/src/ffi/event.rs +index f75eebdddf32e..a29f92eaba55d 100644 +--- a/toolkit/components/glean/api/src/ffi/event.rs ++++ b/toolkit/components/glean/api/src/ffi/event.rs +@@ -15,91 +15,16 @@ pub extern "C" fn fog_event_record( + id: u32, + extra_keys: &ThinVec, + extra_values: &ThinVec, +-) { +- // If no extra keys are passed, we can shortcut here. +- if extra_keys.is_empty() { +- if id & (1 << crate::factory::DYNAMIC_METRIC_BIT) > 0 { +- let map = crate::factory::__jog_metric_maps::EVENT_MAP +- .read() +- .expect("Read lock for dynamic metric map was poisoned"); +- match map.get(&id.into()) { +- Some(m) => m.record_raw(Default::default()), +- None => panic!("No (dynamic) metric for event with id {}", id), +- } +- return; +- } +- +- if metric_maps::record_event_by_id(id, Default::default()).is_err() { +- panic!("No event for id {}", id); +- } +- +- return; +- } +- +- assert_eq!( +- extra_keys.len(), +- extra_values.len(), +- "Extra keys and values differ in length. ID: {}", +- id +- ); +- +- // Otherwise we need to decode them and pass them along. +- let extra = extra_keys +- .iter() +- .zip(extra_values.iter()) +- .map(|(k, v)| (k.to_string(), v.to_string())) +- .collect(); +- if id & (1 << crate::factory::DYNAMIC_METRIC_BIT) > 0 { +- let map = crate::factory::__jog_metric_maps::EVENT_MAP +- .read() +- .expect("Read lock for dynamic metric map was poisoned"); +- match map.get(&id.into()) { +- Some(m) => m.record_raw(extra), +- None => panic!("No (dynamic) metric for event with id {}", id), +- } +- } else { +- match metric_maps::record_event_by_id(id, extra) { +- Ok(()) => {} +- Err(EventRecordingError::InvalidId) => panic!("No event for id {}", id), +- Err(_) => panic!("Unpossible!"), +- } +- } +-} ++) {} + + #[no_mangle] + pub unsafe extern "C" fn fog_event_test_has_value(id: u32, ping_name: &nsACString) -> bool { +- let storage = if ping_name.is_empty() { +- None +- } else { +- Some(ping_name.to_utf8().into_owned()) +- }; +- if id & (1 << crate::factory::DYNAMIC_METRIC_BIT) > 0 { +- let map = crate::factory::__jog_metric_maps::EVENT_MAP +- .read() +- .expect("Read lock for dynamic metric map was poisoned"); +- match map.get(&id.into()) { +- Some(m) => m.test_get_value(storage).is_some(), +- None => panic!("No (dynamic) metric for event with id {}", id), +- } +- } else { +- metric_maps::event_test_get_value_wrapper(id, storage).is_some() +- } ++ false + } + + #[no_mangle] + pub extern "C" fn fog_event_test_get_error(id: u32, error_str: &mut nsACString) -> bool { +- let err = if id & (1 << crate::factory::DYNAMIC_METRIC_BIT) > 0 { +- let map = crate::factory::__jog_metric_maps::EVENT_MAP +- .read() +- .expect("Read lock for dynamic metric map was poisoned"); +- match map.get(&id.into()) { +- Some(m) => test_get_errors!(m), +- None => panic!("No (dynamic) metric for event with id {}", id), +- } +- } else { +- metric_maps::event_test_get_error(id) +- }; +- err.map(|err_str| error_str.assign(&err_str)).is_some() ++ false + } + + /// FFI-compatible representation of recorded event data. +@@ -118,48 +43,4 @@ pub extern "C" fn fog_event_test_get_value( + id: u32, + ping_name: &nsACString, + out_events: &mut ThinVec, +-) { +- let storage = if ping_name.is_empty() { +- None +- } else { +- Some(ping_name.to_utf8().into_owned()) +- }; +- +- let events = if id & (1 << crate::factory::DYNAMIC_METRIC_BIT) > 0 { +- let map = crate::factory::__jog_metric_maps::EVENT_MAP +- .read() +- .expect("Read lock for dynamic metric map was poisoned"); +- let events = match map.get(&id.into()) { +- Some(m) => m.test_get_value(storage), +- None => return, +- }; +- match events { +- Some(events) => events, +- None => return, +- } +- } else { +- match metric_maps::event_test_get_value_wrapper(id, storage) { +- Some(events) => events, +- None => return, +- } +- }; +- +- for event in events { +- let extra = event.extra.unwrap_or_default(); +- let extra_len = extra.len(); +- let mut extras = ThinVec::with_capacity(extra_len * 2); +- for (k, v) in extra.into_iter() { +- extras.push(nsCString::from(k)); +- extras.push(nsCString::from(v)); +- } +- +- let event = FfiRecordedEvent { +- timestamp: event.timestamp, +- category: nsCString::from(event.category), +- name: nsCString::from(event.name), +- extras, +- }; +- +- out_events.push(event); +- } +-} ++) {} +diff --git a/toolkit/components/glean/api/src/ffi/string.rs b/toolkit/components/glean/api/src/ffi/string.rs +index fc28e03a3860f..a1a4c140b988a 100644 +--- a/toolkit/components/glean/api/src/ffi/string.rs ++++ b/toolkit/components/glean/api/src/ffi/string.rs +@@ -8,7 +8,7 @@ use nsstring::nsACString; + + #[no_mangle] + pub extern "C" fn fog_string_test_has_value(id: u32, ping_name: &nsACString) -> bool { +- with_metric!(STRING_MAP, id, metric, test_has!(metric, ping_name)) ++ false + } + + #[no_mangle] +@@ -16,18 +16,12 @@ pub extern "C" fn fog_string_test_get_value( + id: u32, + ping_name: &nsACString, + value: &mut nsACString, +-) { +- let val = with_metric!(STRING_MAP, id, metric, test_get!(metric, ping_name)); +- value.assign(&val); +-} ++) {} + + #[no_mangle] +-pub extern "C" fn fog_string_set(id: u32, value: &nsACString) { +- with_metric!(STRING_MAP, id, metric, metric.set(value.to_utf8())); +-} ++pub extern "C" fn fog_string_set(id: u32, value: &nsACString) {} + + #[no_mangle] + pub extern "C" fn fog_string_test_get_error(id: u32, error_str: &mut nsACString) -> bool { +- let err = with_metric!(STRING_MAP, id, metric, test_get_errors!(metric)); +- err.map(|err_str| error_str.assign(&err_str)).is_some() ++ false + } +diff --git a/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py b/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py +index e37f704e502ba..ebaf0e84e4bd1 100644 +--- a/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py ++++ b/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py +@@ -299,6 +299,25 @@ def output_rust(objs, output_fd, ping_names_by_app_id, options={}): + else: + template_filename = "rust.jinja2" + objs = get_metrics(objs) ++ ++ # copy one metric of each type into a separate list ++ metric_per_type = {} ++ for category_name, category_value in objs.items(): ++ for metric in category_value.values(): ++ metric_per_type[metric.type] = metric ++ ++ # remove types that we stubbed out ++ whitelist = ["fog.ipc"] ++ types_to_remove = ["counter", "event", "string", "boolean"] ++ for category_name, category_value in objs.items(): ++ if category_name in whitelist: continue ++ objs[category_name] = { ++ name: metric ++ for name, metric in category_value.items() ++ if metric.type not in types_to_remove ++ } ++ objs['dummy'] = metric_per_type ++ + for category_name, category_value in objs.items(): + for metric in category_value.values(): + # The constant is all uppercase and suffixed by `_MAP` +-- +2.54.0 + diff --git a/recipes/firefox-patches/lfs64.patch b/recipes/firefox-patches/lfs64.patch new file mode 100644 index 00000000..0d18b10b --- /dev/null +++ b/recipes/firefox-patches/lfs64.patch @@ -0,0 +1,35 @@ +force stat() instead of stat64() on 32-bit +-- +--- a/xpcom/io/nsLocalFileUnix.h ++++ b/xpcom/io/nsLocalFileUnix.h +@@ -21,7 +21,7 @@ + + // stat64 and lstat64 are deprecated on OS X. Normal stat and lstat are + // 64-bit by default on OS X 10.6+. +-#if defined(HAVE_STAT64) && defined(HAVE_LSTAT64) && !defined(XP_DARWIN) ++#if 0 && defined(HAVE_STAT64) && defined(HAVE_LSTAT64) && !defined(XP_DARWIN) + # define STAT stat64 + # define LSTAT lstat64 + # define HAVE_STATS64 1 +--- a/mozglue/baseprofiler/core/shared-libraries-linux.cc ++++ b/mozglue/baseprofiler/core/shared-libraries-linux.cc +@@ -178,7 +178,7 @@ + return false; + } + +-#if defined(__x86_64__) || defined(__aarch64__) || \ ++#if 1 || defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__mips__) && _MIPS_SIM == _ABI64) || \ + !(defined(GP_OS_linux) || defined(GP_OS_android)) + +--- a/security/sandbox/linux/broker/SandboxBrokerUtils.h ++++ b/security/sandbox/linux/broker/SandboxBrokerUtils.h +@@ -15,7 +15,7 @@ + // calls. We'll intercept those and handle them in the stat functions + // but must be sure to use the right structure layout. + +-#if defined(__NR_stat64) || defined(__NR_fstatat64) ++#if 0 && (defined(__NR_stat64) || defined(__NR_fstatat64) ) + typedef struct stat64 statstruct; + # define statsyscall stat64 + # define lstatsyscall lstat64 diff --git a/recipes/firefox-patches/musl-no-linux-prctl.patch b/recipes/firefox-patches/musl-no-linux-prctl.patch new file mode 100644 index 00000000..a8f692e0 --- /dev/null +++ b/recipes/firefox-patches/musl-no-linux-prctl.patch @@ -0,0 +1,19 @@ +see https://www.openwall.com/lists/musl/2025/06/12/11 + + /usr/include/sys/prctl.h:88:8: error: redefinition of 'prctl_mm_map' + 88 | struct prctl_mm_map { + | ^ + /usr/include/linux/prctl.h:134:8: note: previous definition is here + 134 | struct prctl_mm_map { + | ^ + +--- a/third_party/libwebrtc/rtc_base/platform_thread_types.cc ++++ b/third_party/libwebrtc/rtc_base/platform_thread_types.cc +@@ -12,7 +12,6 @@ + + // IWYU pragma: begin_keep + #if defined(WEBRTC_LINUX) +-#include + #include + #include + diff --git a/recipes/firefox-patches/rust-lto-thin.patch b/recipes/firefox-patches/rust-lto-thin.patch new file mode 100644 index 00000000..b14617ad --- /dev/null +++ b/recipes/firefox-patches/rust-lto-thin.patch @@ -0,0 +1,21 @@ +set rust crate lto to thin to not use fatlto for gkrust which fails sometimes + +additionally, disable lto on riscv64 altogether + +--- a/config/makefiles/rust.mk ++++ b/config/makefiles/rust.mk +@@ -91,11 +91,13 @@ + ifndef rustflags_sancov + # Never enable when coverage is enabled to work around https://github.com/rust-lang/rust/issues/90045. + ifndef MOZ_CODE_COVERAGE ++ifeq (,$(findstring riscv64,$(RUST_TARGET))) + ifeq (,$(findstring gkrust_gtest,$(RUST_LIBRARY_FILE))) +-cargo_rustc_flags += -Clto$(if $(filter full,$(MOZ_LTO_RUST_CROSS)),=fat) ++cargo_rustc_flags += -Clto=thin + endif + # We need -Cembed-bitcode=yes for all crates when using -Clto. + RUSTFLAGS += -Cembed-bitcode=yes ++endif + endif + endif + endif diff --git a/recipes/firefox-patches/sandbox-sched_setscheduler.patch b/recipes/firefox-patches/sandbox-sched_setscheduler.patch new file mode 100644 index 00000000..ffdf1267 --- /dev/null +++ b/recipes/firefox-patches/sandbox-sched_setscheduler.patch @@ -0,0 +1,24 @@ +upstream bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1657849 +diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp +index ed958bc..9824433 100644 +--- a/security/sandbox/linux/SandboxFilter.cpp ++++ b/security/sandbox/linux/SandboxFilter.cpp +@@ -1751,6 +1751,6 @@ class GMPSandboxPolicy : public SandboxPolicyCommon { + case __NR_sched_get_priority_max: ++ case __NR_sched_setscheduler: + return Allow(); + case __NR_sched_getparam: +- case __NR_sched_getscheduler: +- case __NR_sched_setscheduler: { ++ case __NR_sched_getscheduler: { + Arg pid(0); +@@ -1926,3 +1926,2 @@ class RDDSandboxPolicy final : public SandboxPolicyCommon { + case __NR_sched_getscheduler: +- case __NR_sched_setscheduler: + case __NR_sched_getattr: +@@ -1932,2 +1931,5 @@ class RDDSandboxPolicy final : public SandboxPolicyCommon { + } ++ // sched_setscheduler gets special treatment here (bug 1657849): ++ case __NR_sched_setscheduler: ++ return Allow(); + diff --git a/recipes/firefox-patches/time64.patch b/recipes/firefox-patches/time64.patch new file mode 100644 index 00000000..4d0ab7a2 --- /dev/null +++ b/recipes/firefox-patches/time64.patch @@ -0,0 +1,66 @@ +From 028fe668ae12ba3c8fec833778c31f6d5b6d318b Mon Sep 17 00:00:00 2001 +From: Aelin +Date: Wed, 24 Jun 2026 17:36:25 +0200 +Subject: [PATCH] time64 compile fixes + +--- + third_party/rust/alsa/src/pcm.rs | 6 +++--- + third_party/rust/wgpu-hal/src/vulkan/adapter.rs | 5 +---- + third_party/rust/zeitstempel/src/unix.rs | 10 ++-------- + 3 files changed, 6 insertions(+), 15 deletions(-) + +diff --git a/third_party/rust/alsa/src/pcm.rs b/third_party/rust/alsa/src/pcm.rs +index 16569b7..ca3517b 100644 +--- a/third_party/rust/alsa/src/pcm.rs ++++ b/third_party/rust/alsa/src/pcm.rs +@@ -1110,19 +1110,19 @@ impl Status { + fn ptr(&self) -> *mut alsa::snd_pcm_status_t { self.0.as_ptr() as *const _ as *mut alsa::snd_pcm_status_t } + + pub fn get_htstamp(&self) -> timespec { +- let mut h = timespec {tv_sec: 0, tv_nsec: 0}; ++ let mut h = timespec::default(); + unsafe { alsa::snd_pcm_status_get_htstamp(self.ptr(), &mut h) }; + h + } + + pub fn get_trigger_htstamp(&self) -> timespec { +- let mut h = timespec {tv_sec: 0, tv_nsec: 0}; ++ let mut h = timespec::default(); + unsafe { alsa::snd_pcm_status_get_trigger_htstamp(self.ptr(), &mut h) }; + h + } + + pub fn get_audio_htstamp(&self) -> timespec { +- let mut h = timespec {tv_sec: 0, tv_nsec: 0}; ++ let mut h = timespec::default(); + unsafe { alsa::snd_pcm_status_get_audio_htstamp(self.ptr(), &mut h) }; + h + } +diff --git a/third_party/rust/zeitstempel/src/unix.rs b/third_party/rust/zeitstempel/src/unix.rs +index d2db5c6..874047b 100644 +--- a/third_party/rust/zeitstempel/src/unix.rs ++++ b/third_party/rust/zeitstempel/src/unix.rs +@@ -12,10 +12,7 @@ fn timespec_to_ns(ts: libc::timespec) -> u64 { + /// + /// [`clock_gettime`]: https://manpages.debian.org/buster/manpages-dev/clock_gettime.3.en.html + pub fn now_including_suspend() -> u64 { +- let mut ts = libc::timespec { +- tv_sec: 0, +- tv_nsec: 0, +- }; ++ let mut ts = libc::timespec::default(); + unsafe { + libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut ts); + } +@@ -32,10 +29,7 @@ pub fn now_including_suspend() -> u64 { + /// [`clock_gettime`]: https://manpages.debian.org/buster/manpages-dev/clock_gettime.3.en.html + /// [`FreeBSD clock_gettime`]: https://man.freebsd.org/cgi/man.cgi?query=clock_gettime&manpath=FreeBSD+15.0-RELEASE + pub fn now_awake() -> u64 { +- let mut ts = libc::timespec { +- tv_sec: 0, +- tv_nsec: 0, +- }; ++ let mut ts = libc::timespec::default(); + #[cfg(any(target_os = "linux", target_os = "android"))] + let clock = libc::CLOCK_MONOTONIC; + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] diff --git a/recipes/firefox-patches/wasip1.patch b/recipes/firefox-patches/wasip1.patch new file mode 100644 index 00000000..c97a5922 --- /dev/null +++ b/recipes/firefox-patches/wasip1.patch @@ -0,0 +1,11 @@ +--- a/build/moz.configure/toolchain.configure ++++ b/build/moz.configure/toolchain.configure +@@ -1112,7 +1112,7 @@ + + @dependable + def wasm(): +- return split_triplet("wasm32-wasi", allow_wasi=True) ++ return split_triplet("wasm32-wasip1", allow_wasi=True) + + + @template diff --git a/recipes/firefox-patches/widevine.patch b/recipes/firefox-patches/widevine.patch new file mode 100644 index 00000000..9c4104b6 --- /dev/null +++ b/recipes/firefox-patches/widevine.patch @@ -0,0 +1,35 @@ +widevine is linked against glibc and needs gcompat to work. Load the +libraries before the sandbox is started. + +--- a/dom/media/gmp/GMPChild.cpp ++++ b/dom/media/gmp/GMPChild.cpp +@@ -208,6 +208,10 @@ + "libdl.so.2", + "libpthread.so.0", + "librt.so.1", ++ "libgcompat.so.0", ++ "ld-linux-x86-64.so.2", ++ "ld-linux-aarch64.so.1", ++ "ld-linux.so.2", + }; + + nsTArray libs; +--- a/dom/media/gmp/GMPParent.cpp ++++ b/dom/media/gmp/GMPParent.cpp +@@ -1206,6 +1206,16 @@ + // psapi.dll added for GetMappedFileNameW, which could possibly be avoided + // in future versions, see bug 1383611 for details. + mLibs = "dxva2.dll, ole32.dll, psapi.dll, shell32.dll, winmm.dll"_ns; ++#elif XP_LINUX ++ mLibs = "libgcompat.so.0"_ns ++#if defined(__x86_64__) ++ ", ld-linux-x86-64.so.2"_ns ++#elif defined(__aarch64__) ++ ", ld-linux-aarch64.so.1"_ns ++#elif defined(__i386__) ++ ", ld-linux.so.2"_ns ++#endif ++ ; + #endif + break; + #ifdef MOZ_WMF_CDM diff --git a/recipes/firefox.toml b/recipes/firefox.toml new file mode 100644 index 00000000..215db017 --- /dev/null +++ b/recipes/firefox.toml @@ -0,0 +1,151 @@ +# Firefox 154.0 — el navegador. Tercera app de usuario final, y **la cabeza de la familia Gecko**: +# Waterfox y Zen son forks suyos y reutilizan todo lo de abajo. +# +# ══ POR QUÉ 154 Y NO 155, QUE ES LA QUE SIGUE ZEN ══════════════════════════════════════════════ +# Zen declara `"version": "155.0.1"` en su `surfer.json` y Waterfox 6.7 también va por el canal +# release, así que 155 parecía la base obvia. Se eligió **154** por una razón concreta: **los parches +# de musl de Alpine son para 154.0**, y son once. Ese es el trabajo de portabilidad que un import de +# nix pierde y que no conviene rehacer a mano — sin ellos Firefox no compila contra musl. +# +# Un Firefox que compila con el set probado vale más que uno con el número correcto que no compila. +# Y como Firefox se mueve cada cuatro semanas, la paridad exacta con Zen es una cinta de correr: lo +# que de verdad se reutiliza entre los tres es LA PLATAFORMA (gtk3/nodejs/clang/cbindgen, todo ya en +# el corpus) y ESTE SET DE PARCHES. Subir a 155 después es un rebase, no un port. +# +# ══ TODO BUNDLEADO SALVO GTK3 ══════════════════════════════════════════════════════════════════ +# Alpine usa `--with-system-{icu,nspr,nss,av1,libvpx,webp,libevent,...}`; de ésas el corpus tiene +# CERO. Firefox trae todas en el árbol, así que se dejan bundleadas: son menos piezas móviles para el +# primer build, que es exactamente cuando conviene minimizar variables. Cuando alguna de esas +# librerías tenga receta propia y valga compartirla, el flag se enciende y se re-mide. +# +# ══ SIN BRANDING OFICIAL, Y NO ES UN DESCUIDO ══════════════════════════════════════════════════ +# Alpine pone `--enable-official-branding`. Acá NO: el binario lleva once parches, y usar el nombre y +# el logo de Firefox sobre un build modificado entra en la política de marcas de Mozilla — es +# literalmente la historia de Iceweasel en Debian. Con el branding `unofficial` el navegador es el +# mismo software y nadie tiene que pedir permiso a nadie. Es la misma cautela que la receta de +# `dejavu-fonts-nerd` ya aplicó con la licencia de Bitstream Vera: **una fuente modificada no puede +# llamarse como la original, y un navegador parcheado tampoco.** +# +# ══ WAYLAND-ONLY, HEREDADO DE GTK3 ═════════════════════════════════════════════════════════════ +# `--enable-default-toolkit=cairo-gtk3-wayland`. Nuestro GTK3 se construyó con `-Dx11_backend=false` +# ⇒ este Firefox **no puede correr como cliente X11 ni bajo Xwayland**. Bajo Wayland nativo sí. Está +# escrito en `recipes/gtk3.toml` y se repite acá porque es lo primero que alguien va a preguntar. +# +# ══ HERMÉTICO: NADA DE RED DURANTE EL BUILD ════════════════════════════════════════════════════ +# --disable-bootstrap su trabajo ES descargar toolchains. Prohibido. +# MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE sin esto `mach` arma un virtualenv con `pip` y sale a +# =system la red. Con `system` usa lo que ya está. +# MOZBUILD_STATE_PATH por defecto escribe en `$HOME`, que en el sandbox no es +# suyo; se apunta al árbol de build. +# Los crates de Rust vienen VENDORIZADOS en el tarball (`third_party/rust`) ⇒ cargo no baja nada. +# +# ══ LO DEMÁS QUE SE APAGA ══════════════════════════════════════════════════════════════════════ +# --disable-jemalloc musl trae su propio allocator; jemalloc encima es la receta del +# cuelgue clásico de Firefox en Alpine. +# --without-wasm-sandboxed- exige el SDK de WASI, que no está en ninguna cola. Apaga el +# libraries sandbox wasm de algunas librerías de medios, no el sandbox del +# proceso de contenido. +# --disable-crashreporter manda telemetría a Mozilla; además pide breakpad. +# --disable-updater la distro actualiza por hammer, no por un updater propio. +# --disable-tests no entran al artefacto. +# --enable-linker=lld zig ES lld; pedir bfd/gold sería pedir algo que no hay. +name = "firefox" +version = "154.0" +license = "MPL-2.0" + +[source] +# Tarball de RELEASE de Mozilla: fichero SUBIDO por upstream, sha256 estable y publicado en su +# SHA256SUMS. No es un `/archive/` de forja, que se genera al vuelo (ver `recipes/mbedtls.toml`). +tarball = "https://ftp.mozilla.org/pub/firefox/releases/154.0/source/firefox-154.0.source.tar.xz" +sha256 = "36cec5b3688a60f78a6d20dcaee15b598f84e03c66f6587056aead6cb498b99a" +# Los once de musl del APKBUILD de Alpine (community/firefox). NO se traen los suyos de ppc64le, +# loongarch ni Android: no aplican a x86_64 y cada parche que no hace falta es una forma más de que +# un rebase falle sin motivo. +patches = [ + "firefox-patches/lfs64.patch", + "firefox-patches/time64.patch", + "firefox-patches/musl-no-linux-prctl.patch", + "firefox-patches/fix-fortify-system-wrappers.patch", + "firefox-patches/fix-rust-target.patch", + "firefox-patches/sandbox-sched_setscheduler.patch", + "firefox-patches/abseil-cpp.patch", + "firefox-patches/glean-stub.patch", + "firefox-patches/rust-lto-thin.patch", + "firefox-patches/wasip1.patch", + "firefox-patches/widevine.patch", +] + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "dynamic" +flags = [] + +[build.phases] +configure = ''' +export MOZBUILD_STATE_PATH="$PWD/.mozbuild" +export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system +export MOZ_NOSPAM=1 +cat > .mozconfig <<'MOZ' +ac_add_options --prefix=/usr +ac_add_options --enable-application=browser +ac_add_options --enable-default-toolkit=cairo-gtk3-wayland +ac_add_options --enable-release +ac_add_options --enable-optimize +ac_add_options --enable-linker=lld +ac_add_options --enable-hardening +ac_add_options --with-branding=browser/branding/unofficial +ac_add_options --with-libclang-path=/usr/lib +ac_add_options --disable-bootstrap +ac_add_options --disable-jemalloc +ac_add_options --disable-crashreporter +ac_add_options --disable-updater +ac_add_options --disable-tests +ac_add_options --disable-debug +ac_add_options --disable-debug-symbols +ac_add_options --disable-strip +ac_add_options --disable-install-strip +ac_add_options --disable-cargo-incremental +ac_add_options --without-wasm-sandboxed-libraries +ac_add_options --enable-alsa +ac_add_options --enable-pulseaudio +ac_add_options --enable-dbus +ac_add_options --enable-ffmpeg +mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir +MOZ +./mach configure +''' +# `mach build` respeta -jN; la cuenta es la misma que en nodejs.toml y por el mismo motivo: un número +# fijo ataría el ArtifactHash a la RAM de quien escribió la receta. +# ⚠ OJO con el techo: dentro del sandbox `/proc/meminfo` NO muestra la memoria del contenedor sino la +# del host (medido en el LXC: 186 GiB en vez de 16), así que en un contenedor esta cuenta se degrada +# a `nproc`. Es un tope, no una garantía. +compile = ''' +export MOZBUILD_STATE_PATH="$PWD/.mozbuild" +export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system +export MOZ_NOSPAM=1 +gib=$(awk "/MemTotal/{printf \"%d\", \$2/1024/1024}" /proc/meminfo) +j=$(( gib / 3 )); [ "$j" -lt 1 ] && j=1 +n=$(nproc); [ "$j" -gt "$n" ] && j=$n +echo "mach build -j$j (MemTotal ${gib} GiB, nproc $n)" +./mach build -j"$j" +''' +install = ''' +export MOZBUILD_STATE_PATH="$PWD/.mozbuild" +export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system +DESTDIR=/out ./mach install +''' + +[deps] +build = [ + "python3", "pkgconf", "nasm", "make", "cmake", + # la plataforma Gecko, compartida con Waterfox y Zen + "nodejs", "cbindgen", "clang18", "llvm18", + "gtk3", "atk", "gdk-pixbuf", "pango", "cairo", "libepoxy", + "glib-shared", "pcre2-shared", "libffi-shared", "zlib-shared", + "harfbuzz", "fribidi", "freetype-shared", "fontconfig-shared", "pixman", + "libpng-shared", "libjpeg-turbo-shared", + "wayland", "wayland-protocols", "libxkbcommon", "mesa", "libdrm", + "dbus", "pipewire", "pulseaudio", "alsa-lib", + "libxml2-shared", "linux-headers", +]