signal-desktop: add darwin support (#491588)

This commit is contained in:
Marcin Serwin
2026-02-24 16:25:27 +00:00
committed by GitHub
3 changed files with 154 additions and 49 deletions
+50 -6
View File
@@ -13,6 +13,7 @@
jq,
makeDesktopItem,
copyDesktopItems,
xcodebuild,
replaceVars,
noto-fonts-color-emoji,
nixosTests,
@@ -105,9 +106,14 @@ stdenv.mkDerivation (finalAttrs: {
pnpmConfigHook
pnpm
makeWrapper
copyDesktopItems
python3
jq
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
xcodebuild
]
++ lib.optionals stdenv.hostPlatform.isLinux [
copyDesktopItems
];
buildInputs = (lib.optional (!withAppleEmojis) noto-fonts-color-emoji-png);
@@ -134,6 +140,16 @@ stdenv.mkDerivation (finalAttrs: {
# https://github.com/signalapp/Signal-Desktop/issues/7667
substituteInPlace ts/util/version.std.ts \
--replace-fail 'isAdhoc(version)' 'true'
# Nix builds do not need upstream release hooks (notarization and
# language-pack postprocessing), and they expect a different macOS
# app layout than nixpkgs' Electron provides.
substituteInPlace package.json \
--replace-fail '"artifactBuildCompleted": "ts/scripts/artifact-build-completed.node.js",' "" \
--replace-fail '"afterSign": "ts/scripts/after-sign.node.js",' "" \
--replace-fail '"afterPack": "ts/scripts/after-pack.node.js",' "" \
--replace-fail '"sign": "./ts/scripts/sign-macos.node.js",' "" \
--replace-fail '"afterAllArtifactBuild": "ts/scripts/after-all-artifact-build.node.js",' ""
'';
pnpmDeps = fetchPnpmDeps {
@@ -156,6 +172,10 @@ stdenv.mkDerivation (finalAttrs: {
ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
SIGNAL_ENV = "production";
SOURCE_DATE_EPOCH = 1771441806;
}
// lib.optionalAttrs stdenv.hostPlatform.isDarwin {
# Disable code signing during local macOS builds.
CSC_IDENTITY_AUTO_DISCOVERY = "false";
};
preBuild = ''
@@ -200,6 +220,15 @@ stdenv.mkDerivation (finalAttrs: {
rm -r node_modules/@signalapp/sqlcipher
cp -r ${signal-sqlcipher} node_modules/@signalapp/sqlcipher
# fs-xattr is required at runtime by preload.wrapper.js,
# but with npmRebuild disabled its native binding is missing.
# Build it explicitly against Electron headers ahead of packaging.
export npm_config_nodedir=${electron.headers}
pushd node_modules/fs-xattr
pnpm exec node-gyp rebuild
popd
test -f node_modules/fs-xattr/build/Release/xattr.node
'';
buildPhase = ''
@@ -212,18 +241,29 @@ stdenv.mkDerivation (finalAttrs: {
pnpm run generate
pnpm exec electron-builder \
--linux "dir:${stdenv.hostPlatform.node.arch}" \
${
if stdenv.hostPlatform.isDarwin then "--mac" else "--linux"
} "dir:${stdenv.hostPlatform.node.arch}" \
--config.extraMetadata.environment=$SIGNAL_ENV \
-c.electronDist=electron-dist \
-c.electronVersion=${electron.version}
-c.electronVersion=${electron.version} \
-c.npmRebuild=false \
${lib.optionalString stdenv.hostPlatform.isDarwin "-c.mac.identity=null"}
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/share/
''
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
mkdir -p $out/{Applications,bin}
cp -r dist/mac*/Signal.app $out/Applications
makeWrapper "$out/Applications/Signal.app/Contents/MacOS/Signal" "$out/bin/signal-desktop" \
--add-flags ${lib.escapeShellArg commandLineArgs}
''
+ lib.optionalString (!stdenv.hostPlatform.isDarwin) ''
mkdir -p $out/share
cp -r dist/*-unpacked/resources $out/share/signal-desktop
for icon in build/icons/png/*
@@ -236,7 +276,8 @@ stdenv.mkDerivation (finalAttrs: {
--set-default ELECTRON_FORCE_IS_PACKAGED 1 \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}" \
--add-flags ${lib.escapeShellArg commandLineArgs}
''
+ ''
runHook postInstall
'';
@@ -293,6 +334,7 @@ stdenv.mkDerivation (finalAttrs: {
++ lib.optional withAppleEmojis unfree;
maintainers = with lib.maintainers; [
eclairevoyant
iamanaws
marcin-serwin
teutat3s
];
@@ -300,6 +342,8 @@ stdenv.mkDerivation (finalAttrs: {
platforms = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
};
})
@@ -10,6 +10,8 @@
cargo,
dump_syms,
python3,
xcodebuild,
cctools,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "node-sqlcipher";
@@ -45,6 +47,10 @@ stdenv.mkDerivation (finalAttrs: {
cargo
dump_syms
python3
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
xcodebuild
cctools.libtool
];
buildPhase = ''
@@ -75,6 +81,6 @@ stdenv.mkDerivation (finalAttrs: {
# deps/sqlcipher
bsd3
];
platforms = lib.platforms.linux;
platforms = lib.platforms.linux ++ lib.platforms.darwin;
};
})
+97 -42
View File
@@ -4,6 +4,7 @@
buildPackages,
ninja,
gn,
symlinkJoin,
python3,
pkg-config,
glib,
@@ -12,9 +13,20 @@
writeShellScriptBin,
gclient2nix,
rustc,
apple-sdk,
xcodebuild,
llvmPackages,
}:
let
llvmCcAndBintools = symlinkJoin {
name = "signal-webrtc-llvm-cc-and-bintools";
paths = [
llvmPackages.llvm
llvmPackages.stdenv.cc
];
};
chromiumRosettaStone = {
cpu =
platform:
@@ -39,6 +51,13 @@ stdenv.mkDerivation (finalAttrs: {
gclientDeps = gclient2nix.importGclientDeps ./webrtc-sources.json;
sourceRoot = "src";
# Chromium's Darwin toolchain defines _LIBCPP_HARDENING_MODE itself; keep
# cc-wrapper from injecting a conflicting default.
hardeningDisable = lib.optionals stdenv.isDarwin [
"libcxxhardeningfast"
"libcxxhardeningextensive"
];
nativeBuildInputs = [
gn
ninja
@@ -49,21 +68,44 @@ stdenv.mkDerivation (finalAttrs: {
rustc
pkg-config
gclient2nix.gclientUnpackHook
]
++ lib.optionals stdenv.isDarwin [
apple-sdk
xcodebuild
];
buildInputs = [
glib
alsa-lib
pulseaudio
]
++ lib.optionals stdenv.isDarwin [
llvmPackages.compiler-rt
]
++ lib.optionals stdenv.isLinux [
alsa-lib
];
postPatch = ''
substituteInPlace build/toolchain/linux/BUILD.gn \
--replace-fail 'toolprefix = "aarch64-linux-gnu-"' 'toolprefix = ""'
patchShebangs build/mac/should_use_hermetic_xcode.py
substituteInPlace modules/audio_device/linux/pulseaudiosymboltable_linux.cc \
--replace-fail "libpulse.so.0" "${pulseaudio}/lib/libpulse.so.0"
''
+ lib.optionalString stdenv.isDarwin ''
# Fix Darwin Python script shebangs for sandbox builds
patchShebangs build/mac/should_use_hermetic_xcode.py build/toolchain/apple/linker_driver.py
substituteInPlace build/config/clang/BUILD.gn \
--replace-fail '_clang_lib_dir = "$clang_base_path/lib/clang/$clang_version/lib"' \
'_clang_lib_dir = "${llvmPackages.compiler-rt}/lib"'
# Keep target triple aligned with nix cc-wrapper expectations to avoid
# arm64-apple-macos vs arm64-apple-darwin warning spam.
substituteInPlace build/config/mac/BUILD.gn \
--replace-fail "apple-macos" "apple-darwin"
''
+ lib.optionalString stdenv.isLinux ''
substituteInPlace modules/audio_device/linux/alsasymboltable_linux.cc \
--replace-fail "libasound.so.2" "${alsa-lib}/lib/libasound.so.2"
'';
@@ -73,46 +115,59 @@ stdenv.mkDerivation (finalAttrs: {
echo "generate_location_tags = true" >> build/config/gclient_args.gni
'';
gnFlags = [
# webrtc uses chromium's `src/build/BUILDCONFIG.gn`. many of these flags
# are copied from pkgs/applications/networking/browsers/chromium/common.nix.
''target_os="linux"''
''target_cpu="${chromiumRosettaStone.cpu stdenv.hostPlatform}"''
''pkg_config="${stdenv.cc.targetPrefix}pkg-config"''
"use_sysroot=false"
"is_clang=false"
"treat_warnings_as_errors=false"
"use_llvm_libatomic=false"
"use_custom_libcxx=false"
gnFlags =
lib.optionals stdenv.isLinux [
# webrtc uses chromium's `src/build/BUILDCONFIG.gn`. many of these flags
# are copied from pkgs/applications/networking/browsers/chromium/common.nix.
''target_os="linux"''
''pkg_config="${stdenv.cc.targetPrefix}pkg-config"''
"use_sysroot=false"
"is_clang=false"
# https://github.com/signalapp/ringrtc/blob/main/bin/build-desktop
"rtc_build_examples=false"
"rtc_build_tools=false"
"rtc_use_x11=false"
"rtc_enable_sctp=false"
"rtc_libvpx_build_vp9=true"
"rtc_disable_metrics=true"
"rtc_disable_trace_events=true"
"is_debug=false"
"symbol_level=1"
"rtc_include_tests=false"
"rtc_enable_protobuf=false"
''rust_sysroot_absolute="${buildPackages.rustc}"''
# Build using the system toolchain (for Linux distributions):
#
# What you would expect to be called "target_toolchain" is
# actually called either "default_toolchain" or "custom_toolchain",
# depending on which part of the codebase you are in; see:
# https://chromium.googlesource.com/chromium/src/build/+/3c4595444cc6d514600414e468db432e0f05b40f/config/BUILDCONFIG.gn#17
''custom_toolchain="//build/toolchain/linux/unbundle:default"''
''host_toolchain="//build/toolchain/linux/unbundle:default"''
]
++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
''host_toolchain="//build/toolchain/linux/unbundle:host"''
''v8_snapshot_toolchain="//build/toolchain/linux/unbundle:host"''
];
# Build using the system toolchain (for Linux distributions):
#
# What you would expect to be called "target_toolchain" is
# actually called either "default_toolchain" or "custom_toolchain",
# depending on which part of the codebase you are in; see:
# https://chromium.googlesource.com/chromium/src/build/+/3c4595444cc6d514600414e468db432e0f05b40f/config/BUILDCONFIG.gn#17
''custom_toolchain="//build/toolchain/linux/unbundle:default"''
''host_toolchain="//build/toolchain/linux/unbundle:default"''
]
++ lib.optionals stdenv.isDarwin [
''target_os="mac"''
''mac_deployment_target="${stdenv.hostPlatform.darwinMinVersion}"''
"use_sysroot=true"
"is_clang=true"
"use_lld=false"
"clang_use_chrome_plugins=false"
"clang_use_raw_ptr_plugin=false"
"use_clang_modules=false"
''clang_base_path="${llvmCcAndBintools}"''
''custom_toolchain="//build/toolchain/mac:clang_${chromiumRosettaStone.cpu stdenv.hostPlatform}"''
]
++ [
''target_cpu="${chromiumRosettaStone.cpu stdenv.hostPlatform}"''
# https://github.com/signalapp/ringrtc/blob/main/bin/build-desktop
"rtc_build_examples=false"
"rtc_build_tools=false"
"rtc_use_x11=false"
"rtc_enable_sctp=false"
"rtc_libvpx_build_vp9=true"
"rtc_disable_metrics=true"
"rtc_disable_trace_events=true"
"is_debug=false"
"symbol_level=1"
"rtc_include_tests=false"
"rtc_enable_protobuf=false"
"treat_warnings_as_errors=false"
"use_llvm_libatomic=false"
"use_custom_libcxx=false"
''rust_sysroot_absolute="${buildPackages.rustc}"''
]
++ lib.optionals (stdenv.isLinux && stdenv.buildPlatform != stdenv.hostPlatform) [
''host_toolchain="//build/toolchain/linux/unbundle:host"''
''v8_snapshot_toolchain="//build/toolchain/linux/unbundle:host"''
];
ninjaFlags = [ "webrtc" ];
installPhase = ''
@@ -128,6 +183,6 @@ stdenv.mkDerivation (finalAttrs: {
homepage = "https://github.com/SignalApp/webrtc";
license = lib.licenses.bsd3;
maintainers = [ ];
platforms = lib.platforms.linux;
platforms = lib.platforms.linux ++ lib.platforms.darwin;
};
})