# use: # - nix develop # - mkdir cache-yarn ; rm -rf ~/.cache/yarn ; ln -s $(pwd)/cache-yarn ~/.cache/yarn # - mkdir cache-node-gyp ; rm -rf ~/.cache/node-gyp ; ln -s $(pwd)/cache-node-gyp ~/.cache/node-gyp # - mkdir cache-electron ; rm -rf ~/.cache/electron ; ln -s $(pwd)/cache-electron ~/.cache/electron # - yarn install --frozen-lockfile --ignore-engines # - yarn generate # - yarn start (or, `electron .`) # - patch-signal release/linux-unpacked/signal-desktop # # contributing.md recommends: # > npm install --global yarn # Make sure you have have `yarn` # > yarn install --frozen-lockfile # Install and build dependencies (this will take a while) # > yarn generate # Generate final JS and CSS assets # > yarn test # A good idea to make sure tests run first # > yarn start # Start Signal! # # a build process which creates `release/linux-unpacked/signal-desktop`: # - yarn generate # - yarn build:esbuild:prod # - yarn build:release # # .github/workflows/ci.yml linux build is: # - yarn generate # - yarn prepare-beta-build # - yarn build:esbuild:prod # - DISABLE_INSPECT_FUSE=on yarn build:release -- --publish=never # - DISABLE_INSPECT_FUSE=on yarn build:release --linux dir # - yarn test-node # - ARTIFACTS_DIR=artifacts/linux LANG=en_US LANGUAGE=en_US yarn test-electron # - NODE_ENV=production yarn test-release # # fix for specific problems: # - linux cannot execute required file not found # - patchelf --set-interpreter /nix/store/gqghjch4p1s69sv4mcjksb2kb65rwqjy-glibc-2.38-23/lib/ld-linux-x86-64.so.2 /home/colin/ref/repos/signalapp/Signal-Desktop/node_modules/electron/dist/electron # - /home/colin/.cache/electron-builder/fpm/fpm-1.9.3-2.3.1-linux-x86_64/fpm: no such file or directory # - change fpm's interpreter from #!/bin/bash to #!/bin/sh # - do the same with the `ruby` packaged in fpm # # electron flags to consider # - --no-sandbox # - --no-zygote (fixes Zygote could not fork: process_type gpu-process numfds 3 child_pid -1) # - --disable-gpu # # # debugging notes # `./node_modules/.bin/electron .` is reading `./package.json`. # - dependent on: "main": "app/main.js" # app/main.js is generated (from app/main.ts, checked into git) # - yarn install --ignore-scripts: # - ringrtc uses a script, to DL https://build-artifacts.signal.org/libraries/ringrtc-desktop-build-v2.33.0.tar.gz # - it's in package.scripts.install # - node scripts/fetch-prebuild.js # - wants it to exist as `prebuild.tar.gz` (i could provide that for it) { inputs = { nixpkgs.url = "nixpkgs/nixos-unstable"; flake-utils.url = github:numtide/flake-utils; }; outputs = { self, nixpkgs, flake-utils }: with flake-utils.lib; eachSystem allSystems (system: let pkgs = import nixpkgs { inherit system; }; ringrtcPrebuild = builtins.fetchurl { url = "https://build-artifacts.signal.org/libraries/ringrtc-desktop-build-v2.33.0.tar.gz"; sha256 = "sha256:0zmgjax0ycjkvhqz1hybfi799lzss52s1cd8hzbqnm4ka3b1lhsf"; }; sqlcipher = builtins.fetchurl { url = "https://build-artifacts.signal.org/desktop/sqlcipher-4.5.5-fts5-fix--3.0.7--0.2.1-ef53ea45ed92b928ecfd33c552d8d405263e86e63dec38e1ec63e1b0193b630b.tar.gz"; sha256 = "sha256:02v37ccv1qb3xkhkiv1xws33w9h5skc55i9kzpn2ifcjxm2yllzg"; }; nodejs_18_15_0 = pkgs.nodejs.overrideAttrs (upstream: let # 18.15.0 matches the version in package.json version = "18.15.0"; sha256 = "sha256-jkTWUBj/lzKEGVwjGGRpoOpAgul+xCAOX1cG1VhNqjc="; in { inherit version; src = builtins.fetchurl { url = "https://nodejs.org/dist/v${version}/node-v${version}.tar.xz"; inherit sha256; }; }); yarn_18_15_0 = (pkgs.yarn.override { nodejs = nodejs_18_15_0; }).overrideAttrs (upstream: { # patches = (upstream.patches or []) ++ [ # ./yarn-allow-extraneous.patch # ]; # force yarn to never delete files; that way i can install the ringrtc prebuild w/o yarn deleting it. # postPatch = (upstream.postPatch or "") + '' # substituteInPlace lib/cli.js \ # --replace 'yield (_fs || _load_fs()).unlink' '// yield (_fs || _load_fs()).unlink' # ''; # preFixup = (upstream.preFixup or "") + '' # substituteInPlace $out/libexec/yarn/lib/cli.js --replace \ # "this.reporter.verbose(this.reporter.lang('verboseFileRemoveExtraneous', _loc6));" \ # "if (false)" # ''; }); electronDeps = with pkgs; [ # packages which electron dynamically links against alsa-lib atk cairo cups dbus expat glib gtk3 libdrm libxkbcommon mesa nss nspr pango xorg.libX11 xorg.libXfixes xorg.libXext xorg.libXcomposite xorg.libXdamage xorg.libXrandr xorg.libxcb systemd # fixes "Zygote could not fork: process_type gpu-process" when launching signal-desktop ]; _7zaDeps = with pkgs; [ libgcc.lib ]; fpmDeps = with pkgs; [ libxcrypt-legacy ]; patch-interpreter = with pkgs; writeShellScriptBin "patch-interpreter" '' patchelf --set-interpreter ${glibc}/lib/ld-linux-x86-64.so.2 $1 ''; patch-signal = with pkgs; writeShellScriptBin "patch-signal" '' patchelf --add-needed ${nss}/lib/libnss3.so $1 patchelf --add-needed ${nss}/lib/libnssutil3.so $1 patchelf --add-needed ${nss}/lib/libsmime3.so $1 patchelf --add-needed ${lib.getLib cups}/lib/libcups.so.2 $1 patchelf --add-needed ${cairo}/lib/libcairo.so.2 $1 patchelf --add-needed ${lib.getLib pango}/lib/libpango-1.0.so.0 $1 patchelf --add-needed ${at-spi2-core}/lib/libatspi.so.0 $1 patchelf --add-needed ${alsa-lib}/lib/libasound.so.2 $1 patchelf --add-needed ${atk}/lib/libatk-1.0.so.0 $1 patchelf --add-needed ${atk}/lib/libatk-bridge-2.0.so.0 $1 patchelf --add-needed ${lib.getLib glib}/lib/libgobject-2.0.so.0 $1 patchelf --add-needed ${lib.getLib glib}/lib/libglib-2.0.so.0 $1 patchelf --add-needed ${lib.getLib glib}/lib/libgio-2.0.so.0 $1 patchelf --add-needed ${gtk3}/lib/libgtk-3.so.0 $1 patchelf --add-needed ${libdrm}/lib/libdrm.so.2 $1 patchelf --add-needed ${nspr}/lib/libnspr4.so $1 patchelf --add-needed ${xorg.libXfixes}/lib/libXfixes.so.3 $1 patchelf --add-needed ${xorg.libXext}/lib/libXext.so.6 $1 patchelf --add-needed ${xorg.libXcomposite}/lib/libXcomposite.so.1 $1 patchelf --add-needed ${xorg.libXdamage}/lib/libXdamage.so.1 $1 patchelf --add-needed ${xorg.libXrandr}/lib/libXrandr.so.2 $1 patchelf --add-needed ${xorg.libxcb}/lib/libxcb.so.1 $1 patchelf --add-needed ${xorg.libX11}/lib/libX11.so.6 $1 patchelf --add-needed ${libxkbcommon}/lib/libxkbcommon.so.0 $1 patchelf --add-needed ${expat}/lib/libexpat.so.1 $1 patchelf --add-needed ${lib.getLib dbus}/lib/libdbus-1.so.3 $1 patchelf --add-needed ${lib.getLib mesa}/lib/libgbm.so.1 $1 ''; clean = with pkgs; writeShellScriptBin "clean" '' rm -rf \ cache-* \ node_modules \ preload.bundle.js \ release/ \ .eslintcache \ bundles \ ts/protobuf/compiled.d.ts \ ''; link-caches = with pkgs; writeShellScriptBin "link-caches" '' mkdir cache-yarn ; rm -rf ~/.cache/yarn ; ln -s $(pwd)/cache-yarn ~/.cache/yarn mkdir cache-node-gyp ; rm -rf ~/.cache/node-gyp ; ln -s $(pwd)/cache-node-gyp ~/.cache/node-gyp mkdir cache-electron ; rm -rf ~/.cache/electron ; ln -s $(pwd)/cache-electron ~/.cache/electron mkdir cache-ms-playwright ; rm -rf ~/.cache/ms-playwright ; ln -s $(pwd)/cache-ms-playwright ~/.cache/ms-playwright ''; # run this to clean state, and then build + run Signal in a way which i know WORKS. # you should land at the Signal pairing screen at the end of the command. reproducible0 = with pkgs; writeShellScriptBin "reproducible0" '' clean link-caches yarn install --frozen-lockfile yarn generate yarn build:esbuild:prod patch-interpreter node_modules/electron/dist/electron # yarn start ./node_modules/.bin/electron . # equiv to `yarn start` ''; reproducible1 = with pkgs; writeShellScriptBin "reproducible1" '' clean link-caches yarn install --frozen-lockfile yarn generate yarn build:esbuild:prod patch-interpreter node_modules/electron/dist/electron # this fails because it tries to also build the deb -- but we don't need that! yarn build:release || true patch-interpreter release/linux-unpacked/signal-desktop echo "launch signal with: ./release/linux-unpacked/signal-desktop" ''; reproducible2 = with pkgs; writeShellScriptBin "reproducible2" '' clean link-caches yarn install --frozen-lockfile yarn generate yarn build:esbuild:prod # this fails during the "fuse" process, which is ok to skip yarn build:release \ -c.electronDist=${electron}/libexec/electron \ -c.electronVersion=${electron.version} \ --dir \ || true patch-interpreter release/linux-unpacked/signal-desktop # nixpkgs electron doesn't seem to support zygote/GPU. # not electron (27); not electron_25 echo "launch signal with: ./release/linux-unpacked/signal-desktop --no-sandbox --no-zygote" ''; reproducible3 = with pkgs; writeShellScriptBin "reproducible3" '' clean link-caches yarn install --frozen-lockfile yarn generate yarn build:esbuild:prod # this fails during the "fuse" process, which is ok to skip yarn build:release \ -c.electronDist=${electron-bin}/libexec/electron \ -c.electronVersion=${electron-bin.version} \ --dir \ || true # patch-interpreter release/linux-unpacked/signal-desktop # electron-bin (26.3.0) DOES support default flags (i.e. zygote) # echo "launch signal with: ${electron-bin}/libexec/electron/electron ./release/linux-unpacked/resources/app.asar" echo "launch signal with: ${electron-bin}/bin/electron ./release/linux-unpacked/resources/app.asar" # same as libexec ''; reproducible4 = with pkgs; writeShellScriptBin "reproducible4" '' clean link-caches yarn install --frozen-lockfile # yarn generate --offline --frozen-lockfile # apparently this isn't equivalent to `yarn generate --offline --frozen-lockfile`! yarn build-module-protobuf --offline --frozen-lockfile yarn build:esbuild --offline --frozen-lockfile yarn sass yarn get-expire-time yarn copy-components yarn build:esbuild:prod --offline --frozen-lockfile # this fails during the "fuse" process, which is ok to skip yarn build:release \ -c.electronDist=${electron-bin}/libexec/electron \ -c.electronVersion=${electron-bin.version} \ --dir \ || true # electron-bin (26.3.0) DOES support default flags (i.e. zygote) # echo "launch signal with: ${electron-bin}/libexec/electron/electron ./release/linux-unpacked/resources/app.asar" echo "launch signal with: ${electron-bin}/bin/electron ./release/linux-unpacked/resources/app.asar" # same as libexec ''; reproducible5 = with pkgs; writeShellScriptBin "reproducible5" '' set -x clean link-caches # mkdir -p "$HOME/.node-gyp/${nodejs_18_15_0.version}" # echo 9 > "$HOME/.node-gyp/${nodejs_18_15_0.version}/installVersion" # ln -sfv "$(pwd)/include" "$HOME/.node-gyp/${nodejs_18_15_0.version}" # export npm_config_nodedir=${nodejs_18_15_0} yarn install --frozen-lockfile --ignore-scripts cp ${ringrtcPrebuild} node_modules/@signalapp/ringrtc/scripts/prebuild.tar.gz cp ${sqlcipher} node_modules/@signalapp/better-sqlite3/deps/sqlcipher.tar.gz # N.B.: without patched yarn, this deletes the vendored dependencies i just installed yarn install --frozen-lockfile # N.B.: `yarn install` ships node_modules/@signalapp/better-sqlite3/build/Release/better_sqlite3.node # also build/Release/obj.target/better_sqlite3.noe # also libcrypto.a, libsignal_tokenizer.a # - both of these for x64 and aarch64 # also sqlite3.a # remove build/Release to remove allof those prebuilts rm -rf node_modules/@signalapp/better-sqlite3/build/Release npm rebuild @signalapp/better-sqlite3 --offline # yarn generate --offline --frozen-lockfile # apparently this isn't equivalent to `yarn generate --offline --frozen-lockfile`! yarn build-module-protobuf --offline --frozen-lockfile yarn build:esbuild --offline --frozen-lockfile yarn sass yarn get-expire-time yarn copy-components yarn build:esbuild:prod --offline --frozen-lockfile # this fails during the "fuse" process, which is ok to skip yarn build:release \ -c.electronDist=${electron-bin}/libexec/electron \ -c.electronVersion=${electron-bin.version} \ --dir \ || true # patch-interpreter release/linux-unpacked/signal-desktop # electron-bin (26.3.0) DOES support default flags (i.e. zygote) # echo "launch signal with: ${electron-bin}/libexec/electron/electron ./release/linux-unpacked/resources/app.asar" echo "launch signal with: ${electron-bin}/bin/electron ./release/linux-unpacked/resources/app.asar" # same as libexec ''; reproducible6 = with pkgs; writeShellScriptBin "reproducible6" '' set -x clean link-caches yarn install --frozen-lockfile --ignore-scripts # these packages have build scripts: # - [x] node_modules/@signalapp/ringrtc/package.json # - 22: "install": "node scripts/fetch-prebuild.js", # - [x] node_modules/@signalapp/mock-server/node_modules/@signalapp/libsignal-client/package.json # - 19: "install": "node-gyp-build", # - [x] node_modules/@signalapp/better-sqlite3/package.json # - 37: "install": "npm run download && npm run build-release", # - [x] node_modules/@signalapp/libsignal-client/package.json # - 19: "install": "node-gyp-build", # # - [x] node_modules/bufferutil/package.json # - 10: "install": "node-gyp-build", # - [x] node_modules/mac-screen-capture-permissions/package.json # - 18: "install": "prebuild-install || node install.js" # - [x] node_modules/playwright/package.json # - 28: "install": "node install.js" # - [x] node_modules/utf-8-validate/package.json # - 10: "install": "node-gyp-build", # # several packages also have a postinstall in their package.json # - [x] node_modules/@babel/runtime-corejs3/node_modules/core-js-pure/package.json # - 55: "postinstall": "node -e \"try{require('./postinstall')}catch(e){}\"" # - [x] node_modules/@storybook/builder-manager/node_modules/esbuild/package.json # - 7: "postinstall": "node install.js" # - [x] node_modules/@storybook/core-common/node_modules/esbuild/package.json # - 7: "postinstall": "node install.js" # - [x] node_modules/@swc/core/package.json # - 51: "postinstall": "node postinstall.js", # - [x] node_modules/core-js-pure/package.json # - 71: "postinstall": "node -e \"try{require('./postinstall')}catch(e){}\"" # - [x] node_modules/core-js/package.json # - 41: "postinstall": "node scripts/postinstall || echo \"ignore\"" # - [x] node_modules/danger/node_modules/core-js/package.json # - 55: "postinstall": "node -e \"try{require('./postinstall')}catch(e){}\"" # - [x] node_modules/electron/package.json # - 8: "postinstall": "node install.js" # - [x] node_modules/esbuild/package.json # - 7: "postinstall": "node install.js" # - [x] node_modules/protobufjs/package.json # - 43: "postinstall": "node scripts/postinstall", # - [x] node_modules/websocket/node_modules/es5-ext/package.json # - 115: "postinstall": " node -e \"try{require('./_postinstall')}catch(e){}\" || exit 0", cp ${ringrtcPrebuild} node_modules/@signalapp/ringrtc/scripts/prebuild.tar.gz pushd node_modules/@signalapp/ringrtc/ tar -xzf ./scripts/prebuild.tar.gz popd cp ${sqlcipher} node_modules/@signalapp/better-sqlite3/deps/sqlcipher.tar.gz # pushd node_modules/@signalapp/libsignal-client # yarn node-gyp-build # popd # pushd node_modules/@signalapp/mock-server/node_modules/@signalapp/libsignal-client # yarn node-gyp-build # popd # pushd node_modules/bufferutil # yarn node-gyp-build # popd # pushd node_modules/bufferutil # yarn node-gyp-build # popd # pushd node_modules/mac-screen-capture-permissions # yarn prebuild-install || node install.js # popd # pushd node_modules/playwright # node install.js # popd # pushd node_modules/utf-8-validate # yarn node-gyp-build # popd # pushd node_modules/@babel/runtime-corejs3/node_modules/core-js-pure # node -e "try{require('./postinstall')}catch(e){}" # popd # pushd node_modules/@swc/core # node postinstall.js # popd # pushd node_modules/@storybook/builder-manager/node_modules/esbuild # node install.js # popd # pushd node_modules/@storybook/core-common/node_modules/esbuild # node install.js # popd # pushd node_modules/core-js-pure # node -e "try{require('./postinstall')}catch(e){}" # popd # pushd node_modules/core-js # node scripts/postinstall || echo "ignore" # popd # pushd node_modules/danger/node_modules/core-js # node -e "try{require('./postinstall')}catch(e){}" # popd # pushd node_modules/electron # node install.js # popd # pushd node_modules/esbuild # node install.js # popd # pushd node_modules/protobufjs # node scripts/postinstall # popd # pushd node_modules/websocket/node_modules/es5-ext # node -e "try{require('./_postinstall')}catch(e){}" # popd # run signal's own `postinstall`: yarn build:acknowledgments yarn patch-package # yarn electron:install-app-deps # N.B.: `yarn install` ships node_modules/@signalapp/better-sqlite3/build/Release/better_sqlite3.node # specifically, better-sqlite3's package.json install script does that # also build/Release/obj.target/better_sqlite3.node # also libcrypto.a, libsignal_tokenizer.a # - both of these for x64 and aarch64 # also sqlite3.a # remove build/Release to remove all of those prebuilts # rm -rf node_modules/@signalapp/better-sqlite3/build/Release # npm rebuild @signalapp/better-sqlite3 --offline # yarn generate --offline --frozen-lockfile # apparently this isn't equivalent to `yarn generate --offline --frozen-lockfile`! yarn build-module-protobuf --offline --frozen-lockfile yarn build:esbuild --offline --frozen-lockfile yarn sass yarn get-expire-time yarn copy-components yarn build:esbuild:prod --offline --frozen-lockfile # this fails during the "fuse" process, which is ok to skip yarn build:release \ -c.electronDist=${electron-bin}/libexec/electron \ -c.electronVersion=${electron-bin.version} \ --dir \ || true # patch-interpreter release/linux-unpacked/signal-desktop # electron-bin (26.3.0) DOES support default flags (i.e. zygote) # echo "launch signal with: ${electron-bin}/libexec/electron/electron ./release/linux-unpacked/resources/app.asar" echo "launch signal with: ${electron-bin}/bin/electron ./release/linux-unpacked/resources/app.asar" # same as libexec ''; reproducible7 = with pkgs; writeShellScriptBin "reproducible7" '' set -x clean link-caches # prevent node-gyp from trying to download nodejs headers # mkdir -p "$HOME/.node-gyp/${nodejs_18_15_0.version}" # echo 9 > "$HOME/.node-gyp/${nodejs_18_15_0.version}/installVersion" # ln -sfv "$(pwd)/include" "$HOME/.node-gyp/${nodejs_18_15_0.version}" # export npm_config_nodedir=${nodejs_18_15_0} # export npm_config_nodedir=${nodejs_18_15_0} tar xzf ${electron-bin.headers} export npm_config_nodedir=$(pwd)/node_headers yarn install --frozen-lockfile --ignore-scripts cp ${ringrtcPrebuild} node_modules/@signalapp/ringrtc/scripts/prebuild.tar.gz pushd node_modules/@signalapp/ringrtc/ tar -xzf ./scripts/prebuild.tar.gz popd cp ${sqlcipher} node_modules/@signalapp/better-sqlite3/deps/sqlcipher.tar.gz pushd node_modules/@signalapp/better-sqlite3 yarn --offline build-release popd # run signal's own `postinstall`: yarn build:acknowledgments yarn patch-package # yarn electron:install-app-deps # yarn generate --offline --frozen-lockfile # apparently this isn't equivalent to `yarn generate --offline --frozen-lockfile`! yarn build-module-protobuf --offline --frozen-lockfile yarn build:esbuild --offline --frozen-lockfile yarn sass yarn get-expire-time yarn copy-components yarn build:esbuild:prod --offline --frozen-lockfile # this fails during the "fuse" process, which is ok to skip yarn build:release \ -c.electronDist=${electron-bin}/libexec/electron \ -c.electronVersion=${electron-bin.version} \ --dir \ || true # patch-interpreter release/linux-unpacked/signal-desktop # electron-bin (26.3.0) DOES support default flags (i.e. zygote) echo "launch signal with: ${electron-bin}/bin/electron ./release/linux-unpacked/resources/app.asar" ''; LD_LIBRARY_PATH = builtins.concatStringsSep ":" (builtins.map (pkg: "${pkgs.lib.getLib pkg}/lib") (electronDeps ++ _7zaDeps ++ fpmDeps) ); in rec { devShells.default = with pkgs; mkShell { env = { inherit LD_LIBRARY_PATH; }; buildInputs = [ clean link-caches patch-interpreter patch-signal reproducible0 reproducible1 reproducible2 reproducible3 reproducible4 reproducible5 reproducible6 reproducible7 # yarn # nodejs # nodejs 18.18.2 causes signal to hang on launch. # 18.15.0 (matching package.json) works! yarn_18_15_0 nodejs_18_15_0 # needed for `yarn install` bettersqlite step # electron # ruby # needed by fpm (?) # this seems to all not be needed, thanks to LD_LIBRARY_PATH above # alsa-lib # necessary? # at-spi2-atk # at-spi2-core # atk # cups # # electron # flac # gdk-pixbuf # gtk3 # libpulseaudio # libwebp # libxslt # mesa # for libgbm # nspr # nss # pango ]; }; packages.yarn_18_15_0 = yarn_18_15_0; packages.sqlcipher = sqlcipher; packages.ringrtcPrebuild = ringrtcPrebuild; packages.signal-desktop-from-src = with pkgs; stdenv.mkDerivation { pname = "signal-desktop-from-src"; version = "6.36.0"; src = ./.; env = { inherit LD_LIBRARY_PATH; yarnOfflineCache = fetchYarnDeps { # this might be IFD: if `nix run '.#check.nur'` fails then inline the lock: `yarnLock = ./yarn.lock` yarnLock = ./yarn.lock; hash = "sha256-AXT6p5lgF0M9ckoxiAvT1HaJhUWVtwEOadY4otdeB0Q="; }; # ELECTRON_SKIP_BINARY_DOWNLOAD = "1"; }; nativeBuildInputs = with pkgs; [ fixup_yarn_lock makeWrapper nodejs_18_15_0 # needed for `yarn install` bettersqlite step python3 yarn_18_15_0 ]; configurePhase = '' runHook preConfigure set -x export HOME=$NIX_BUILD_TOP yarn config --offline set yarn-offline-mirror $yarnOfflineCache fixup_yarn_lock yarn.lock # prevent node-gyp from trying to download nodejs headers # THIS BREAKS better-sqlite ABI # mkdir -p "$HOME/.node-gyp/${nodejs_18_15_0.version}" # echo 9 > "$HOME/.node-gyp/${nodejs_18_15_0.version}/installVersion" # ln -sfv "$(pwd)/include" "$HOME/.node-gyp/${nodejs_18_15_0.version}" # export npm_config_nodedir=${nodejs_18_15_0} tar xzf ${electron-bin.headers} export npm_config_nodedir=$(pwd)/node_headers # optional flags: --no-progress --non-interactive # yarn install creates the node_modules/ directory yarn install --offline --frozen-lockfile --ignore-scripts patchShebangs node_modules/ # manually emulate install scripts for key dependencies cp ${ringrtcPrebuild} node_modules/@signalapp/ringrtc/scripts/prebuild.tar.gz pushd node_modules/@signalapp/ringrtc/ tar -xzf ./scripts/prebuild.tar.gz popd cp ${sqlcipher} node_modules/@signalapp/better-sqlite3/deps/sqlcipher.tar.gz pushd node_modules/@signalapp/better-sqlite3 yarn --offline build-release popd pushd node_modules/@signalapp/libsignal-client yarn node-gyp-build popd pushd node_modules/@signalapp/mock-server/node_modules/@signalapp/libsignal-client yarn node-gyp-build popd pushd node_modules/bufferutil yarn node-gyp-build popd pushd node_modules/bufferutil yarn node-gyp-build popd # pushd node_modules/mac-screen-capture-permissions # yarn prebuild-install || node install.js # popd # pushd node_modules/playwright # node install.js # popd pushd node_modules/utf-8-validate yarn node-gyp-build popd pushd node_modules/@babel/runtime-corejs3/node_modules/core-js-pure node -e "try{require('./postinstall')}catch(e){}" popd pushd node_modules/@swc/core node postinstall.js popd pushd node_modules/@storybook/builder-manager/node_modules/esbuild node install.js popd pushd node_modules/@storybook/core-common/node_modules/esbuild node install.js popd pushd node_modules/core-js-pure node -e "try{require('./postinstall')}catch(e){}" popd pushd node_modules/core-js node scripts/postinstall || echo "ignore" popd pushd node_modules/danger/node_modules/core-js node -e "try{require('./postinstall')}catch(e){}" popd # pushd node_modules/electron # node install.js # popd pushd node_modules/esbuild node install.js popd pushd node_modules/protobufjs node scripts/postinstall popd pushd node_modules/websocket/node_modules/es5-ext node -e "try{require('./_postinstall')}catch(e){}" popd # run signal's own `postinstall`: yarn build:acknowledgments yarn patch-package yarn electron:install-app-deps runHook postConfigure ''; buildPhase = '' runHook preBuild set -x # rebuild better-sqlite to avoid using prebuilts # - experiment to fix `_ZN2v812api_internal18GlobalizeReferenceEPNS_8internal7IsolateEPm` undefined symbol (doesn't fix) # rm -rf node_modules/@signalapp/better-sqlite3/build/Release # npm rebuild @signalapp/better-sqlite3 --offline # yarn generate yarn build-module-protobuf --offline --frozen-lockfile yarn build:esbuild --offline --frozen-lockfile yarn sass yarn get-expire-time yarn copy-components yarn build:esbuild:prod --offline --frozen-lockfile # this fails during the "fuse" process, which is ok to skip yarn build:release \ -c.electronDist=${electron-bin}/libexec/electron \ -c.electronVersion=${electron-bin.version} \ --dir \ || true runHook postBuild ''; installPhase = '' runHook preInstall # cp -R ./release $out # directory structure follows the original `signal-desktop` nix package mkdir -p $out/lib/Signal cp -R release/linux-unpacked/* $out/lib/Signal mkdir $out/bin makeWrapper ${electron-bin}/bin/electron $out/bin/signal-desktop \ --add-flags $out/lib/Signal/resources/app.asar \ --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations}}" \ --inherit-argv0 runHook postInstall ''; }; defaultPackage = packages.signal-desktop-from-src; } ) ; }