Skip to content

Commit fbca2a8

Browse files
authored
Merge pull request #2998 from input-output-hk/chore/line-up-nodejs-to-electrons-14.16.0
[DDW-1109] Allow specifying Node.js version; patch `electron-rebuild` forcing proper Electron-Node.js headers; fix M1 CI
2 parents bda926e + 558ece9 commit fbca2a8

File tree

8 files changed

+124
-42
lines changed

8 files changed

+124
-42
lines changed

default.nix

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,20 @@ let
7272
cardanoLib = localLib.iohkNix.cardanoLib;
7373
daedalus-bridge = self.bridgeTable.${nodeImplementation};
7474

75-
nodejs = pkgs.nodejs-16_x;
75+
nodejs = let
76+
njPath = pkgs.path + "/pkgs/development/web/nodejs";
77+
buildNodeJs = pkgs.callPackage (import (njPath + "/nodejs.nix")) {
78+
python = pkgs.python3;
79+
icu = pkgs.icu68; # can’t build against ICU 69: <https://chromium-review.googlesource.com/c/v8/v8/+/2477751>
80+
};
81+
in
82+
buildNodeJs {
83+
enableNpm = true;
84+
version = "14.17.0";
85+
sha256 = "1vf989canwcx0wdpngvkbz2x232yccp7fzs1vcbr60rijgzmpq2n";
86+
patches = pkgs.lib.optional pkgs.stdenv.isDarwin (njPath + "/bypass-xcodebuild.diff");
87+
};
88+
7689
nodePackages = pkgs.nodePackages.override { nodejs = self.nodejs; };
7790
yarnInfo = {
7891
version = "1.22.4";

installers/nix/electron.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{ stdenv, lib, makeWrapper, fetchurl, unzip, atomEnv, libuuid, at-spi2-atk, at_spi2_core, libxshmfence,
2-
libxkbcommon }:
2+
libxkbcommon, runCommand, binutils-unwrapped }:
33

44
let
5-
version = "13.6.3";
5+
version = (builtins.fromJSON (builtins.readFile ../../package.json)).dependencies.electron;
66
name = "electron-${version}";
77

88
throwSystem = throw "Unsupported system: ${stdenv.hostPlatform.system}";

nix/yarn-nix-shell.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,9 @@ if [ -z "$command" ] ; then
2929
fi
3030

3131
export NETWORK
32+
33+
# Prevent segfaults on Darwin in `GC_*` code:
34+
export GC_DONT_GC=1
35+
3236
# `return` will make the user stay in `nix-shell` after the initial command finishes:
3337
exec nix-shell --argstr nodeImplementation cardano --argstr cluster "$cluster" --command "$command ; return"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"build:main": "yarn webpack -c source/main/webpack.config.js --progress",
1414
"build:renderer": "yarn webpack -c source/renderer/webpack.config.js --progress",
1515
"build:cleanup": "rimraf ./dist",
16-
"build:electron": "electron-rebuild -w usb --useCache -s --debug",
16+
"build:electron": "electron-rebuild --useCache && electron-rebuild -w usb --useCache -s --debug",
1717
"check:all": "yarn prettier:check && yarn lint && yarn compile && yarn stylelint && yarn lockfile:check && yarn i18n:manage && yarn storybook:build",
1818
"start": "yarn electron ./",
1919
"start:dev": "nodemon --watch 'dist/main' --exec 'NODE_ENV=development yarn start'",

release.nix

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@ in {
6969
in {
7070
daedalus-installer = allArchesNoWindows;
7171
yaml2json = allArchesNoWindows;
72+
nodejs = allArchesNoWindows;
7273
bridgeTable = {
7374
cardano = allArches;
7475
};
7576
cardano-node = allArches;
76-
}))
77+
})) // {
78+
recurseForDerivations = {};
79+
}

scripts/postinstall.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@
22

33
if [[ "$CI" != "true" ]]; then
44
yarn lockfile:fix
5+
6+
# Let’s patch electron-rebuild to force correct Node.js headers to
7+
# build native modules against even in `nix-shell`, otherwise, it
8+
# doesn’t work reliably.
9+
eval "$(nix-build -A rawapp.patchElectronRebuild)"
510
fi

shell.nix

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,6 @@ let
111111
ln -svf $(type -P cardano-node)
112112
ln -svf $(type -P cardano-wallet)
113113
ln -svf $(type -P cardano-cli)
114-
mkdir -p ${BUILDTYPE}/
115-
${let
116-
# (TODO: investigate why – @michalrus)
117-
sourceBUILDTYPE = "Release";
118-
in ''
119-
ln -svf $PWD/node_modules/usb/build/${sourceBUILDTYPE}/usb_bindings.node ${BUILDTYPE}/
120-
ln -svf $PWD/node_modules/node-hid/build/${sourceBUILDTYPE}/HID.node ${BUILDTYPE}/
121-
ln -svf $PWD/node_modules/node-hid/build/${sourceBUILDTYPE}/HID_hidraw.node ${BUILDTYPE}/
122-
ln -svf $PWD/node_modules/usb-detection/build/${sourceBUILDTYPE}/detection.node ${BUILDTYPE}/
123-
''}
124114
125115
${pkgs.lib.optionalString (nodeImplementation == "cardano") ''
126116
source <(cardano-node --bash-completion-script `type -p cardano-node`)
@@ -135,14 +125,51 @@ let
135125
''
136126
}
137127
yarn install --frozen-lockfile
128+
129+
# Rebuild native modules for <https://www.electronjs.org/docs/latest/tutorial/using-native-node-modules>:
130+
find Debug/ Release/ -name '*.node' | xargs rm -v || true
138131
yarn build:electron
132+
133+
${let
134+
# Several native modules have to be linked in ${BUILDTYPE}/ in
135+
# root directory, for `yarn dev` to work correctly. If a Debug
136+
# version of such extension exists, we use it, otherwise, we
137+
# use Release:
138+
tryLink = dependency: fileName: ''
139+
symlinkTarget=$(ls 2>/dev/null -d \
140+
"$PWD/node_modules/${dependency}/build/Debug/${fileName}" \
141+
"$PWD/node_modules/${dependency}/build/Release/${fileName}" \
142+
| head -1
143+
)
144+
145+
if [ -z "$symlinkTarget" ] ; then
146+
echo >&2 "error: symlink target not found: ‘${fileName}’ in ‘${dependency}’"
147+
# ~exit 1~ — do not exit, let the person fix from inside `nix-shell`
148+
fi
149+
150+
${localLib.optionalString pkgs.stdenv.isLinux ''
151+
${pkgs.patchelf}/bin/patchelf --set-rpath ${pkgs.lib.makeLibraryPath [
152+
pkgs.stdenv.cc.cc pkgs.udev
153+
]} "$symlinkTarget"
154+
''}
155+
156+
mkdir -p ${BUILDTYPE}/
157+
ln -svf "$symlinkTarget" ${BUILDTYPE}/
158+
unset symlinkTarget
159+
'';
160+
in ''
161+
${tryLink "usb" "usb_bindings.node"}
162+
${tryLink "usb-detection" "detection.node"}
163+
${tryLink "node-hid" "HID.node"}
164+
${localLib.optionalString pkgs.stdenv.isLinux ''
165+
${tryLink "node-hid" "HID_hidraw.node"}
166+
''}
167+
''}
168+
139169
${localLib.optionalString pkgs.stdenv.isLinux ''
140-
${pkgs.patchelf}/bin/patchelf --set-rpath ${pkgs.lib.makeLibraryPath [ pkgs.stdenv.cc.cc pkgs.udev ]} ${BUILDTYPE}/usb_bindings.node
141-
${pkgs.patchelf}/bin/patchelf --set-rpath ${pkgs.lib.makeLibraryPath [ pkgs.stdenv.cc.cc pkgs.udev ]} ${BUILDTYPE}/HID.node
142-
# TODO: is this needed for `detection.node`?
143-
${pkgs.patchelf}/bin/patchelf --set-rpath ${pkgs.lib.makeLibraryPath [ pkgs.stdenv.cc.cc pkgs.udev ]} ${BUILDTYPE}/detection.node
144170
ln -svf ${daedalusPkgs.electron}/bin/electron ./node_modules/electron/dist/electron
145171
''}
172+
146173
echo 'jq < $LAUNCHER_CONFIG'
147174
echo debug the node by running debug-node
148175
'';

yarn2nix.nix

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
, lz4
1111
, pkgconfig
1212
, systemd
13-
, writeShellScriptBin
13+
, writeShellScript
1414
, xz
1515
, nodePackages
1616
, zlib
@@ -35,24 +35,29 @@ let
3535
main = "main/index.js";
3636
};
3737
newPackagePath = builtins.toFile "package.json" (builtins.toJSON newPackage);
38-
windowsElectronVersion = "13.6.3";
39-
electronPath = "https://github.com/electron/electron/releases/download/v${windowsElectronVersion}";
38+
electronVersion = origPackage.dependencies.electron;
39+
electronPath = "https://github.com/electron/electron/releases/download/v${electronVersion}";
4040
windowsElectron = fetchurl {
41-
url = "${electronPath}/electron-v${windowsElectronVersion}-win32-x64.zip";
41+
url = "${electronPath}/electron-v${electronVersion}-win32-x64.zip";
4242
sha256 = "18085a2509447fef8896daeee96a12f48f8e60a4d5ec4cfab44d8d59b9d89a72";
4343
};
4444
electronPathHash = builtins.hashString "sha256" electronPath;
4545
electron-cache = runCommand "electron-cache" {} ''
4646
# newer style
4747
mkdir -p $out/${electronPathHash}/
48-
ln -sv ${windowsElectron} $out/${electronPathHash}/electron-v${windowsElectronVersion}-win32-x64.zip
49-
mkdir $out/httpsgithub.comelectronelectronreleasesdownloadv${windowsElectronVersion}electron-v${windowsElectronVersion}-win32-x64.zip
50-
ln -s ${windowsElectron} $out/httpsgithub.comelectronelectronreleasesdownloadv${windowsElectronVersion}electron-v${windowsElectronVersion}-win32-x64.zip/electron-v${windowsElectronVersion}-win32-x64.zip
48+
ln -sv ${windowsElectron} $out/${electronPathHash}/electron-v${electronVersion}-win32-x64.zip
49+
mkdir $out/httpsgithub.comelectronelectronreleasesdownloadv${electronVersion}electron-v${electronVersion}-win32-x64.zip
50+
ln -s ${windowsElectron} $out/httpsgithub.comelectronelectronreleasesdownloadv${electronVersion}electron-v${electronVersion}-win32-x64.zip/electron-v${electronVersion}-win32-x64.zip
5151
'';
52-
electron-gyp = fetchurl {
53-
url = "https://www.electronjs.org/headers/v${windowsElectronVersion}/node-v${windowsElectronVersion}-headers.tar.gz";
52+
electron-node-headers = fetchurl {
53+
url = "https://www.electronjs.org/headers/v${electronVersion}/node-v${electronVersion}-headers.tar.gz";
5454
sha256 = "f8567511857ab62659505ba5158b6ad69afceb512105a3251d180fe47f44366c";
5555
};
56+
electron-node-headers-unpacked = runCommand "electron-node-headers-${electronVersion}-unpacked" {} ''
57+
tar -xf ${electron-node-headers}
58+
mkdir -p $out
59+
mv node_headers/* $out/
60+
'';
5661
filter = name: type: let
5762
baseName = baseNameOf (toString name);
5863
sansPrefix = lib.removePrefix (toString ./.) name;
@@ -74,6 +79,38 @@ let
7479
pkgconfig
7580
libusb
7681
];
82+
83+
# We patch `node_modules/electron-rebuild` to force specific Node.js
84+
# headers to be used when building native extensions for
85+
# Electron. Electron’s Node.js ABI differs from the same version of
86+
# Node.js, because different libraries are used in Electon,
87+
# e.g. BoringSSL instead of OpenSSL,
88+
# cf. <https://www.electronjs.org/docs/latest/tutorial/using-native-node-modules>
89+
#
90+
# We also use this same code in `shell.nix`, since for some reason
91+
# `electron-rebuild` there determines incorrect headers to use
92+
# automatically, and we keep getting ABI errors. TODO: investigate
93+
# why…
94+
#
95+
# TODO: That `sed` is rather awful… Can it be done better? – @michalrus
96+
patchElectronRebuild = writeShellScript "patch-electron-rebuild" ''
97+
echo 'Patching electron-rebuild to force our Node.js headers…'
98+
99+
nodeGypJs=lib/src/module-type/node-gyp.js
100+
if [ ! -e $nodeGypJs ] ; then
101+
# makes it work both here, and in shell.nix:
102+
nodeGypJs="node_modules/electron-rebuild/$nodeGypJs"
103+
fi
104+
if [ ! -e $nodeGypJs ] ; then
105+
echo >&2 'fatal: shouldn’t happen unless electron-rebuild changes'
106+
exit 1
107+
fi
108+
109+
# Patch idempotently (matters in repetitive shell.nix):
110+
if ! grep -qF ${electron-node-headers} $nodeGypJs ; then
111+
sed -r 's|const extraNodeGypArgs.*|\0 extraNodeGypArgs.push("--tarball", "${electron-node-headers}", "--nodedir", "${electron-node-headers-unpacked}");|' -i $nodeGypJs
112+
fi
113+
'';
77114
in
78115
yarn2nix.mkYarnPackage {
79116
name = "daedalus-js";
@@ -141,12 +178,6 @@ yarn2nix.mkYarnPackage {
141178
export HOME=$(realpath home)
142179
yarn --offline run build
143180
144-
mkdir -pv $HOME/.electron-gyp/
145-
tar -xvf ${electron-gyp} -C $HOME/.electron-gyp
146-
mv -vi $HOME/.electron-gyp/node_headers $HOME/.electron-gyp/${windowsElectronVersion}/
147-
148-
ln -sv $HOME/.electron-gyp $HOME/.node-gyp
149-
150181
#export DEBUG=electron-rebuild
151182
152183
ls -ltrha $NIX_BUILD_TOP/daedalus/node_modules/
@@ -206,25 +237,24 @@ yarn2nix.mkYarnPackage {
206237
# libunistring
207238
# libusb1
208239
#] ++ stdenv.cc.libc.buildInputs;
240+
241+
# `yarnPreBuild` is only used in `yarn2nix.mkYarnModules`, not `yarn2nix.mkYarnPackage`:
209242
yarnPreBuild = ''
210243
mkdir -p $HOME/.node-gyp/${nodejs.version}
211244
echo 9 > $HOME/.node-gyp/${nodejs.version}/installVersion
212245
ln -sfv ${nodejs}/include $HOME/.node-gyp/${nodejs.version}
213246
'';
247+
248+
inherit patchElectronRebuild; # for use in shell.nix
249+
214250
pkgConfig = {
215251
electron-rebuild = {
216-
# TODO: That is rather awful… Can it be done better? – @michalrus
217252
postInstall = ''
218-
nodeGypJs=lib/src/module-type/node-gyp.js
219-
if [ ! -e $nodeGypJs ] ; then
220-
echo >&2 'shouldn’t happen unless electron-rebuild changes'
221-
exit 1
222-
fi
223-
224-
sed -r 's|const extraNodeGypArgs.*|\0 extraNodeGypArgs.push("--tarball", "${electron-gyp}", "--nodedir", process.env["HOME"] + "/.node-gyp/${windowsElectronVersion}");|' -i $nodeGypJs
253+
${patchElectronRebuild}
225254
'';
226255
};
227256
};
257+
228258
# work around some purity problems in nix
229259
yarnLock = ./yarn.lock;
230260
packageJSON = ./package.json;

0 commit comments

Comments
 (0)