Unverified Commit 45308f55 authored by Maciej Krüger's avatar Maciej Krüger Committed by GitHub
Browse files

Merge pull request #281662 from hacker1024/feature/flutter-build-web

Support Web builds in buildFlutterApplication
parents 8c1add25 64f9fa0d
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ Do _not_ use `dart run <package_name>`, as this will attempt to download depende

### Usage with nix-shell {#ssec-dart-applications-nix-shell}

#### Using dependencies from the Nix store {#ssec-dart-applications-nix-shell-deps}

As `buildDartApplication` provides dependencies instead of `pub get`, Dart needs to be explicitly told where to find them.

Run the following commands in the source directory to configure Dart appropriately.
@@ -103,6 +105,9 @@ flutter.buildFlutterApplication {
  pname = "firmware-updater";
  version = "unstable-2023-04-30";

  # To build for the Web, use the targetFlutterPlatform argument.
  # targetFlutterPlatform = "web";

  src = fetchFromGitHub {
    owner = "canonical";
    repo = "firmware-updater";
@@ -117,4 +122,15 @@ flutter.buildFlutterApplication {

### Usage with nix-shell {#ssec-dart-flutter-nix-shell}

See the [Dart documentation](#ssec-dart-applications-nix-shell) for nix-shell instructions.
Flutter-specific `nix-shell` usage notes are included here. See the [Dart documentation](#ssec-dart-applications-nix-shell) for general `nix-shell` instructions.

#### Entering the shell {#ssec-dart-flutter-nix-shell-enter}

By default, dependencies for only the `targetFlutterPlatform` are available in the
build environment. This is useful for keeping closures small, but be problematic
during development. It's common, for example, to build Web apps for Linux during
development to take advantage of native features such as stateful hot reload.

To enter a shell with all the usual target platforms available, use the `multiShell` attribute.

e.g. `nix-shell '<nixpkgs>' -A fluffychat-web.multiShell`.
+42 −17
Original line number Diff line number Diff line
{ lib
, fetchzip
, fetchFromGitHub
, imagemagick
, mesa
@@ -7,13 +8,15 @@
, pulseaudio
, makeDesktopItem
, gnome

, targetFlutterPlatform ? "linux"
}:

let
  libwebrtcRpath = lib.makeLibraryPath [ mesa libdrm ];
in
flutter313.buildFlutterApplication rec {
  pname = "fluffychat";
flutter313.buildFlutterApplication (rec {
  pname = "fluffychat-${targetFlutterPlatform}";
  version = "1.14.1";

  src = fetchFromGitHub {
@@ -30,6 +33,25 @@ flutter313.buildFlutterApplication rec {
    wakelock_windows = "sha256-Dfwe3dSScD/6kvkP67notcbb+EgTQ3kEYcH7wpra2dI=";
  };

  inherit targetFlutterPlatform;

  meta = with lib; {
    description = "Chat with your friends (matrix client)";
    homepage = "https://fluffychat.im/";
    license = licenses.agpl3Plus;
    maintainers = with maintainers; [ mkg20001 gilice ];
    platforms = [ "x86_64-linux" "aarch64-linux" ];
    sourceProvenance = [ sourceTypes.fromSource ];
  };
} // lib.optionalAttrs (targetFlutterPlatform == "linux") {
  nativeBuildInputs = [ imagemagick ];

  runtimeDependencies = [ pulseaudio ];

  extraWrapProgramArgs = "--prefix PATH : ${gnome.zenity}/bin";

  env.NIX_LDFLAGS = "-rpath-link ${libwebrtcRpath}";

  desktopItem = makeDesktopItem {
    name = "Fluffychat";
    exec = "@out@/bin/fluffychat";
@@ -39,9 +61,6 @@ flutter313.buildFlutterApplication rec {
    categories = [ "Chat" "Network" "InstantMessaging" ];
  };

  nativeBuildInputs = [ imagemagick ];
  runtimeDependencies = [ pulseaudio ];
  extraWrapProgramArgs = "--prefix PATH : ${gnome.zenity}/bin";
  postInstall = ''
    FAV=$out/app/data/flutter_assets/assets/favicon.png
    ICO=$out/share/icons
@@ -59,15 +78,21 @@ flutter313.buildFlutterApplication rec {

    patchelf --add-rpath ${libwebrtcRpath} $out/app/lib/libwebrtc.so
  '';

  env.NIX_LDFLAGS = "-rpath-link ${libwebrtcRpath}";

  meta = with lib; {
    description = "Chat with your friends (matrix client)";
    homepage = "https://fluffychat.im/";
    license = licenses.agpl3Plus;
    maintainers = with maintainers; [ mkg20001 gilice ];
    platforms = [ "x86_64-linux" "aarch64-linux" ];
    sourceProvenance = [ sourceTypes.fromSource ];
} // lib.optionalAttrs (targetFlutterPlatform == "web") {
  prePatch =
    # https://github.com/krille-chan/fluffychat/blob/v1.17.1/scripts/prepare-web.sh
    let
      # Use Olm 1.3.2, the oldest version, for FluffyChat 1.14.1 which depends on olm_flutter 1.2.0.
      # In the future, this should be changed to use self.pubspecLock.dependencyVersions.flutter_olm as the script does.
      olmVersion = "1.3.2";
      olmJs = fetchzip {
        url = "https://github.com/famedly/olm/releases/download/v${olmVersion}/olm.zip";
        stripRoot = false;
        hash = "sha256-Vl3Cp2OaYzM5CPOOtTHtUb1W48VXePzOV6FeiIzyD1Y=";
      };
}
    in
    ''
      rm -r assets/js/package
      cp -r '${olmJs}/javascript' assets/js/package
    '';
})
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ let
      dartCompileCommand dartOutputType dartRuntimeCommand dartCompileFlags
      dartJitFlags;

    outputs = args.outputs or [ ] ++ [ "out" "pubcache" ];
    outputs = [ "out" "pubcache" ] ++ args.outputs or [ ];

    dartEntryPoints =
      if (dartEntryPoints != null)
+13 −3
Original line number Diff line number Diff line
@@ -19,15 +19,25 @@ dartInstallHook() {
        fi
    done < <(_getDartEntryPoints)

    runHook postInstall

    echo "Finished dartInstallHook"
}

dartInstallCacheHook() {
    echo "Executing dartInstallCacheHook"

    # Install the package_config.json file.
    mkdir -p "$pubcache"
    cp .dart_tool/package_config.json "$pubcache/package_config.json"

    runHook postInstall

    echo "Finished dartInstallHook"
    echo "Finished dartInstallCacheHook"
}

if [ -z "${dontDartInstall-}" ] && [ -z "${installPhase-}" ]; then
    installPhase=dartInstallHook
fi

if [ -z "${dontDartInstallCache-}" ]; then
    postInstallHooks+=(dartInstallCacheHook)
fi
+155 −126
Original line number Diff line number Diff line
@@ -17,13 +17,14 @@

{ pubGetScript ? "flutter pub get"
, flutterBuildFlags ? [ ]
, targetFlutterPlatform ? "linux"
, extraWrapProgramArgs ? ""
, ...
}@args:

(buildDartApplication.override {
  dart = flutter;
}) (args // {
let
  builderArgs = rec {
    universal = args // {
      sdkSetupScript = ''
        # Pub needs SSL certificates. Dart normally looks in a hardcoded path.
        # https://github.com/dart-lang/sdk/blob/3.1.0/runtime/bin/security_context_linux.cc#L48
@@ -79,8 +80,12 @@
          }]' "$out" | '${moreutils}/bin/sponge' "$out"
        fi
      '';
    };

    linux = universal // {
      outputs = universal.outputs or [ ] ++ [ "debug" ];

  nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
      nativeBuildInputs = (universal.nativeBuildInputs or [ ]) ++ [
        wrapGAppsHook

        # Flutter requires pkg-config for Linux desktop support, and many plugins
@@ -92,10 +97,10 @@
        pkg-config
      ];

  buildInputs = (args.buildInputs or [ ]) ++ [ glib ];
      buildInputs = (universal.buildInputs or [ ]) ++ [ glib ];

      dontDartBuild = true;
  buildPhase = args.buildPhase or ''
      buildPhase = universal.buildPhase or ''
        runHook preBuild

        mkdir -p build/flutter_assets/fonts
@@ -106,7 +111,7 @@
      '';

      dontDartInstall = true;
  installPhase = args.installPhase or ''
      installPhase = universal.installPhase or ''
        runHook preInstall

        built=build/linux/*/release/bundle
@@ -134,11 +139,6 @@
          fi
        done

    # Install the package_config.json file.
    # This is normally done by dartInstallHook, but we disable it.
    mkdir -p "$pubcache"
    cp .dart_tool/package_config.json "$pubcache/package_config.json"

        runHook postInstall
      '';

@@ -147,4 +147,33 @@
        ''${gappsWrapperArgs[@]} \
        ${extraWrapProgramArgs}
      '';
})
    };

    web = universal // {
      dontDartBuild = true;
      buildPhase = universal.buildPhase or ''
        runHook preBuild

        mkdir -p build/flutter_assets/fonts

        flutter build web -v --release ${builtins.concatStringsSep " " (map (flag: "\"${flag}\"") flutterBuildFlags)}

        runHook postBuild
      '';

      dontDartInstall = true;
      installPhase = universal.installPhase or ''
        runHook preInstall

        cp -r build/web "$out"

        runHook postInstall
      '';
    };
  }.${targetFlutterPlatform} or (throw "Unsupported Flutter host platform: ${targetFlutterPlatform}");

  minimalFlutter = flutter.override { supportedTargetFlutterPlatforms = [ "universal" targetFlutterPlatform ]; };

  buildAppWith = flutter: buildDartApplication.override { dart = flutter; };
in
buildAppWith minimalFlutter (builderArgs // { passthru = builderArgs.passthru or { } // { multiShell = buildAppWith flutter builderArgs; }; })
Loading