Packaging dart/flutter for GNU Guix

Recently I have been wanting to learn the flutter toolkit, so I decided to write package definitions for dart and flutter. But I soon learned that its a bit more complex than I thought.

Here is what I have so far,

(define-module (nebula packages dart)
  #:use-module (gnu packages)
  #:use-module (gnu packages base)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages curl)
  #:use-module (gnu packages elf)
  #:use-module (guix git-download)
  #:use-module (guix packages)
  #:use-module (guix build utils)
  #:use-module (guix build-system python)
  #:use-module (guix utils)
  #:use-module ((guix licenses) #:prefix license:))

(define chromium-depot-tools
    (method git-fetch)
    (uri (git-reference
          (url "")
          (commit "1a61eb625d4b062bb2d6f0902b4979b48def4d33")))
     (base32 "1v38mla41dwy00plhxam8z3xk04m3pj5lsjynq9kzhqhmk6airyz"))))

(define-public dart
  (let ((commit "de84385653631c6283b02f09fb1944f8d8dd3b17")
        (revision "0"))
      (name "dart")
      (version "3.3.4")
         (method git-fetch)
         (uri (git-reference
               (url "")
               (commit commit)))
         (file-name (git-file-name name version))
          (base32 "1v38mla41dwy00plhxam8z3xk04m3pj5lsjynq9kzhqhmk6airyz"))))
      (build-system python-build-system)
       (list #:phases
             #~(modify-phases %standard-phases
                 (add-after 'unpack 'add-depot-tools-to-path
                   (lambda _
                     (let* ((depot-tools-path #$chromium-depot-tools))
                       (setenv "PATH" (string-append (getenv "PATH") ":" depot-tools-path)))))
                 (replace 'build
                   (lambda _
                     (system* "./tools/" "--mode" "release" "--arch" "x64" "create_sdk")))
                 (add-after 'install 'patchelf
                   (lambda* (#:key outputs inputs #:allow-other-keys)
                     (let* ((out (assoc-ref outputs "out")))
                       (system* "find"
                                (string-append out "/bin")
                                "-executable" "-type" "f" "-exec"
                                "patchelf" "--set-interpreter"
                                (string-append #$glibc "/lib/")
      (inputs (list curl))
      (native-inputs (list patchelf
                           ;; xz
      (home-page "")
      (synopsis "The Dart SDK, including the VM, dart2js, core libraries, and more")
      (description "Dart is a scalable programming language, with robust libraries and runtimes,
for building web, server, and mobile apps.")
      (license license:bsd-3))))

(Yes I am aware the hash for the chromium-depot-tools is wrong)

I was following this guide BTW, Building · dart-lang/sdk Wiki · GitHub, and also the nix package definition.

Currently I get this error,

/home/apoorv/repos/nebula/nebula/packages/dart.scm:62:15: warning: source expression failed to match any pattern
guix build: error: dart: unknown package

In any case, I don’t think I’m even close to making this work.

I also found that someone was trying to package dart for Guix, but there is no more activity there.

In case anyone is interested, here is the nix package definition for dart,

{ stdenv
, lib
, fetchurl
, unzip
, runCommand
, darwin
, sources ? import ./sources.nix {inherit fetchurl;}
, version ? sources.versionUsed

assert sources != null && (builtins.isAttrs sources);
stdenv.mkDerivation (finalAttrs: {
  pname = "dart";
  inherit version;

  nativeBuildInputs = [ unzip ];

  src = sources."${version}-${stdenv.hostPlatform.system}" or (throw "unsupported version/system: ${version}/${stdenv.hostPlatform.system}");

  installPhase = ''
    mkdir -p $out
    cp -R * $out/
    echo $libPath
  '' + lib.optionalString (stdenv.isLinux) ''
    find $out/bin -executable -type f -exec patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) {} \;

  libPath = lib.makeLibraryPath [ ];
  dontStrip = true;
  passthru = {
    updateScript = ./;
    tests = {
      testCreate = runCommand "dart-test-create" { nativeBuildInputs = [ finalAttrs.finalPackage ]; } ''
        dart create --no-pub $PROJECTNAME

        [[ -d $PROJECTNAME ]]
        [[ -f $PROJECTNAME/bin/$PROJECTNAME.dart ]]
        touch $out

      testCompile = runCommand "dart-test-compile" {
        nativeBuildInputs = [ finalAttrs.finalPackage ]
          ++ lib.optionals stdenv.isDarwin [ darwin.cctools darwin.sigtool ];
      } ''
        HELLO_MESSAGE="Hello, world!"
        echo "void main() => print('$HELLO_MESSAGE');" > hello.dart
        dart compile exe hello.dart

        [[ "$PROGRAM_OUT" == "$HELLO_MESSAGE" ]]
        touch $out

  meta = with lib; {
    homepage = "";
    maintainers = with maintainers; [ grburst ];
    description = "Scalable programming language, with robust libraries and runtimes, for building web, server, and mobile apps";
    longDescription = ''
      Dart is a class-based, single inheritance, object-oriented language
      with C-style syntax. It offers compilation to JavaScript, interfaces,
      mixins, abstract classes, reified generics, and optional typing.
    platforms = [ "x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
    sourceProvenance = with sourceTypes; [ binaryNativeCode ];
    license = licenses.bsd3;
1 Like

This particular error seems to go away if #use-module (guix gexp) is added to the module definition.

I haven’t tried building it, so I don’t know if anything else will show up (aside from the wrong hash).

This particular error seems to go away if #use-module (guix gexp) is added to the module definition.

Yup I was missing this.

But I don’t think I am even remotely close to building it. Apparently I might also have to package Android Studio which I think will require a fhs container, of which I have no idea how to package.

For now I am using Android Studio installed via Nix package manager with a locally installed flutter sdk under ~/.local/share/flutter.

It works, but I wanted to use emacs, as I’m so used to it, the keybinds and all.

The issue with Emacs ATM is that it couldn’t read the flutter and dart bin/scripts I just get this error when I run dart binary from shell,

  dart
/home/apoorv/.local/share/flutter/bin/internal/ line 263: /home/apoorv/.local/share/flutter/bin/cache/dart-sdk/bin/dart: No such file or directory

same with flutter binary. I’m guessing these also require a fhs container. I actually tried running it inside guix shell fhs container,

 guix shell --container --network --emulate-fhs --preserve=^PATH --preserve=^ANDROID_HOME --verbosity=3 coreutils bash git which inetutils nss-certs pkg-config cmake

But I still couldn’t make it work with emacs so…