Skip to content

Instantly share code, notes, and snippets.

@cryptix
Created April 9, 2021 09:30
Show Gist options
  • Save cryptix/9dc8806fe44f266d47f550b23b703ff8 to your computer and use it in GitHub Desktop.
Save cryptix/9dc8806fe44f266d47f550b23b703ff8 to your computer and use it in GitHub Desktop.
NixOS Shell for cabal-desktop development
with import <nixpkgs> {};
with pkgs;
let cabalEnv = buildEnv {
name = "cabal-desktop-env";
paths = [
# npm sodium stuff
clang
gnumake
libtool
autoconf
automake
m4
# electron stuff
alsaLib
atk
at-spi2-atk
at-spi2-core
binutils
bzip2
cairo
cups
dbus.lib
expat
fontconfig
freetype
fuse
gdk_pixbuf
glib
glibc
gtk3-x11
libuuid
libcap
libgnome_keyring3
libgpgerror
libnotify
libsodium
libappindicator-gtk3
nspr
nss
pango
python
readline
systemd
udev
xdg_utils
xorg.libX11
xorg.libXScrnSaver
xorg.libXcomposite
xorg.libXcursor
xorg.libXdamage
xorg.libXext
xorg.libXfixes
xorg.libXi
xorg.libXrandr
xorg.libXrender
xorg.libXtst
xorg.libxcb
zlib
];
extraOutputsToInstall = [ "lib" "dev" "out" ];
}; in
(pkgs.buildFHSUserEnv {
name = "cabal-desktop-chroot";
targetPkgs = pkgs: (with pkgs; [
nodejs-14_x
git
unzip
cabalEnv
]);
extraOutputsToInstall = [ "lib" "dev" "out" ];
extraBuildCommands = ''
(cd usr/lib64 && ln -sv libbz2.so.1.0.* libbz2.so.1.0)
'';
# see to compile native modules for electron and not the nodejs of the env
# https://www.electronjs.org/docs/tutorial/using-native-node-modules#using-npm
profile = ''
export npm_config_cache="/tmp/cabal-desktop-npm-cache/"
export npm_config_devdir="/tmp/cabal-desktop-gyp/"
export ELECTRON_CACHE="/tmp/cabal-desktop-electron-cache/"
export npm_config_target=7.1.13 # from package.json
# The architecture of Electron, see https://electronjs.org/docs/tutorial/support#supported-platforms
# for supported architectures.
export npm_config_arch=x64
export npm_config_target_arch=x64
# Download headers for Electron.
export npm_config_disturl=https://electronjs.org/headers
# Tell node-pre-gyp that we are building for Electron.
export npm_config_runtime=electron
# Tell node-pre-gyp to build module from source code.
export npm_config_build_from_source=true
export CC=clang
export CXX=clang++
export CFLAGS="$NIX_CFLAGS_COMPILE"
export CXXFLAGS="$NIX_CFLAGS_COMPILE"
export LDFLAGS="$NIX_LDFLAGS_BEFORE"
'';
}).env
@cryptix
Copy link
Author

cryptix commented Apr 9, 2021

This creates a FHS chroot inside which you can run stuff just like on any other linux/unix system without having to package everything for nixos specificly.

It's not as nice as packaging for nixpkgs and there might be a bit too much stuff in the cabalEnv but it get's the job done.

How to use this:

put the shell.nix inside your checkout of cabal-desktop, run nix-shell and start hacking, aka:

nix-shell
npm i
npm start

@nixinator
Copy link

maybe i can look at shaping this up to a real derivation/flake , however electron apps can be tricky..... so we'll have to see.

@kototama
Copy link

There is a conflict because ld is both in clang and binutils, any idea how to solve that?

@nixinator
Copy link

does it need both, at the same tine to function... if so how does it work in 'the real world'

@dansbandit
Copy link

Create default.nix with the following contents and run
nix-build -E 'with import <nixpkgs> {}; callPackage ./default.nix {}'

Works fine for me but it would be nice if anyone can test it so I can create a pull request for this.

{ lib
, stdenv
, fetchurl
, alsa-lib
, at-spi2-atk
, at-spi2-core
, atk
, autoPatchelfHook
, cairo
, cups
, dbus
, dpkg
, expat
, fontconfig
, gdk-pixbuf
, glib
, glibc
, gsettings-desktop-schemas
, gtk3
, libX11
, libXScrnSaver
, libXcomposite
, libXcursor
, libXdamage
, libXext
, libXfixes
, libXi
, libXrandr
, libXrender
, libXtst
, libappindicator-gtk3
, libcap
, libgnome-keyring3
, libgpgerror
, libnotify
, libsodium
, libudev0-shim
, libuuid
, libxcb
, makeWrapper
, nspr
, nss
, pango
, wrapGAppsHook
}:

stdenv.mkDerivation rec {
  pname = "cabal-desktop";
  version = "7.0.0";

  src = fetchurl {
    url = "https://github.com/cabal-club/cabal-desktop/releases/download/v${version}/cabal-desktop_${version}_amd64.deb";
    hash = "sha256-PgQJWE4OmZNIykYMzOpGyXvXGnImOlq/egqZVB6ZFNE=";
  };

  buildInputs = [
    alsa-lib
    at-spi2-atk
    at-spi2-core
    atk
    cairo
    cups
    dbus
    expat
    fontconfig
    gdk-pixbuf
    glib
    gsettings-desktop-schemas
    gtk3
    libX11
    libXScrnSaver
    libXcomposite
    libXcursor
    libXdamage
    libXext
    libXfixes
    libXi
    libXrandr
    libXrender
    libXtst
    libappindicator-gtk3
    libcap
    libgnome-keyring3
    libgpgerror
    libnotify
    libsodium
    libudev0-shim
    libuuid
    libxcb
    nspr
    nss
    pango
  ];

  nativeBuildInputs = [
    autoPatchelfHook
    dpkg
    makeWrapper
    wrapGAppsHook
  ];

  runtimeLibs = lib.makeLibraryPath [ libudev0-shim glibc ];

  unpackPhase = ''
    dpkg-deb -x $src .
  '';

  installPhase = ''
    mkdir -p $out/share/cabal-desktop $out/bin $out/lib
    mv opt/Cabal/* $out/share/cabal-desktop
    mv usr/share/* $out/share/
    ln -s $out/share/cabal-desktop/cabal-desktop $out/bin/cabal-desktop
  '';

  preFixup = ''
    gappsWrapperArgs+=(--prefix LD_LIBRARY_PATH : "${runtimeLibs}" )
    # Correct desktop file `Exec`
    substituteInPlace $out/share/applications/cabal-desktop.desktop \
      --replace "/opt/Cabal/cabal-desktop" "$out/bin/cabal-desktop"
  '';

  meta = {
    homepage = "https://cabal.chat/";
    description = "Desktop client for cabal, the p2p/decentralized/offline-first chat platform";
    license = lib.licenses.agpl3Only;
    maintainers = [ lib.maintainers.dansbandit ];
    platforms = lib.platforms.linux;
    sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
  };
}

@nixinator
Copy link

it a shame the it's a .deb that has to use patch elf, is the source not avalable?

@cryptix
Copy link
Author

cryptix commented Apr 6, 2023

It is! But I couldn’t get electron builder and node2nix to play nicely… 🤷‍♂️🙈

ps: it actually uses yarn and I couldn’t figure out how that factors into this.

@nixinator
Copy link

roger that.. !! !!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment