1010 inherit ( pkgs ) lib ;
1111
1212 inherit ( common )
13- daedalus-bridge daedalus-installer launcherConfigs mock-token-metadata-server
13+ launcherConfigs mock-token-metadata-server
1414 cardanoNodeVersion cardanoWalletVersion ;
1515
1616 inherit ( common ) originalPackageJson electronVersion electronChromedriverVersion commonSources ;
@@ -107,19 +107,100 @@ in rec {
107107
108108 darwin-launcher = pkgs . callPackage ./darwin-launcher.nix { } ;
109109
110+ # TODO: don’t use cardano-bridge.nix
111+
112+ # TODO: compare runtime-nodejs-deps.json with Linux and Windows, and re-use it there
113+
114+ # TODO: remove MacInstaller.hs
115+
116+ nix-bundle-exe-same-dir = pkgs . runCommand "nix-bundle-exe-same-dir" { } ''
117+ cp -R ${ inputs . nix-bundle-exe } $out
118+ chmod -R +w $out
119+ sed -r 's+@executable_path/\$relative_bin_to_lib/\$lib_dir+@executable_path+g' -i $out/bundle-macos.sh
120+ '' ;
121+
122+ mkBundle = exes : let
123+ unbundled = pkgs . linkFarm "exes" ( lib . mapAttrsToList ( name : path : {
124+ name = "bin/" + name ;
125+ inherit path ;
126+ } ) exes ) ;
127+ in ( import nix-bundle-exe-same-dir {
128+ inherit pkgs ;
129+ bin_dir = "bundle" ;
130+ exe_dir = "_unused_" ;
131+ lib_dir = "bundle" ;
132+ } unbundled ) . overrideAttrs ( drv : {
133+ buildCommand = (
134+ builtins . replaceStrings
135+ [ "'${ unbundled } /bin'" ]
136+ [ "'${ unbundled } /bin' -follow" ]
137+ drv . buildCommand
138+ ) + ''
139+ mv $out/bundle/* $out/
140+ rmdir $out/bundle
141+ '' ;
142+ } ) ;
143+
144+ # XXX: cardano-launcher cannot be a symlink, because it looks at its own
145+ # `realpath` to determine DAEDALUS_INSTALL_DIRECTORY:
146+ bundle-cardano-launcher = ( mkBundle {
147+ "cardano-launcher" = common . cardano-shell . haskellPackages . cardano-launcher . components . exes . cardano-launcher + "/bin/cardano-launcher" ;
148+ } ) . overrideAttrs ( drv : {
149+ buildCommand = let exeName = "cardano-launcher" ; in drv . buildCommand + ''
150+ (
151+ cd $out
152+ mkdir -p bundle-${ exeName }
153+ mv *.dylib bundle-${ exeName } /
154+ otool -L ${ exeName } \
155+ | grep -E '^\s*@executable_path' \
156+ | sed -r 's/^\s*//g ; s/ \(.*//g' \
157+ | while IFS= read -r lib ; do
158+ install_name_tool -change "$lib" "$(sed <<<"$lib" -r 's,@executable_path/,@executable_path/bundle-${ exeName } /,g')" ${ exeName }
159+ done
160+ )
161+ '' ;
162+ } ) ;
163+
164+ bundle-cardano-node = mkBundle { "cardano-node" = lib . getExe common . cardano-node ; } ;
165+ bundle-cardano-cli = mkBundle { "cardano-cli" = lib . getExe common . cardano-cli ; } ;
166+ bundle-cardano-address = mkBundle { "cardano-address" = lib . getExe common . cardano-address ; } ;
167+ bundle-cardano-wallet = pkgs . runCommandNoCC "bundle-cardano-wallet" { } ''cp -r ${ common . cardano-wallet } /bin $out'' ; # upstream bundles it
168+ bundle-mock-token-metadata-server = mkBundle { "mock-token-metadata-server" = lib . getExe common . mock-token-metadata-server ; } ;
169+ bundle-local-cluster = mkBundle { "local-cluster" = lib . getExe common . walletPackages . local-cluster ; } ;
170+
171+ # HID.node and others depend on `/nix/store`, we have to bundle them, too:
172+ bundleNodeJsNativeModule = pkgs . writeShellScript "bundleNodeJsNativeModule" ''
173+ #!/usr/bin/env bash
174+ set -euo pipefail
175+ target="$1"
176+ export bin_dir="bundle"
177+ export exe_dir="_unused_"
178+ export lib_dir="bundle"
179+ export PATH=${ lib . makeBinPath ( with pkgs ; [ darwin . cctools darwin . binutils darwin . sigtool nukeReferences ] ) } :"$PATH"
180+ tmpdir=$(mktemp -d)
181+ cp ${ nix-bundle-exe-same-dir } /bundle-macos.sh "$tmpdir"/
182+ chmod -R +w "$tmpdir"
183+ sed -r 's/@executable_path/@loader_path/g' -i "$tmpdir"/bundle-macos.sh
184+ bash "$tmpdir"/bundle-macos.sh "$tmpdir" "$target"
185+ rm "$tmpdir"/bundle-macos.sh
186+ mv "$tmpdir/bundle" "$(dirname "$target")/bundle-$(basename "$target")"
187+ rmdir "$tmpdir"
188+ rm "$target"
189+ ln -s "bundle-$(basename "$target")/$(basename "$target")" "$target"
190+ '' ;
191+
110192 package = genClusters ( cluster : let
111193 pname = "daedalus" ;
112194 in pkgs . stdenv . mkDerivation {
113195 name = pname ;
114196 src = srcWithoutNix ;
115- nativeBuildInputs = [ yarn nodejs daedalus-installer ]
116- ++ ( with pkgs ; [ python3 perl pkgconfig darwin . cctools xcbuild ] ) ;
197+ nativeBuildInputs = [ yarn nodejs ]
198+ ++ ( with pkgs ; [ python3 perl pkgconfig darwin . cctools xcbuild jq ] ) ;
117199 buildInputs = ( with pkgs . darwin ; [
118200 apple_sdk . frameworks . CoreServices
119201 apple_sdk . frameworks . AppKit
120202 libobjc
121203 ] ) ++ [
122- daedalus-bridge . ${ cluster }
123204 darwin-launcher
124205 mock-token-metadata-server
125206 ] ;
@@ -141,21 +222,103 @@ in rec {
141222
142223 ${ common . temporaryNodeModulesPatches }
143224
144- export DEVX_FIXME_DONT_YARN_INSTALL=1
145225 (
146226 cd installers/
147227 cp -r ${ launcherConfigs . ${ cluster } . configFiles } /. ./.
148228
149- # make-installer needs to see `bin/nix-store` to break all references to dylibs inside /nix/store:
150- export PATH="${ lib . makeBinPath [ pkgs . nixUnstable ] } :$PATH"
229+ echo "Creating icons ..."
230+ /usr/bin/iconutil --convert icns --output icons/electron.icns "icons/${ cluster } .iconset"
231+ )
232+
233+ mkdir -p release
234+ echo "Installing nodejs dependencies..."
235+ echo "Running electron packager script..."
236+ export "NODE_ENV" "production"
237+ yarn build:electron
238+ yarn run package -- --name ${ lib . escapeShellArg common . launcherConfigs . ${ cluster } . installerConfig . spacedName }
239+ echo "Size of Electron app is $(du -sh release)"
240+ find -name '*.node'
241+
242+ pathtoapp=release/darwin-${ archSuffix } /${ lib . escapeShellArg launcherConfigs . ${ cluster } . installerConfig . spacedName } -darwin-${ archSuffix } /${ lib . escapeShellArg launcherConfigs . ${ cluster } . installerConfig . spacedName } .app
243+ mkdir -p "$pathtoapp"/Contents/Resources/app/node_modules
244+ jq -r '.[]' ${ ./runtime-nodejs-deps.json } | sed -r 's,^,node_modules/,' | xargs -d '\n' cp -r -t "$pathtoapp"/Contents/Resources/app/node_modules/
245+
246+ mkdir -p "$pathtoapp"/Contents/Resources/app/build
247+
248+ for f in \
249+ "usb/build/Release/usb_bindings.node" \
250+ "node-hid/build/Release/HID.node" \
251+ "usb-detection/build/Release/detection.node" \
252+ ; do
253+ cp node_modules/"$f" "$pathtoapp"/Contents/Resources/app/build/
254+ done
255+
256+ jq --arg name "xxx" '.productName = $name' "$pathtoapp/Contents/Resources/app/package.json" >tmp-package.json
257+ mv tmp-package.json "$pathtoapp/Contents/Resources/app/package.json"
258+
259+ dir="$pathtoapp/Contents/MacOS"
260+ dataDir="$pathtoapp/Contents/Resources"
261+
262+ mkdir -p "$dir" "$dataDir"
263+
264+ echo "Preparing files ..."
265+ cp installers/launcher-config.yaml "$dataDir"/
266+
267+ cp -r ${ bundle-cardano-launcher } /. "$dir"/
268+
269+ ${ lib . concatStringsSep "\n " ( lib . mapAttrsToList ( exe : bundle : ''
270+ cp -r ${ bundle } "$dir"/bundle-${ exe }
271+ ln -s bundle-${ exe } /${ exe } "$dir"/${ exe }
272+ '' ) ( {
273+ "cardano-node" = bundle-cardano-node ;
274+ "cardano-cli" = bundle-cardano-cli ;
275+ "cardano-address" = bundle-cardano-address ;
276+ "cardano-wallet" = bundle-cardano-wallet ;
277+ } // ( lib . optionalAttrs ( cluster == "selfnode" ) {
278+ "mock-token-metadata-server" = bundle-mock-token-metadata-server ;
279+ "local-cluster" = bundle-local-cluster ;
280+ } ) ) ) }
281+
282+ cp installers/{config.yaml,genesis.json,topology.yaml} "$dataDir"/
283+ ${ if ( cluster != "selfnode" ) then ''
284+ cp installers/{genesis-byron.json,genesis-shelley.json,genesis-alonzo.json} "$dataDir"/
285+ cp installers/genesis-conway.json "$dataDir"/ || true
286+ '' else ''
287+ cp installers/{signing.key,delegation.cert} "$dataDir"/
288+ cp -f ${ ./../../utils/cardano/selfnode } /token-metadata.json "$dir"/
289+ '' }
290+
291+ chmod -R +w "$dir"
292+ rm -r "$dataDir/app/installers"
293+
294+ for f in "usb_bindings.node" "detection.node" "HID.node" ; do
295+ (
296+ cd "$dataDir"/app/build/
297+ mv "$f" ../../../MacOS/"$f"
298+ # TODO: why is/was this "reverse" symlink needed? does it make sense?
299+ ln -s ../../../MacOS/"$f" ./
300+ )
301+ ${ bundleNodeJsNativeModule } "$dir/$f"
302+ done
151303
152- make-installer --cardano ${ daedalus-bridge . ${ cluster } } \
153- --build-rev-short ${ sourceLib . buildRevShort } \
154- --build-counter ${ toString sourceLib . buildCounter } \
155- --cluster ${ cluster } \
156- --out-dir doesnt-matter \
157- --dont-pkgbuild
304+ # TODO: why is/was this "reverse" symlink needed? does it make sense?
305+ (
306+ cd "$dataDir"/app/node_modules/usb-detection/build/Release/
307+ rm detection.node
308+ ln -sfn ../../../../../../MacOS/detection.node
158309 )
310+
311+ mv "$dir"/${ lib . escapeShellArg launcherConfigs . ${ cluster } . installerConfig . spacedName } "$dir"/Frontend
312+ chmod +x "$dir"/Frontend
313+
314+ cat ${ pkgs . writeText "helper" ''
315+ #!/usr/bin/env bash
316+ mkdir -p "${ launcherConfigs . ${ cluster } . installerConfig . dataDir } /Secrets-1.0"
317+ mkdir -p "${ launcherConfigs . ${ cluster } . installerConfig . dataDir } /Logs/pub"
318+ '' } >"$dataDir"/helper
319+ chmod +x "$dataDir"/helper
320+
321+ cp ${ darwin-launcher } /bin/darwin-launcher "$dir"/${ lib . escapeShellArg launcherConfigs . ${ cluster } . installerConfig . spacedName }
159322 '' ;
160323 installPhase = ''
161324 mkdir -p $out/Applications/
0 commit comments