push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

View File

@@ -0,0 +1 @@
/cache

View File

@@ -0,0 +1,730 @@
From e3a1797dbab3eaa1c808d53215b32c8759d27ac7 Mon Sep 17 00:00:00 2001
From: Collin Baker <collinbaker@chromium.org>
Date: Fri, 4 Apr 2025 14:08:18 -0700
Subject: [PATCH] Reland "Use #[global_allocator] to provide Rust allocator
implementation"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a reland of commit cfa3beef52625e03ba6ce2b2ac98e1b89dde5cdb
Original was reverted due to a cronet gn2bp failure. The script
filtered out GN rules in //build/rust/std, but this caused an exception
when //build/rust/std:allocator was referenced later.
Moving the rules to //build/rust/allocator sidesteps the issue.
Original change's description:
> Use #[global_allocator] to provide Rust allocator implementation
>
> The allocator shim hack we have been using no longer works with
> upstream Rust. Replace it with a less-unsupported method: provide a
> https://github.com/rust-lang/rust/issues/123015, which still requires
> us to provide a few symbol definitions.
>
> Bug: 408221149, 407024458
> Change-Id: If1808ca24b12dc80ead35a25521313a3d2e148d5
>
> Cq-Include-Trybots: luci.chromium.try:android-rust-arm32-rel,android-rust-arm64-dbg,android-rust-arm64-rel,linux-rust-x64-dbg,linux-rust-x64-rel,mac-rust-x64-dbg,win-rust-x64-dbg,win-rust-x64-rel
> Change-Id: If1808ca24b12dc80ead35a25521313a3d2e148d5
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6427855
> Reviewed-by: Alan Zhao <ayzhao@google.com>
> Reviewed-by: Lei Zhang <thestig@chromium.org>
> Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
> Commit-Queue: Collin Baker <collinbaker@chromium.org>
> Auto-Submit: Collin Baker <collinbaker@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1442472}
Bug: 408221149, 407024458
Cq-Include-Trybots: luci.chromium.try:android-rust-arm32-rel,android-rust-arm64-dbg,android-rust-arm64-rel,linux-rust-x64-dbg,linux-rust-x64-rel,mac-rust-x64-dbg,win-rust-x64-dbg,win-rust-x64-rel
Change-Id: I36fef217297bfe64ae81519be24b8c653f6fdfa1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6432410
Reviewed-by: Mohannad Farrag <aymanm@google.com>
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
Auto-Submit: Collin Baker <collinbaker@chromium.org>
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1442922}
---
build/rust/allocator/BUILD.gn | 90 ++++++++++++++++
build/rust/{std => allocator}/alias.cc | 4 +-
build/rust/{std => allocator}/alias.h | 6 +-
.../allocator_impls.cc} | 100 ++++++++----------
build/rust/allocator/allocator_impls.h | 25 +++++
.../allocator/allocator_shim_definitions.cc | 30 ++++++
.../{std => allocator}/compiler_specific.h | 6 +-
.../rust/{std => allocator}/immediate_crash.h | 6 +-
build/rust/allocator/lib.rs | 48 +++++++++
build/rust/cargo_crate.gni | 9 ++
build/rust/rust_macro.gni | 3 +
build/rust/rust_target.gni | 4 +
build/rust/std/BUILD.gn | 41 -------
components/cronet/android/dependencies.txt | 1 +
third_party/breakpad/BUILD.gn | 10 +-
15 files changed, 272 insertions(+), 111 deletions(-)
create mode 100644 build/rust/allocator/BUILD.gn
rename build/rust/{std => allocator}/alias.cc (87%)
rename build/rust/{std => allocator}/alias.h (91%)
rename build/rust/{std/remap_alloc.cc => allocator/allocator_impls.cc} (67%)
create mode 100644 build/rust/allocator/allocator_impls.h
create mode 100644 build/rust/allocator/allocator_shim_definitions.cc
rename build/rust/{std => allocator}/compiler_specific.h (87%)
rename build/rust/{std => allocator}/immediate_crash.h (97%)
create mode 100644 build/rust/allocator/lib.rs
diff --git a/build/rust/allocator/BUILD.gn b/build/rust/allocator/BUILD.gn
new file mode 100644
index 00000000000000..06aa47f097c9c4
--- /dev/null
+++ b/build/rust/allocator/BUILD.gn
@@ -0,0 +1,90 @@
+# Copyright 2025 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/buildflag_header.gni")
+import("//build/config/rust.gni")
+import("//build/rust/rust_static_library.gni")
+
+rust_allocator_uses_partition_alloc = false
+if (build_with_chromium) {
+ import("//base/allocator/partition_allocator/partition_alloc.gni")
+ rust_allocator_uses_partition_alloc = use_partition_alloc_as_malloc
+}
+
+buildflag_header("buildflags") {
+ header = "buildflags.h"
+ flags = [
+ "RUST_ALLOCATOR_USES_PARTITION_ALLOC=$rust_allocator_uses_partition_alloc",
+ ]
+ visibility = [ ":*" ]
+}
+
+if (toolchain_has_rust) {
+ # All targets which depend on Rust code but are not linked by rustc must
+ # depend on this. Usually, this dependency will come from the rust_target() GN
+ # template. However, cargo_crate() does *not* include this dependency so any
+ # C++ targets which directly depend on a cargo_crate() must depend on this.
+ rust_static_library("allocator") {
+ sources = [ "lib.rs" ]
+ crate_root = "lib.rs"
+ cxx_bindings = [ "lib.rs" ]
+
+ deps = [
+ ":allocator_impls",
+ ":allocator_shim_definitions",
+ ]
+
+ no_chromium_prelude = true
+ no_allocator_crate = true
+ allow_unsafe = true
+ }
+
+ static_library("allocator_impls") {
+ public_deps = []
+ if (rust_allocator_uses_partition_alloc) {
+ public_deps += [ "//base/allocator/partition_allocator:partition_alloc" ]
+ }
+
+ sources = [
+ "allocator_impls.cc",
+ "allocator_impls.h",
+ ]
+
+ deps = [
+ ":allocator_cpp_shared",
+ ":buildflags",
+
+ # TODO(crbug.com/408221149): remove the C++ -> Rust dependency for the
+ # default allocator.
+ "//build/rust/std",
+ ]
+
+ visibility = [ ":*" ]
+ }
+
+ source_set("allocator_shim_definitions") {
+ sources = [ "allocator_shim_definitions.cc" ]
+
+ deps = [ ":allocator_cpp_shared" ]
+
+ visibility = [ ":*" ]
+ }
+
+ source_set("allocator_cpp_shared") {
+ sources = [
+ # `alias.*`, `compiler_specific.h`, and `immediate_crash.*` have been
+ # copied from `//base`.
+ # TODO(crbug.com/40279749): Avoid duplication / reuse code.
+ "alias.cc",
+ "alias.h",
+ "compiler_specific.h",
+ "immediate_crash.h",
+ ]
+
+ visibility = [
+ ":allocator_impls",
+ ":allocator_shim_definitions",
+ ]
+ }
+}
diff --git a/build/rust/std/alias.cc b/build/rust/allocator/alias.cc
similarity index 87%
rename from build/rust/std/alias.cc
rename to build/rust/allocator/alias.cc
index 42febac3ed1fc5..ca20986f8ed496 100644
--- a/build/rust/std/alias.cc
+++ b/build/rust/allocator/alias.cc
@@ -7,9 +7,9 @@
//
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
-#include "build/rust/std/alias.h"
+#include "build/rust/allocator/alias.h"
-#include "build/rust/std/compiler_specific.h"
+#include "build/rust/allocator/compiler_specific.h"
namespace build_rust_std {
namespace debug {
diff --git a/build/rust/std/alias.h b/build/rust/allocator/alias.h
similarity index 91%
rename from build/rust/std/alias.h
rename to build/rust/allocator/alias.h
index 0eaba6766148fa..80995ecfb045e3 100644
--- a/build/rust/std/alias.h
+++ b/build/rust/allocator/alias.h
@@ -8,8 +8,8 @@
//
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
-#ifndef BUILD_RUST_STD_ALIAS_H_
-#define BUILD_RUST_STD_ALIAS_H_
+#ifndef BUILD_RUST_ALLOCATOR_ALIAS_H_
+#define BUILD_RUST_ALLOCATOR_ALIAS_H_
#include <stddef.h>
@@ -34,4 +34,4 @@ void Alias(const void* var);
const int line_number = __LINE__; \
build_rust_std::debug::Alias(&line_number)
-#endif // BUILD_RUST_STD_ALIAS_H_
+#endif // BUILD_RUST_ALLOCATOR_ALIAS_H_
diff --git a/build/rust/std/remap_alloc.cc b/build/rust/allocator/allocator_impls.cc
similarity index 67%
rename from build/rust/std/remap_alloc.cc
rename to build/rust/allocator/allocator_impls.cc
index a443b11ec513df..1fde98f23cd124 100644
--- a/build/rust/std/remap_alloc.cc
+++ b/build/rust/allocator/allocator_impls.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "build/rust/allocator/allocator_impls.h"
+
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
#pragma allow_unsafe_libc_calls
@@ -11,9 +13,9 @@
#include <cstring>
#include "build/build_config.h"
-#include "build/rust/std/alias.h"
-#include "build/rust/std/buildflags.h"
-#include "build/rust/std/immediate_crash.h"
+#include "build/rust/allocator/alias.h"
+#include "build/rust/allocator/buildflags.h"
+#include "build/rust/allocator/immediate_crash.h"
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
#include "partition_alloc/partition_alloc_constants.h" // nogncheck
@@ -22,6 +24,11 @@
#include <cstdlib>
#endif
+// NOTE: this documentation is outdated.
+//
+// TODO(crbug.com/408221149): update this documentation, or replace it with docs
+// in the Rust allocator implementation.
+//
// When linking a final binary, rustc has to pick between either:
// * The default Rust allocator
// * Any #[global_allocator] defined in *any rlib in its dependency tree*
@@ -87,19 +94,6 @@
// enabling it breaks Win32 APIs like CreateProcess:
// https://issues.chromium.org/u/1/issues/368070343#comment29
-extern "C" {
-
-#ifdef COMPONENT_BUILD
-#if BUILDFLAG(IS_WIN)
-#define REMAP_ALLOC_ATTRIBUTES __declspec(dllexport) __attribute__((weak))
-#else
-#define REMAP_ALLOC_ATTRIBUTES \
- __attribute__((visibility("default"))) __attribute__((weak))
-#endif
-#else
-#define REMAP_ALLOC_ATTRIBUTES __attribute__((weak))
-#endif // COMPONENT_BUILD
-
#if !BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) && BUILDFLAG(IS_WIN) && \
defined(ADDRESS_SANITIZER)
#define USE_WIN_ALIGNED_MALLOC 1
@@ -107,17 +101,19 @@ extern "C" {
#define USE_WIN_ALIGNED_MALLOC 0
#endif
-// This must exist as the stdlib depends on it to prove that we know the
-// alloc shims below are unstable. In the future we may be required to replace
-// them with a #[global_allocator] crate (see file comment above for more).
-//
-// Marked as weak as when Rust drives linking it includes this symbol itself,
-// and we don't want a collision due to C++ being in the same link target, where
-// C++ causes us to explicitly link in the stdlib and this symbol here.
-[[maybe_unused]]
-__attribute__((weak)) unsigned char __rust_no_alloc_shim_is_unstable;
+// The default allocator functions provided by the Rust standard library.
+extern "C" void* __rdl_alloc(size_t size, size_t align);
+extern "C" void __rdl_dealloc(void* p, size_t size, size_t align);
+extern "C" void* __rdl_realloc(void* p,
+ size_t old_size,
+ size_t align,
+ size_t new_size);
+
+extern "C" void* __rdl_alloc_zeroed(size_t size, size_t align);
+
+namespace rust_allocator_internal {
-REMAP_ALLOC_ATTRIBUTES void* __rust_alloc(size_t size, size_t align) {
+unsigned char* alloc(size_t size, size_t align) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
// PartitionAlloc will crash if given an alignment larger than this.
if (align > partition_alloc::internal::kMaxSupportedAlignment) {
@@ -125,19 +121,19 @@ REMAP_ALLOC_ATTRIBUTES void* __rust_alloc(size_t size, size_t align) {
}
if (align <= alignof(std::max_align_t)) {
- return allocator_shim::UncheckedAlloc(size);
+ return static_cast<unsigned char*>(allocator_shim::UncheckedAlloc(size));
} else {
- return allocator_shim::UncheckedAlignedAlloc(size, align);
+ return static_cast<unsigned char*>(
+ allocator_shim::UncheckedAlignedAlloc(size, align));
}
#elif USE_WIN_ALIGNED_MALLOC
- return _aligned_malloc(size, align);
+ return static_cast<unsigned char*>(_aligned_malloc(size, align));
#else
- extern void* __rdl_alloc(size_t size, size_t align);
- return __rdl_alloc(size, align);
+ return static_cast<unsigned char*>(__rdl_alloc(size, align));
#endif
}
-REMAP_ALLOC_ATTRIBUTES void __rust_dealloc(void* p, size_t size, size_t align) {
+void dealloc(unsigned char* p, size_t size, size_t align) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
if (align <= alignof(std::max_align_t)) {
allocator_shim::UncheckedFree(p);
@@ -147,54 +143,44 @@ REMAP_ALLOC_ATTRIBUTES void __rust_dealloc(void* p, size_t size, size_t align) {
#elif USE_WIN_ALIGNED_MALLOC
return _aligned_free(p);
#else
- extern void __rdl_dealloc(void* p, size_t size, size_t align);
__rdl_dealloc(p, size, align);
#endif
}
-REMAP_ALLOC_ATTRIBUTES void* __rust_realloc(void* p,
- size_t old_size,
- size_t align,
- size_t new_size) {
+unsigned char* realloc(unsigned char* p,
+ size_t old_size,
+ size_t align,
+ size_t new_size) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
if (align <= alignof(std::max_align_t)) {
- return allocator_shim::UncheckedRealloc(p, new_size);
+ return static_cast<unsigned char*>(
+ allocator_shim::UncheckedRealloc(p, new_size));
} else {
- return allocator_shim::UncheckedAlignedRealloc(p, new_size, align);
+ return static_cast<unsigned char*>(
+ allocator_shim::UncheckedAlignedRealloc(p, new_size, align));
}
#elif USE_WIN_ALIGNED_MALLOC
- return _aligned_realloc(p, new_size, align);
+ return static_cast<unsigned char*>(_aligned_realloc(p, new_size, align));
#else
- extern void* __rdl_realloc(void* p, size_t old_size, size_t align,
- size_t new_size);
- return __rdl_realloc(p, old_size, align, new_size);
+ return static_cast<unsigned char*>(
+ __rdl_realloc(p, old_size, align, new_size));
#endif
}
-REMAP_ALLOC_ATTRIBUTES void* __rust_alloc_zeroed(size_t size, size_t align) {
+unsigned char* alloc_zeroed(size_t size, size_t align) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) || USE_WIN_ALIGNED_MALLOC
// TODO(danakj): When RUST_ALLOCATOR_USES_PARTITION_ALLOC is true, it's
// possible that a partition_alloc::UncheckedAllocZeroed() call would perform
// better than partition_alloc::UncheckedAlloc() + memset. But there is no
// such API today. See b/342251590.
- void* p = __rust_alloc(size, align);
+ unsigned char* p = alloc(size, align);
if (p) {
memset(p, 0, size);
}
return p;
#else
- extern void* __rdl_alloc_zeroed(size_t size, size_t align);
- return __rdl_alloc_zeroed(size, align);
+ return static_cast<unsigned char*>(__rdl_alloc_zeroed(size, align));
#endif
}
-REMAP_ALLOC_ATTRIBUTES void __rust_alloc_error_handler(size_t size,
- size_t align) {
- NO_CODE_FOLDING();
- IMMEDIATE_CRASH();
-}
-
-REMAP_ALLOC_ATTRIBUTES extern const unsigned char
- __rust_alloc_error_handler_should_panic = 0;
-
-} // extern "C"
+} // namespace rust_allocator_internal
diff --git a/build/rust/allocator/allocator_impls.h b/build/rust/allocator/allocator_impls.h
new file mode 100644
index 00000000000000..afb335412faf9c
--- /dev/null
+++ b/build/rust/allocator/allocator_impls.h
@@ -0,0 +1,25 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_
+#define BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_
+
+#include <cstddef>
+
+#include "build/build_config.h"
+#include "build/rust/allocator/buildflags.h"
+
+namespace rust_allocator_internal {
+
+unsigned char* alloc(size_t size, size_t align);
+void dealloc(unsigned char* p, size_t size, size_t align);
+unsigned char* realloc(unsigned char* p,
+ size_t old_size,
+ size_t align,
+ size_t new_size);
+unsigned char* alloc_zeroed(size_t size, size_t align);
+
+} // namespace rust_allocator_internal
+
+#endif // BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_
diff --git a/build/rust/allocator/allocator_shim_definitions.cc b/build/rust/allocator/allocator_shim_definitions.cc
new file mode 100644
index 00000000000000..a4d1bd77b7016e
--- /dev/null
+++ b/build/rust/allocator/allocator_shim_definitions.cc
@@ -0,0 +1,30 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstddef>
+
+#include "build/rust/allocator/alias.h"
+#include "build/rust/allocator/immediate_crash.h"
+
+extern "C" {
+
+// As part of rustc's contract for using `#[global_allocator]` without
+// rustc-generated shims we must define this symbol, since we are opting in to
+// unstable functionality. See https://github.com/rust-lang/rust/issues/123015
+//
+// Mark it weak since rustc will generate it when it drives linking.
+[[maybe_unused]]
+__attribute__((weak)) unsigned char __rust_no_alloc_shim_is_unstable;
+
+__attribute__((weak)) void __rust_alloc_error_handler(size_t size,
+ size_t align) {
+ NO_CODE_FOLDING();
+ IMMEDIATE_CRASH();
+}
+
+__attribute__((
+ weak)) extern const unsigned char __rust_alloc_error_handler_should_panic =
+ 0;
+
+} // extern "C"
diff --git a/build/rust/std/compiler_specific.h b/build/rust/allocator/compiler_specific.h
similarity index 87%
rename from build/rust/std/compiler_specific.h
rename to build/rust/allocator/compiler_specific.h
index ea79a7a8dc2842..f9079679a3e9af 100644
--- a/build/rust/std/compiler_specific.h
+++ b/build/rust/allocator/compiler_specific.h
@@ -7,8 +7,8 @@
//
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
-#ifndef BUILD_RUST_STD_COMPILER_SPECIFIC_H_
-#define BUILD_RUST_STD_COMPILER_SPECIFIC_H_
+#ifndef BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_
+#define BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_
#include "build/build_config.h"
@@ -35,4 +35,4 @@
#define NOINLINE
#endif
-#endif // BUILD_RUST_STD_COMPILER_SPECIFIC_H_
+#endif // BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_
diff --git a/build/rust/std/immediate_crash.h b/build/rust/allocator/immediate_crash.h
similarity index 97%
rename from build/rust/std/immediate_crash.h
rename to build/rust/allocator/immediate_crash.h
index e4fd5a09d9379f..9cbf9fd65f3e09 100644
--- a/build/rust/std/immediate_crash.h
+++ b/build/rust/allocator/immediate_crash.h
@@ -5,8 +5,8 @@
// This file has been copied from //base/immediate_crash.h.
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
-#ifndef BUILD_RUST_STD_IMMEDIATE_CRASH_H_
-#define BUILD_RUST_STD_IMMEDIATE_CRASH_H_
+#ifndef BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_
+#define BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_
#include "build/build_config.h"
@@ -168,4 +168,4 @@
#endif // defined(__clang__) || defined(COMPILER_GCC)
-#endif // BUILD_RUST_STD_IMMEDIATE_CRASH_H_
+#endif // BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_
diff --git a/build/rust/allocator/lib.rs b/build/rust/allocator/lib.rs
new file mode 100644
index 00000000000000..7f4a0fc2456942
--- /dev/null
+++ b/build/rust/allocator/lib.rs
@@ -0,0 +1,48 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Define the allocator that Rust code in Chrome should use.
+//!
+//! Any final artifact that depends on this crate, even transitively, will use
+//! the allocator defined here. Currently this is a thin wrapper around
+//! allocator_impls.cc's functions; see the documentation there.
+
+use std::alloc::{GlobalAlloc, Layout};
+
+struct Allocator;
+
+unsafe impl GlobalAlloc for Allocator {
+ unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+ unsafe { ffi::alloc(layout.size(), layout.align()) }
+ }
+
+ unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+ unsafe {
+ ffi::dealloc(ptr, layout.size(), layout.align());
+ }
+ }
+
+ unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+ unsafe { ffi::alloc_zeroed(layout.size(), layout.align()) }
+ }
+
+ unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+ unsafe { ffi::realloc(ptr, layout.size(), layout.align(), new_size) }
+ }
+}
+
+#[global_allocator]
+static GLOBAL: Allocator = Allocator;
+
+#[cxx::bridge(namespace = "rust_allocator_internal")]
+mod ffi {
+ extern "C++" {
+ include!("build/rust/allocator/allocator_impls.h");
+
+ unsafe fn alloc(size: usize, align: usize) -> *mut u8;
+ unsafe fn dealloc(p: *mut u8, size: usize, align: usize);
+ unsafe fn realloc(p: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
+ unsafe fn alloc_zeroed(size: usize, align: usize) -> *mut u8;
+ }
+}
diff --git a/build/rust/cargo_crate.gni b/build/rust/cargo_crate.gni
index 6d11c538bf4d5a..d9912722b4ecdb 100644
--- a/build/rust/cargo_crate.gni
+++ b/build/rust/cargo_crate.gni
@@ -259,6 +259,12 @@ template("cargo_crate") {
# Don't import the `chromium` crate into third-party code.
no_chromium_prelude = true
+ # Don't depend on the chrome-specific #[global_allocator] crate from
+ # third-party code. This avoids some dependency cycle issues. The allocator
+ # crate will still be used if it exists anywhere in the dependency graph for
+ # a given linked artifact.
+ no_allocator_crate = true
+
rustc_metadata = _rustc_metadata
# TODO(crbug.com/40259764): don't default to true. This requires changes to
@@ -483,6 +489,9 @@ template("cargo_crate") {
# Don't import the `chromium` crate into third-party code.
no_chromium_prelude = true
+ # Build scripts do not need to link to chrome's allocator.
+ no_allocator_crate = true
+
# The ${_build_script_name}_output target looks for the exe in this
# location. Due to how the Windows component build works, this has to
# be $root_out_dir for all EXEs. In component build, C++ links to the
diff --git a/build/rust/rust_macro.gni b/build/rust/rust_macro.gni
index bcbb30ed441115..41d857632ccdc9 100644
--- a/build/rust/rust_macro.gni
+++ b/build/rust/rust_macro.gni
@@ -16,6 +16,9 @@ template("rust_macro") {
forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
proc_macro_configs = invoker.configs
target_type = "rust_proc_macro"
+
+ # Macros are loaded by rustc and shouldn't use chrome's allocation routines.
+ no_allocator_crate = true
}
}
diff --git a/build/rust/rust_target.gni b/build/rust/rust_target.gni
index 1a2f96337d4361..1003a7b678352d 100644
--- a/build/rust/rust_target.gni
+++ b/build/rust/rust_target.gni
@@ -339,6 +339,10 @@ template("rust_target") {
_rust_deps += [ "//build/rust/std" ]
}
+ if (!defined(invoker.no_allocator_crate) || !invoker.no_allocator_crate) {
+ _rust_deps += [ "//build/rust/allocator" ]
+ }
+
if (_build_unit_tests) {
_unit_test_target = "${_target_name}_unittests"
if (defined(invoker.unit_test_target)) {
diff --git a/build/rust/std/BUILD.gn b/build/rust/std/BUILD.gn
index 6b996aa1fe3865..25db126076b2fa 100644
--- a/build/rust/std/BUILD.gn
+++ b/build/rust/std/BUILD.gn
@@ -15,51 +15,12 @@
# allocator functions to PartitionAlloc when `use_partition_alloc_as_malloc` is
# true, so that Rust and C++ use the same allocator backend.
-import("//build/buildflag_header.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/coverage/coverage.gni")
import("//build/config/rust.gni")
import("//build/config/sanitizers/sanitizers.gni")
-rust_allocator_uses_partition_alloc = false
-if (build_with_chromium) {
- import("//base/allocator/partition_allocator/partition_alloc.gni")
- rust_allocator_uses_partition_alloc = use_partition_alloc_as_malloc
-}
-
-buildflag_header("buildflags") {
- header = "buildflags.h"
- flags = [
- "RUST_ALLOCATOR_USES_PARTITION_ALLOC=$rust_allocator_uses_partition_alloc",
- ]
- visibility = [ ":*" ]
-}
-
if (toolchain_has_rust) {
- # If clang performs the link step, we need to provide the allocator symbols
- # that are normally injected by rustc during linking.
- #
- # We also "happen to" use this to redirect allocations to PartitionAlloc,
- # though that would be better done through a #[global_allocator] crate (see
- # above).
- source_set("remap_alloc") {
- public_deps = []
- if (rust_allocator_uses_partition_alloc) {
- public_deps += [ "//base/allocator/partition_allocator:partition_alloc" ]
- }
- deps = [ ":buildflags" ]
- sources = [
- # `alias.*`, `compiler_specific.h`, and `immediate_crash.*` have been
- # copied from `//base`.
- # TODO(crbug.com/40279749): Avoid duplication / reuse code.
- "alias.cc",
- "alias.h",
- "compiler_specific.h",
- "immediate_crash.h",
- "remap_alloc.cc",
- ]
- }
-
# List of Rust stdlib rlibs which are present in the official Rust toolchain
# we are using from the Android team. This is usually a version or two behind
# nightly. Generally this matches the toolchain we build ourselves, but if
@@ -269,8 +230,6 @@ if (toolchain_has_rust) {
foreach(libname, stdlib_files + skip_stdlib_files) {
deps += [ "rules:$libname" ]
}
-
- public_deps = [ ":remap_alloc" ]
}
} else {
action("find_stdlib") {
diff --git a/components/cronet/android/dependencies.txt b/components/cronet/android/dependencies.txt
index bf56bc45ed41f7..c0e41ef7c6766a 100644
--- a/components/cronet/android/dependencies.txt
+++ b/components/cronet/android/dependencies.txt
@@ -14,6 +14,7 @@
//build/config
//build/config/compiler
//build/rust
+//build/rust/allocator
//build/rust/chromium_prelude
//build/rust/std
//build/rust/std/rules
diff --git a/third_party/breakpad/BUILD.gn b/third_party/breakpad/BUILD.gn
index 2f4e1ab0156609..e140ecbedcc9a0 100644
--- a/third_party/breakpad/BUILD.gn
+++ b/third_party/breakpad/BUILD.gn
@@ -495,7 +495,10 @@ if (is_mac) {
defines = [ "HAVE_MACH_O_NLIST_H" ]
# Rust demangle support.
- deps = [ "//third_party/rust/rustc_demangle_capi/v0_1:lib" ]
+ deps = [
+ "//build/rust/allocator",
+ "//third_party/rust/rustc_demangle_capi/v0_1:lib",
+ ]
defines += [ "HAVE_RUSTC_DEMANGLE" ]
include_dirs += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include" ]
sources += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include/rustc_demangle.h" ]
@@ -743,7 +746,10 @@ if (is_linux || is_chromeos || is_android) {
include_dirs = [ "breakpad/src" ]
# Rust demangle support.
- deps = [ "//third_party/rust/rustc_demangle_capi/v0_1:lib" ]
+ deps = [
+ "//build/rust/allocator",
+ "//third_party/rust/rustc_demangle_capi/v0_1:lib",
+ ]
defines += [ "HAVE_RUSTC_DEMANGLE" ]
include_dirs += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include" ]
sources += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include/rustc_demangle.h" ]

View File

@@ -0,0 +1,13 @@
let
infoJson = builtins.fromJSON (builtins.readFile ./info.json);
in
{ lib, callPackage }:
let
mkElectron = callPackage ./generic.nix { };
in
lib.mapAttrs' (
majorVersion: info:
lib.nameValuePair "electron_${majorVersion}-bin" (mkElectron info.version info.hashes)
) infoJson

View File

@@ -0,0 +1,211 @@
{
lib,
stdenv,
makeWrapper,
fetchurl,
fetchzip,
wrapGAppsHook3,
glib,
gtk3,
gtk4,
unzip,
at-spi2-atk,
libdrm,
libgbm,
libxkbcommon,
libxshmfence,
libGL,
vulkan-loader,
alsa-lib,
cairo,
cups,
dbus,
expat,
gdk-pixbuf,
nss,
nspr,
xorg,
pango,
systemd,
pciutils,
libnotify,
pipewire,
libsecret,
libpulseaudio,
speechd-minimal,
}:
version: hashes:
let
pname = "electron";
meta = with lib; {
description = "Cross platform desktop application shell";
homepage = "https://github.com/electron/electron";
license = licenses.mit;
mainProgram = "electron";
maintainers = with maintainers; [
yayayayaka
teutat3s
tomasajt
];
platforms = [
"x86_64-darwin"
"x86_64-linux"
"armv7l-linux"
"aarch64-linux"
"aarch64-darwin"
];
sourceProvenance = with sourceTypes; [ binaryNativeCode ];
# https://www.electronjs.org/docs/latest/tutorial/electron-timelines
knownVulnerabilities = optional (versionOlder version "36.0.0") "Electron version ${version} is EOL";
};
fetcher =
vers: tag: hash:
fetchurl {
url = "https://github.com/electron/electron/releases/download/v${vers}/electron-v${vers}-${tag}.zip";
sha256 = hash;
};
headersFetcher =
vers: hash:
fetchzip {
name = "electron-${vers}-headers";
url = "https://artifacts.electronjs.org/headers/dist/v${vers}/node-v${vers}-headers.tar.gz";
sha256 = hash;
};
tags = {
x86_64-linux = "linux-x64";
armv7l-linux = "linux-armv7l";
aarch64-linux = "linux-arm64";
x86_64-darwin = "darwin-x64";
aarch64-darwin = "darwin-arm64";
};
get = as: platform: as.${platform.system} or (throw "Unsupported system: ${platform.system}");
common = platform: {
inherit pname version meta;
src = fetcher version (get tags platform) (get hashes platform);
passthru.headers = headersFetcher version hashes.headers;
};
electronLibPath = lib.makeLibraryPath [
alsa-lib
at-spi2-atk
cairo
cups
dbus
expat
gdk-pixbuf
glib
gtk3
gtk4
nss
nspr
xorg.libX11
xorg.libxcb
xorg.libXcomposite
xorg.libXdamage
xorg.libXext
xorg.libXfixes
xorg.libXrandr
xorg.libxkbfile
pango
pciutils
stdenv.cc.cc
systemd
libnotify
pipewire
libsecret
libpulseaudio
speechd-minimal
libdrm
libgbm
libxkbcommon
libxshmfence
libGL
vulkan-loader
];
linux = finalAttrs: {
buildInputs = [
glib
gtk3
gtk4
];
nativeBuildInputs = [
unzip
makeWrapper
wrapGAppsHook3
];
dontUnpack = true;
dontBuild = true;
installPhase = ''
mkdir -p $out/libexec/electron
unzip -d $out/libexec/electron $src
chmod u-x $out/libexec/electron/*.so*
'';
# We don't want to wrap the contents of $out/libexec automatically
dontWrapGApps = true;
preFixup = ''
makeWrapper "$out/libexec/electron/electron" $out/bin/electron \
"''${gappsWrapperArgs[@]}"
'';
postFixup = ''
patchelf \
--set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
--set-rpath "${electronLibPath}:$out/libexec/electron" \
$out/libexec/electron/electron \
$out/libexec/electron/chrome_crashpad_handler
# patch libANGLE
patchelf \
--set-rpath "${
lib.makeLibraryPath [
libGL
pciutils
vulkan-loader
]
}" \
$out/libexec/electron/lib*GL*
# replace bundled vulkan-loader
rm "$out/libexec/electron/libvulkan.so.1"
ln -s -t "$out/libexec/electron" "${lib.getLib vulkan-loader}/lib/libvulkan.so.1"
'';
passthru.dist = finalAttrs.finalPackage + "/libexec/electron";
};
darwin = finalAttrs: {
nativeBuildInputs = [
makeWrapper
unzip
];
buildCommand = ''
mkdir -p $out/Applications
unzip $src
mv Electron.app $out/Applications
mkdir -p $out/bin
makeWrapper $out/Applications/Electron.app/Contents/MacOS/Electron $out/bin/electron
'';
passthru.dist = finalAttrs.finalPackage + "/Applications";
};
in
stdenv.mkDerivation (
finalAttrs:
lib.recursiveUpdate (common stdenv.hostPlatform) (
(if stdenv.hostPlatform.isDarwin then darwin else linux) finalAttrs
)
)

View File

@@ -0,0 +1,46 @@
{
"35": {
"hashes": {
"aarch64-darwin": "2fe3a3cfad607a8c1627f6f2bb9834f959c665ef575b663206db11929634b92f",
"aarch64-linux": "35c4c30aed2639a38fafa6bd1a6a97b3af89a681afbd5c7a0f40673859040ea3",
"armv7l-linux": "350e80638b5ba8a1b56e2463fa55de25f8ee595c0496ef833b07fb4dc65e0c22",
"headers": "1w8qcgsbii6gizv31i1nkbhaipcr6r1x384wkwnxp60dk9a6cl59",
"x86_64-darwin": "48a426bb5df999dd46c0700261a1a7f572b17581c4c0d1c28afade5ae600cdc9",
"x86_64-linux": "368d155a2189e1056d111d334b712779e77066fce1f5ab935b22c4ef544eaa29"
},
"version": "35.7.5"
},
"36": {
"hashes": {
"aarch64-darwin": "33892aeb000bd7f3f8a102f3bb3111b6fa1e2ccd92cbb5b787c79423e96d61b8",
"aarch64-linux": "55da6f2d692445f0eff0ee898160ff4da2c2d3f1736aff77fcb12c836f19db5e",
"armv7l-linux": "0631d0dc472c412f4c52def18adf6fddc0aefde37e0b15d0611cd4743f9e1e9b",
"headers": "0fv8hz55xk76vksj8sagfhja0xx03ks8awi3sbmlinjb9m02hb9p",
"x86_64-darwin": "8448b9f39e6c540b326b2abfcdfd41349482247b936a72914f9c843478b6597c",
"x86_64-linux": "bab89894ad4336ee8f855de3bb5405ee3d872d90b2ba7b196ac24cbc7a3025b8"
},
"version": "36.9.2"
},
"37": {
"hashes": {
"aarch64-darwin": "82869e916e74cb763c03fefb5fcee1fc99536e597716d4f3a9c716f9c37effab",
"aarch64-linux": "7c76a5147a9870b8bcbd859278148e1e326f98ea6a5dcb3ac2707d39bd22b2d5",
"armv7l-linux": "0d4a49b5f462972173daf6e919664cc04cad7a7d2a96b074cb181ea07bb0cd74",
"headers": "0pxwny0ynvyqb3zqnharc4mkgj6acipqra1jjmf4hbr2a8m5fnc6",
"x86_64-darwin": "258a104f781c50939ec6b45177a6f810da646ade15567a09cf9d14ec81b82cb2",
"x86_64-linux": "02e644d75392a1ea8991106bc77e1db243ee1fc0c23107dc3b253ed545dd4c66"
},
"version": "37.6.0"
},
"38": {
"hashes": {
"aarch64-darwin": "cff178e2cb9ae0d957d43009ef46d249d5594bc107d7704130bc0ce2e234bbd1",
"aarch64-linux": "76116429b368c883f93eb98cbdb053f98d811c35943133fe3cf9b408018ebe2f",
"armv7l-linux": "a4345bb87504b6b2bef29c0dc53b99770b203a7052fd2c5d38fd3e16177d3e68",
"headers": "096wv1fp5m6nlsv11hsa2jj4yr8mb8pjh16s7ip5amj0phlx5783",
"x86_64-darwin": "232a83cb11b37f67dc0683402463ef30ac0309afb8e96f3bc1ea53e72fafa789",
"x86_64-linux": "f0028975282a6f2946797175ac406a95096f29c5dcda98048148668dfa36eff8"
},
"version": "38.2.0"
}
}

View File

@@ -0,0 +1,217 @@
#! /usr/bin/env nix-shell
#! nix-shell -i python -p python3.pkgs.click python3.pkgs.click-log nix
"""
electron updater
A script for updating binary hashes.
It supports the following modes:
| Mode | Description |
|------------- | ----------------------------------------------- |
| `update` | for updating a specific Electron release |
| `update-all` | for updating all electron releases at once |
The `update` command requires a `--version` flag
to specify the major release to be update.
The `update-all` command updates all non-eol major releases.
The `update` and `update-all` commands accept an optional `--commit`
flag to automatically commit the changes for you.
"""
import logging
import os
import subprocess
import sys
import click
import click_log
from typing import Tuple
os.chdir(os.path.dirname(__file__))
sys.path.append("..")
from update_util import *
# Relatice path to the electron-bin info.json
BINARY_INFO_JSON = "info.json"
# Relative path the the electron-chromedriver info.json
CHROMEDRIVER_INFO_JSON = "../chromedriver/info.json"
logger = logging.getLogger(__name__)
click_log.basic_config(logger)
systems = {
"i686-linux": "linux-ia32",
"x86_64-linux": "linux-x64",
"armv7l-linux": "linux-armv7l",
"aarch64-linux": "linux-arm64",
"x86_64-darwin": "darwin-x64",
"aarch64-darwin": "darwin-arm64",
}
def get_shasums256(version: str) -> list:
"""Returns the contents of SHASUMS256.txt"""
try:
called_process: subprocess.CompletedProcess = subprocess.run(
[
"nix-prefetch-url",
"--print-path",
f"https://github.com/electron/electron/releases/download/v{version}/SHASUMS256.txt",
],
capture_output=True,
check=True,
text=True,
)
hash_file_path = called_process.stdout.split("\n")[1]
with open(hash_file_path, "r") as f:
return f.read().split("\n")
except subprocess.CalledProcessError as err:
print(err.stderr)
sys.exit(1)
def get_headers(version: str) -> str:
"""Returns the hash of the release headers tarball"""
try:
called_process: subprocess.CompletedProcess = subprocess.run(
[
"nix-prefetch-url",
"--unpack",
f"https://artifacts.electronjs.org/headers/dist/v{version}/node-v{version}-headers.tar.gz",
],
capture_output=True,
check=True,
text=True,
)
return called_process.stdout.split("\n")[0]
except subprocess.CalledProcessError as err:
print(err.stderr)
sys.exit(1)
def get_electron_hashes(major_version: str) -> dict:
"""Returns a dictionary of hashes for a given major version"""
m, _ = get_latest_version(major_version)
version: str = m["version"]
out = {}
out[major_version] = {
"hashes": {},
"version": version,
}
hashes: list = get_shasums256(version)
for nix_system, electron_system in systems.items():
filename = f"*electron-v{version}-{electron_system}.zip"
if any([x.endswith(filename) for x in hashes]):
out[major_version]["hashes"][nix_system] = [
x.split(" ")[0] for x in hashes if x.endswith(filename)
][0]
out[major_version]["hashes"]["headers"] = get_headers(version)
return out
def get_chromedriver_hashes(major_version: str) -> dict:
"""Returns a dictionary of hashes for a given major version"""
m, _ = get_latest_version(major_version)
version: str = m["version"]
out = {}
out[major_version] = {
"hashes": {},
"version": version,
}
hashes: list = get_shasums256(version)
for nix_system, electron_system in systems.items():
filename = f"*chromedriver-v{version}-{electron_system}.zip"
if any([x.endswith(filename) for x in hashes]):
out[major_version]["hashes"][nix_system] = [
x.split(" ")[0] for x in hashes if x.endswith(filename)
][0]
out[major_version]["hashes"]["headers"] = get_headers(version)
return out
def update_binary(major_version: str, commit: bool, chromedriver: bool) -> None:
"""Update a given electron-bin or chromedriver release
Args:
major_version: The major version number, e.g. '27'
commit: Whether the updater should commit the result
"""
if chromedriver:
json_path=CHROMEDRIVER_INFO_JSON
package_name = f"electron-chromedriver_{major_version}"
update_fn=get_chromedriver_hashes
else:
json_path=BINARY_INFO_JSON
package_name = f"electron_{major_version}-bin"
update_fn = get_electron_hashes
print(f"Updating {package_name}")
old_info = load_info_json(json_path)
new_info = update_fn(major_version)
out = old_info | new_info
save_info_json(json_path, out)
old_version = (
old_info[major_version]["version"] if major_version in old_info else None
)
new_version = new_info[major_version]["version"]
if old_version == new_version:
print(f"{package_name} is up-to-date")
elif commit:
commit_result(package_name, old_version, new_version, json_path)
@click.group()
def cli() -> None:
"""A script for updating electron-bin and chromedriver hashes"""
pass
@cli.command("update-chromedriver", help="Update a single major release")
@click.option("-v", "--version", help="The major version, e.g. '23'")
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
def update_chromedriver(version: str, commit: bool) -> None:
update_binary(version, commit, True)
@cli.command("update", help="Update a single major release")
@click.option("-v", "--version", required=True, type=str, help="The major version, e.g. '23'")
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
def update(version: str, commit: bool) -> None:
update_binary(version, commit, False)
update_binary(version, commit, True)
@cli.command("update-all", help="Update all releases at once")
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
def update_all(commit: bool) -> None:
# Filter out releases that have reached end-of-life
filtered_bin_info = dict(
filter(
lambda entry: int(entry[0]) in supported_version_range(),
load_info_json(BINARY_INFO_JSON).items(),
)
)
for major_version, _ in filtered_bin_info.items():
update_binary(str(major_version), commit, False)
update_binary(str(major_version), commit, True)
if __name__ == "__main__":
cli()

View File

@@ -0,0 +1,15 @@
let
infoJson = builtins.fromJSON (builtins.readFile ./info.json);
in
{ lib, callPackage }:
let
mkElectronChromedriver = callPackage ./generic.nix { };
in
lib.mapAttrs' (
majorVersion: info:
lib.nameValuePair "electron-chromedriver_${majorVersion}" (
mkElectronChromedriver info.version info.hashes
)
) infoJson

View File

@@ -0,0 +1,110 @@
{
lib,
stdenv,
fetchurl,
glib,
xorg,
nspr,
nss,
autoPatchelfHook,
unzip,
}:
version: hashes:
let
pname = "electron-chromedriver";
meta = with lib; {
homepage = "https://www.electronjs.org/";
description = "WebDriver server for running Selenium tests on Chrome";
longDescription = ''
WebDriver is an open source tool for automated testing of webapps across
many browsers. It provides capabilities for navigating to web pages, user
input, JavaScript execution, and more. ChromeDriver is a standalone
server that implements the W3C WebDriver standard. This is
an unofficial build of ChromeDriver compiled by the Electronjs
project.
'';
sourceProvenance = with sourceTypes; [ binaryNativeCode ];
license = licenses.mit;
maintainers = with maintainers; [
liammurphy14
yayayayaka
];
platforms = [
"x86_64-darwin"
"x86_64-linux"
"armv7l-linux"
"aarch64-linux"
"aarch64-darwin"
];
mainProgram = "chromedriver";
};
fetcher =
vers: tag: hash:
fetchurl {
url = "https://github.com/electron/electron/releases/download/v${vers}/chromedriver-v${vers}-${tag}.zip";
sha256 = hash;
};
tags = {
x86_64-linux = "linux-x64";
aarch64-linux = "linux-arm64";
armv7l-linux = "linux-armv7l";
x86_64-darwin = "darwin-x64";
aarch64-darwin = "darwin-arm64";
};
get = as: platform: as.${platform.system} or (throw "Unsupported system: ${platform.system}");
common = platform: {
inherit pname version meta;
src = fetcher version (get tags platform) (get hashes platform);
buildInputs = [
(lib.getLib stdenv.cc.cc)
glib
xorg.libxcb
nspr
nss
];
};
linux = {
nativeBuildInputs = [
autoPatchelfHook
unzip
];
dontUnpack = true;
dontBuild = true;
installPhase = ''
runHook preInstall
unzip $src
install -m777 -D chromedriver $out/bin/chromedriver
runHook postInstall
'';
};
darwin = {
nativeBuildInputs = [ unzip ];
dontUnpack = true;
dontBuild = true;
# darwin distributions come with libffmpeg dependency + icudtl.dat file
installPhase = ''
runHook preInstall
unzip $src
install -m777 -D chromedriver $out/bin/chromedriver
cp libffmpeg.dylib $out/bin/libffmpeg.dylib
cp icudtl.dat $out/bin/icudtl.dat
runHook postInstall
'';
};
in
stdenv.mkDerivation (
(common stdenv.hostPlatform) // (if stdenv.hostPlatform.isDarwin then darwin else linux)
)

View File

@@ -0,0 +1,46 @@
{
"35": {
"hashes": {
"aarch64-darwin": "9559c7dd0f59b4f9949ce982d589079123b6a1f0677fd7c2260473120e73d487",
"aarch64-linux": "ab98b00e04b7f86e9f7ea8d79ab00cb317e4e3f75501e7257702510979443dbc",
"armv7l-linux": "0fe5eb017c99d8b7727797595957907a9050a773ff1dc6aa1a7184a603235bfc",
"headers": "1w8qcgsbii6gizv31i1nkbhaipcr6r1x384wkwnxp60dk9a6cl59",
"x86_64-darwin": "19911b618f920d21244d8ea3c5ea33aea94ac6155ba88952f2846fb366798997",
"x86_64-linux": "f6a0a3850fc1b63ded8d5bf1ec70308c6ee99f3bc8133d628167bb1ae6afe990"
},
"version": "35.7.5"
},
"36": {
"hashes": {
"aarch64-darwin": "843592feae9fd5cd698cf5db2bcebe59654b108899fa5987a0b3cb34a0245bad",
"aarch64-linux": "9d6c593a608d8a9eb4e6bd1e6aaa84a6c3417b3080f933100790d22661d6b10e",
"armv7l-linux": "78070ec874d829b836cb929272c6264fff1855a1b85cc562d5d907b3f735715c",
"headers": "0fv8hz55xk76vksj8sagfhja0xx03ks8awi3sbmlinjb9m02hb9p",
"x86_64-darwin": "c1c4dd9cda4d9b9b31599716fc63dc71e1f1d6e300a4d4c019fe2bc02ef56557",
"x86_64-linux": "609de7bc826d6c858ce7703d8be9abc0a14d35ab745d178893cadf1291f35fa7"
},
"version": "36.9.2"
},
"37": {
"hashes": {
"aarch64-darwin": "ea1b52ec0af04037b419897585ebb2e81f65ccd79dd8f331e26578d042c01a2f",
"aarch64-linux": "5c588569bbbca2bcef0881ea877d70dafcf7955e0d19765797f60e2c4d228c8a",
"armv7l-linux": "87a781e82f4fc530820311edc059eafe30e9cec673704c8e73ebf452c5382bc6",
"headers": "0pxwny0ynvyqb3zqnharc4mkgj6acipqra1jjmf4hbr2a8m5fnc6",
"x86_64-darwin": "667a9067a774a5ada82a44bc310a23657dc2942067732b6c2879ae0042e2faf2",
"x86_64-linux": "e1c04c3826e506765e90d95738d1cf0ecbb3a798f2f3a7bf17d0cc03fe0be1fe"
},
"version": "37.6.0"
},
"38": {
"hashes": {
"aarch64-darwin": "97345d6f601c009ae810ee82dea77d90ff32040f95aefa7d1dbd95ab76ccebc7",
"aarch64-linux": "a1402389fe0b9687308020bc9b58909fa0987e5af3f5368557a88f18c9576a02",
"armv7l-linux": "7d038066c6c708517c08f06972dc688364a60b4537e1b83c3bf1db1baf290e45",
"headers": "096wv1fp5m6nlsv11hsa2jj4yr8mb8pjh16s7ip5amj0phlx5783",
"x86_64-darwin": "d116d52170eecf0b982c0019f538aa7f01646c8b32b85512ec36096d18a3ed68",
"x86_64-linux": "0ad0238eedb81f71ade28056288b13a3c6a5223654300c423eb266ac0163765c"
},
"version": "38.2.0"
}
}

View File

@@ -0,0 +1,348 @@
{
lib,
stdenv,
chromium,
nodejs,
fetchYarnDeps,
fetchNpmDeps,
fetchpatch,
fixup-yarn-lock,
npmHooks,
yarn,
libnotify,
unzip,
pkgsBuildHost,
pipewire,
libsecret,
libpulseaudio,
speechd-minimal,
info,
gclient2nix,
}:
let
gclientDeps = gclient2nix.importGclientDeps info.deps;
in
((chromium.override { upstream-info = info.chromium; }).mkDerivation (base: {
packageName = "electron";
inherit (info) version;
buildTargets = [
"electron:copy_node_headers"
"electron:electron_dist_zip"
];
outputs = [
"out"
"headers"
];
# don't automatically move the include directory from $headers back into $out
moveToDev = false;
nativeBuildInputs = base.nativeBuildInputs ++ [
nodejs
yarn
fixup-yarn-lock
unzip
npmHooks.npmConfigHook
gclient2nix.gclientUnpackHook
];
buildInputs = base.buildInputs ++ [ libnotify ];
electronOfflineCache = fetchYarnDeps {
yarnLock = gclientDeps."src/electron".path + "/yarn.lock";
sha256 = info.electron_yarn_hash;
};
npmDeps = fetchNpmDeps rec {
src = gclientDeps."src".path;
# Assume that the fetcher always unpack the source,
# based on update.py
sourceRoot = "${src.name}/third_party/node";
hash = info.chromium_npm_hash;
};
inherit gclientDeps;
unpackPhase = null; # prevent chromium's unpackPhase from being used
sourceRoot = "src";
env =
base.env
// {
# Hydra can fail to build electron due to clang spamming deprecation
# warnings mid-build, causing the build log to grow beyond the limit
# of 64mb and then getting killed by Hydra.
# For some reason, the log size limit appears to only be enforced on
# aarch64-linux. x86_64-linux happily succeeds to build with ~180mb. To
# unbreak the build on h.n.o, we simply disable those warnings for now.
# https://hydra.nixos.org/build/283952243
NIX_CFLAGS_COMPILE = base.env.NIX_CFLAGS_COMPILE + " -Wno-deprecated";
}
// lib.optionalAttrs (lib.versionAtLeast info.version "35") {
# Needed for header generation in electron 35 and above
ELECTRON_OUT_DIR = "Release";
};
src = null;
patches =
base.patches
# Fix building with Rust 1.87+
# https://issues.chromium.org/issues/407024458
++ lib.optionals (lib.versionOlder info.version "37") [
# https://chromium-review.googlesource.com/c/chromium/src/+/6432410
# Not using fetchpatch here because it ignores file renames: https://github.com/nixos/nixpkgs/issues/32084
./Reland-Use-global_allocator-to-provide-Rust-allocator-implementation.patch
# https://chromium-review.googlesource.com/c/chromium/src/+/6434355
(fetchpatch {
name = "Call-Rust-default-allocator-directly-from-Rust.patch";
url = "https://github.com/chromium/chromium/commit/73eef8797a8138f5c26f52a1372644b20613f5ee.patch";
hash = "sha256-IcSjPv21xT+l9BwJuzeW2AfwBdKI0dQb3nskk6yeKHU=";
})
# https://chromium-review.googlesource.com/c/chromium/src/+/6439711
(fetchpatch {
name = "Roll-rust.patch";
url = "https://github.com/chromium/chromium/commit/a6c30520486be844735dc646cd5b9b434afa0c6b.patch";
includes = [ "build/rust/allocator/*" ];
hash = "sha256-MFdR75oSAdFW6telEZt/s0qdUvq/BiYFEHW0vk+RgDk=";
})
# https://chromium-review.googlesource.com/c/chromium/src/+/6456604
(fetchpatch {
name = "Drop-remap_alloc-dep.patch";
url = "https://github.com/chromium/chromium/commit/87d5ad2f621e0d5c81849dde24f3a5347efcb167.patch";
hash = "sha256-bEoR6jxEyw6Fzm4Zv4US54Cxa0li/0UTZTU2WUf0Rgo=";
})
# https://chromium-review.googlesource.com/c/chromium/src/+/6454872
(fetchpatch {
name = "rust-Clean-up-build-rust-allocator-after-a-Rust-tool.patch";
url = "https://github.com/chromium/chromium/commit/5c74fcf6fd14491f33dd820022a9ca045f492f68.patch";
hash = "sha256-vcD0Zfo4Io/FVpupWOdgurFEqwFCv+oDOtSmHbm+ons=";
})
]
# Fix building with gperf 3.2+
# https://issues.chromium.org/issues/40209959
++ lib.optionals (lib.versionOlder info.version "37") [
# https://chromium-review.googlesource.com/c/chromium/src/+/6445471
(fetchpatch {
name = "Dont-apply-FALLTHROUGH-edit-to-gperf-3-2-output.patch";
url = "https://github.com/chromium/chromium/commit/f8f21fb4aa01f75acbb12abf5ea8c263c6817141.patch";
hash = "sha256-z/aQ1oQjFZnkUeRnrD6P/WDZiYAI1ncGhOUM+HmjMZA=";
})
]
# Fix build with Rust 1.89.0
++ lib.optionals (lib.versionOlder info.version "38") [
# https://chromium-review.googlesource.com/c/chromium/src/+/6624733
(fetchpatch {
name = "Define-rust-no-alloc-shim-is-unstable-v2.patch";
url = "https://github.com/chromium/chromium/commit/6aae0e2353c857d98980ff677bf304288d7c58de.patch";
hash = "sha256-Dd38c/0hiH+PbGPJhhEFuW6kUR45A36XZqOVExoxlhM=";
})
]
++ lib.optionals (lib.versionOlder info.version "38") [
# Fix build with LLVM 21+
# https://chromium-review.googlesource.com/c/chromium/src/+/6633292
(fetchpatch {
name = "Dont-return-an-enum-from-EnumSizeTraits-Count.patch";
url = "https://github.com/chromium/chromium/commit/b0ff8c3b258a8816c05bdebf472dbba719d3c491.patch";
hash = "sha256-YIWcsCj5w0jUd7D67hsuk0ljTA/IbHwA6db3eK4ggUY=";
})
];
npmRoot = "third_party/node";
postPatch = ''
mkdir -p third_party/jdk/current/bin
echo 'build_with_chromium = true' >> build/config/gclient_args.gni
echo 'checkout_google_benchmark = false' >> build/config/gclient_args.gni
echo 'checkout_android = false' >> build/config/gclient_args.gni
echo 'checkout_android_prebuilts_build_tools = false' >> build/config/gclient_args.gni
echo 'checkout_android_native_support = false' >> build/config/gclient_args.gni
echo 'checkout_ios_webkit = false' >> build/config/gclient_args.gni
echo 'checkout_nacl = false' >> build/config/gclient_args.gni
echo 'checkout_openxr = false' >> build/config/gclient_args.gni
echo 'checkout_rts_model = false' >> build/config/gclient_args.gni
echo 'checkout_src_internal = false' >> build/config/gclient_args.gni
echo 'cros_boards = ""' >> build/config/gclient_args.gni
echo 'cros_boards_with_qemu_images = ""' >> build/config/gclient_args.gni
echo 'generate_location_tags = true' >> build/config/gclient_args.gni
echo 'LASTCHANGE=${info.deps."src".args.tag}-refs/heads/master@{#0}' > build/util/LASTCHANGE
echo "$SOURCE_DATE_EPOCH" > build/util/LASTCHANGE.committime
cat << EOF > gpu/config/gpu_lists_version.h
/* Generated by lastchange.py, do not edit.*/
#ifndef GPU_CONFIG_GPU_LISTS_VERSION_H_
#define GPU_CONFIG_GPU_LISTS_VERSION_H_
#define GPU_LISTS_VERSION "${info.deps."src".args.tag}"
#endif // GPU_CONFIG_GPU_LISTS_VERSION_H_
EOF
cat << EOF > skia/ext/skia_commit_hash.h
/* Generated by lastchange.py, do not edit.*/
#ifndef SKIA_EXT_SKIA_COMMIT_HASH_H_
#define SKIA_EXT_SKIA_COMMIT_HASH_H_
#define SKIA_COMMIT_HASH "${info.deps."src/third_party/skia".args.rev}-"
#endif // SKIA_EXT_SKIA_COMMIT_HASH_H_
EOF
echo -n '${info.deps."src/third_party/dawn".args.rev}' > gpu/webgpu/DAWN_VERSION
(
cd electron
export HOME=$TMPDIR/fake_home
yarn config --offline set yarn-offline-mirror $electronOfflineCache
fixup-yarn-lock yarn.lock
yarn install --offline --frozen-lockfile --ignore-scripts --no-progress --non-interactive
)
(
cd ..
PATH=$PATH:${
lib.makeBinPath (
with pkgsBuildHost;
[
jq
git
]
)
}
config=src/electron/patches/config.json
for entry in $(cat $config | jq -c ".[]")
do
patch_dir=$(echo $entry | jq -r ".patch_dir")
repo=$(echo $entry | jq -r ".repo")
for patch in $(cat $patch_dir/.patches)
do
echo applying in $repo: $patch
git apply -p1 --directory=$repo --exclude='src/third_party/blink/web_tests/*' --exclude='src/content/test/data/*' $patch_dir/$patch
done
done
)
''
+ lib.optionalString (lib.versionAtLeast info.version "36") ''
echo 'checkout_glic_e2e_tests = false' >> build/config/gclient_args.gni
echo 'checkout_mutter = false' >> build/config/gclient_args.gni
''
+ lib.optionalString (lib.versionAtLeast info.version "38") ''
echo 'checkout_clusterfuzz_data = false' >> build/config/gclient_args.gni
''
+ base.postPatch;
preConfigure = ''
(
cd third_party/node
grep patch update_npm_deps | sh
)
''
+ (base.preConfigure or "");
gnFlags = rec {
# build/args/release.gn
is_component_build = false;
is_official_build = true;
rtc_use_h264 = proprietary_codecs;
is_component_ffmpeg = true;
# build/args/all.gn
is_electron_build = true;
root_extra_deps = [ "//electron" ];
node_module_version = lib.toInt info.modules;
v8_promise_internal_field_count = 1;
v8_embedder_string = "-electron.0";
v8_enable_snapshot_native_code_counters = false;
v8_enable_javascript_promise_hooks = true;
enable_cdm_host_verification = false;
proprietary_codecs = true;
ffmpeg_branding = "Chrome";
enable_printing = true;
angle_enable_vulkan_validation_layers = false;
dawn_enable_vulkan_validation_layers = false;
enable_pseudolocales = false;
allow_runtime_configurable_key_storage = true;
enable_cet_shadow_stack = false;
is_cfi = false;
v8_builtins_profiling_log_file = "";
enable_dangling_raw_ptr_checks = false;
dawn_use_built_dxc = false;
v8_enable_private_mapping_fork_optimization = true;
v8_expose_public_symbols = true;
enable_dangling_raw_ptr_feature_flag = false;
clang_unsafe_buffers_paths = "";
enterprise_cloud_content_analysis = false;
# other
enable_widevine = false;
override_electron_version = info.version;
}
// lib.optionalAttrs (lib.versionOlder info.version "38") {
content_enable_legacy_ipc = true;
};
installPhase = ''
runHook preInstall
mkdir -p $libExecPath
unzip -d $libExecPath out/Release/dist.zip
mkdir -p $headers
cp -r out/Release/gen/node_headers/* $headers/
runHook postInstall
'';
postFixup =
let
libPath = lib.makeLibraryPath [
libnotify
pipewire
stdenv.cc.cc
libsecret
libpulseaudio
speechd-minimal
];
in
base.postFixup
+ ''
patchelf \
--add-rpath "${libPath}" \
$out/libexec/electron/electron
'';
requiredSystemFeatures = [ "big-parallel" ];
passthru = {
inherit info;
};
meta = with lib; {
description = "Cross platform desktop application shell";
homepage = "https://github.com/electron/electron";
platforms = lib.platforms.linux;
license = licenses.mit;
maintainers = with maintainers; [
yayayayaka
teutat3s
tomasajt
];
mainProgram = "electron";
hydraPlatforms =
lib.optionals (!(hasInfix "alpha" info.version) && !(hasInfix "beta" info.version))
[
"aarch64-linux"
"x86_64-linux"
];
timeout = 172800; # 48 hours (increased from the Hydra default of 10h)
};
})).overrideAttrs
(
finalAttrs: prevAttrs: {
# this was the only way I could get the package to properly reference itself
passthru = prevAttrs.passthru // {
dist = finalAttrs.finalPackage + "/libexec/electron";
};
}
)

View File

@@ -0,0 +1,14 @@
{ lib, callPackage }:
let
versions = lib.importJSON ./info.json;
in
lib.mapAttrs' (
version: info:
lib.nameValuePair "electron_${version}" (
let
electron-unwrapped = callPackage ./common.nix { inherit info; };
in
callPackage ./wrapper.nix { inherit electron-unwrapped; }
)
) versions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,246 @@
#! /usr/bin/env nix-shell
#! nix-shell -i python -p python3.pkgs.joblib python3.pkgs.click python3.pkgs.click-log nix nurl prefetch-yarn-deps prefetch-npm-deps gclient2nix
"""
electron updater
A script for updating electron source hashes.
It supports the following modes:
| Mode | Description |
|------------- | ----------------------------------------------- |
| `update` | for updating a specific Electron release |
| `update-all` | for updating all electron releases at once |
The `update` commands requires a `--version` flag
to specify the major release to be updated.
The `update-all command updates all non-eol major releases.
The `update` and `update-all` commands accept an optional `--commit`
flag to automatically commit the changes for you.
"""
import base64
import json
import logging
import os
import random
import re
import subprocess
import sys
import tempfile
import urllib.request
import click
import click_log
from datetime import datetime, UTC
from typing import Iterable, Tuple
from urllib.request import urlopen
from joblib import Parallel, delayed, Memory
from update_util import *
# Relative path to the electron-source info.json
SOURCE_INFO_JSON = "info.json"
os.chdir(os.path.dirname(__file__))
# Absolute path of nixpkgs top-level directory
NIXPKGS_PATH = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode("utf-8").strip()
memory: Memory = Memory("cache", verbose=0)
logger = logging.getLogger(__name__)
click_log.basic_config(logger)
def get_gclient_data(rev: str) -> any:
output = subprocess.check_output(
["gclient2nix", "generate",
f"https://github.com/electron/electron@{rev}",
"--root", "src/electron"]
)
return json.loads(output)
def get_chromium_file(chromium_tag: str, filepath: str) -> str:
return base64.b64decode(
urlopen(
f"https://chromium.googlesource.com/chromium/src.git/+/{chromium_tag}/{filepath}?format=TEXT"
).read()
).decode("utf-8")
def get_electron_file(electron_tag: str, filepath: str) -> str:
return (
urlopen(
f"https://raw.githubusercontent.com/electron/electron/{electron_tag}/{filepath}"
)
.read()
.decode("utf-8")
)
@memory.cache
def get_gn_hash(gn_version, gn_commit):
print("gn.override", file=sys.stderr)
expr = f'(import {NIXPKGS_PATH} {{}}).gn.override {{ version = "{gn_version}"; rev = "{gn_commit}"; hash = ""; }}'
out = subprocess.check_output(["nurl", "--hash", "--expr", expr])
return out.decode("utf-8").strip()
@memory.cache
def get_chromium_gn_source(chromium_tag: str) -> dict:
gn_pattern = r"'gn_version': 'git_revision:([0-9a-f]{40})'"
gn_commit = re.search(gn_pattern, get_chromium_file(chromium_tag, "DEPS")).group(1)
gn_commit_info = json.loads(
urlopen(f"https://gn.googlesource.com/gn/+/{gn_commit}?format=json")
.read()
.decode("utf-8")
.split(")]}'\n")[1]
)
gn_commit_date = datetime.strptime(gn_commit_info["committer"]["time"], "%a %b %d %H:%M:%S %Y %z")
gn_date = gn_commit_date.astimezone(UTC).date().isoformat()
gn_version = f"0-unstable-{gn_date}"
return {
"gn": {
"version": gn_version,
"rev": gn_commit,
"hash": get_gn_hash(gn_version, gn_commit),
}
}
@memory.cache
def get_electron_yarn_hash(electron_tag: str) -> str:
print(f"prefetch-yarn-deps", file=sys.stderr)
with tempfile.TemporaryDirectory() as tmp_dir:
with open(tmp_dir + "/yarn.lock", "w") as f:
f.write(get_electron_file(electron_tag, "yarn.lock"))
return (
subprocess.check_output(["prefetch-yarn-deps", tmp_dir + "/yarn.lock"])
.decode("utf-8")
.strip()
)
@memory.cache
def get_chromium_npm_hash(chromium_tag: str) -> str:
print(f"prefetch-npm-deps", file=sys.stderr)
with tempfile.TemporaryDirectory() as tmp_dir:
with open(tmp_dir + "/package-lock.json", "w") as f:
f.write(get_chromium_file(chromium_tag, "third_party/node/package-lock.json"))
return (
subprocess.check_output(
["prefetch-npm-deps", tmp_dir + "/package-lock.json"]
)
.decode("utf-8")
.strip()
)
def get_update(major_version: str, m: str, gclient_data: any) -> Tuple[str, dict]:
tasks = []
a = lambda: (("electron_yarn_hash", get_electron_yarn_hash(gclient_data["src/electron"]["args"]["tag"])))
tasks.append(delayed(a)())
a = lambda: (
(
"chromium_npm_hash",
get_chromium_npm_hash(gclient_data["src"]["args"]["tag"]),
)
)
tasks.append(delayed(a)())
random.shuffle(tasks)
task_results = {
n[0]: n[1]
for n in Parallel(n_jobs=3, require="sharedmem", return_as="generator")(tasks)
if n != None
}
return (
f"{major_version}",
{
"deps": gclient_data,
**{key: m[key] for key in ["version", "modules", "chrome", "node"]},
"chromium": {
"version": m["chrome"],
"deps": get_chromium_gn_source(gclient_data["src"]["args"]["tag"]),
},
**task_results,
},
)
def non_eol_releases(releases: Iterable[int]) -> Iterable[int]:
"""Returns a list of releases that have not reached end-of-life yet."""
return tuple(filter(lambda x: x in supported_version_range(), releases))
def update_source(version: str, commit: bool) -> None:
"""Update a given electron-source release
Args:
version: The major version number, e.g. '27'
commit: Whether the updater should commit the result
"""
major_version = version
package_name = f"electron-source.electron_{major_version}"
print(f"Updating electron-source.electron_{major_version}")
old_info = load_info_json(SOURCE_INFO_JSON)
old_version = (
old_info[major_version]["version"]
if major_version in old_info
else None
)
m, rev = get_latest_version(major_version)
if old_version == m["version"]:
print(f"{package_name} is up-to-date")
return
gclient_data = get_gclient_data(rev)
new_info = get_update(major_version, m, gclient_data)
out = old_info | {new_info[0]: new_info[1]}
save_info_json(SOURCE_INFO_JSON, out)
new_version = new_info[1]["version"]
if commit:
commit_result(package_name, old_version, new_version, SOURCE_INFO_JSON)
@click.group()
def cli() -> None:
"""A script for updating electron-source hashes"""
pass
@cli.command("update", help="Update a single major release")
@click.option("-v", "--version", required=True, type=str, help="The major version, e.g. '23'")
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
def update(version: str, commit: bool) -> None:
update_source(version, commit)
@cli.command("update-all", help="Update all releases at once")
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
def update_all(commit: bool) -> None:
"""Update all eletron-source releases at once
Args:
commit: Whether to commit the result
"""
old_info = load_info_json(SOURCE_INFO_JSON)
filtered_releases = non_eol_releases(tuple(map(lambda x: int(x), old_info.keys())))
for major_version in filtered_releases:
update_source(str(major_version), commit)
if __name__ == "__main__":
cli()

View File

@@ -0,0 +1,161 @@
import json
import re
import sys
import subprocess
import urllib.request
from typing import Iterable, Optional, Tuple
from urllib.request import urlopen
from datetime import datetime
# Number of spaces used for each indentation level
JSON_INDENT = 4
releases_json = None
# Releases that have reached end-of-life no longer receive any updates
# and it is rather pointless trying to update those.
#
# https://endoflife.date/electron
def supported_version_range() -> range:
"""Returns a range of electron releases that have not reached end-of-life yet"""
global releases_json
if releases_json is None:
releases_json = json.loads(
urlopen("https://endoflife.date/api/electron.json").read()
)
supported_releases = [
int(x["cycle"])
for x in releases_json
if x["eol"] == False
or datetime.strptime(x["eol"], "%Y-%m-%d") > datetime.today()
]
return range(
min(supported_releases), # incl.
# We have also packaged the beta release in nixpkgs,
# but it is not tracked by endoflife.date
max(supported_releases) + 2, # excl.
1,
)
def get_latest_version(major_version: str) -> Tuple[str, str]:
"""Returns the latest version for a given major version"""
electron_releases: dict = json.loads(
urlopen("https://releases.electronjs.org/releases.json").read()
)
major_version_releases = filter(
lambda item: item["version"].startswith(f"{major_version}."), electron_releases
)
m = max(major_version_releases, key=lambda item: item["date"])
rev = f"v{m['version']}"
return (m, rev)
def load_info_json(path: str) -> dict:
"""Load the contents of a JSON file
Args:
path: The path to the JSON file
Returns: An empty dict if the path does not exist, otherwise the contents of the JSON file.
"""
try:
with open(path, "r") as f:
return json.loads(f.read())
except:
return {}
def save_info_json(path: str, content: dict) -> None:
"""Saves the given info to a JSON file
Args:
path: The path where the info should be saved
content: The content to be saved as JSON.
"""
with open(path, "w") as f:
f.write(json.dumps(content, indent=JSON_INDENT, default=vars, sort_keys=True))
f.write("\n")
def parse_cve_numbers(tag_name: str) -> Iterable[str]:
"""Returns mentioned CVE numbers from a given release tag"""
cve_pattern = r"CVE-\d{4}-\d+"
url = f"https://api.github.com/repos/electron/electron/releases/tags/{tag_name}"
headers = {
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
}
request = urllib.request.Request(url=url, headers=headers)
release_note = ""
try:
with urlopen(request) as response:
release_note = json.loads(response.read().decode("utf-8"))["body"]
except:
print(
f"WARN: Fetching release note for {tag_name} from GitHub failed!",
file=sys.stderr,
)
return sorted(re.findall(cve_pattern, release_note))
def commit_result(
package_name: str, old_version: Optional[str], new_version: str, path: str
) -> None:
"""Creates a git commit with a short description of the change
Args:
package_name: The package name, e.g. `electron-source.electron-{major_version}`
or `electron_{major_version}-bin`
old_version: Version number before the update.
Can be left empty when initializing a new release.
new_version: Version number after the update.
path: Path to the lockfile to be committed
"""
assert (
isinstance(package_name, str) and len(package_name) > 0
), "Argument `package_name` cannot be empty"
assert (
isinstance(new_version, str) and len(new_version) > 0
), "Argument `new_version` cannot be empty"
if old_version != new_version:
major_version = new_version.split(".")[0]
cve_fixes_text = "\n".join(
list(
map(lambda cve: f"- Fixes {cve}", parse_cve_numbers(f"v{new_version}"))
)
)
init_msg = f"init at {new_version}"
update_msg = f"{old_version} -> {new_version}"
diff = (
f"- Diff: https://github.com/electron/electron/compare/refs/tags/v{old_version}...v{new_version}\n"
if old_version != None
else ""
)
commit_message = f"""{package_name}: {update_msg if old_version != None else init_msg}
- Changelog: https://github.com/electron/electron/releases/tag/v{new_version}
{diff}{cve_fixes_text}
"""
subprocess.run(
[
"git",
"add",
path,
]
)
subprocess.run(
[
"git",
"commit",
"-m",
commit_message,
]
)

View File

@@ -0,0 +1,44 @@
{
stdenv,
electron-unwrapped,
wrapGAppsHook3,
makeWrapper,
gsettings-desktop-schemas,
glib,
gtk3,
gtk4,
}:
stdenv.mkDerivation {
pname = "electron";
inherit (electron-unwrapped) version;
nativeBuildInputs = [
wrapGAppsHook3
makeWrapper
];
buildInputs = [
# needed for GSETTINGS_SCHEMAS_PATH
gsettings-desktop-schemas
glib
gtk3
gtk4
];
dontWrapGApps = true;
buildCommand = ''
gappsWrapperArgsHook
mkdir -p $out/bin
makeWrapper "${electron-unwrapped}/libexec/electron/electron" "$out/bin/electron" \
"''${gappsWrapperArgs[@]}" \
--set CHROME_DEVEL_SANDBOX $out/libexec/electron/chrome-sandbox
ln -s ${electron-unwrapped}/libexec $out/libexec
'';
passthru = {
unwrapped = electron-unwrapped;
inherit (electron-unwrapped) headers dist;
};
inherit (electron-unwrapped) meta;
}