about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhacker1024 <hacker1024@users.sourceforge.net>2024-01-18 10:16:55 +1100
committerhacker1024 <hacker1024@users.sourceforge.net>2024-01-18 10:27:32 +1100
commitf51a0b053d1df26996d6cd3686570ce9f6b45188 (patch)
tree4c23fc1f02fbc53741ee2bb2f60b35632fabbab1
parentb43ee05f4e99bfe8b834d3c37508bbf00f5df539 (diff)
flutter.buildFlutterApplication: Allow building for the Web
-rw-r--r--doc/languages-frameworks/dart.section.md3
-rw-r--r--pkgs/build-support/flutter/default.nix274
-rw-r--r--pkgs/development/compilers/flutter/default.nix7
3 files changed, 154 insertions, 130 deletions
diff --git a/doc/languages-frameworks/dart.section.md b/doc/languages-frameworks/dart.section.md
index fca87fa70e4ec..9de9a1304c6e9 100644
--- a/doc/languages-frameworks/dart.section.md
+++ b/doc/languages-frameworks/dart.section.md
@@ -103,6 +103,9 @@ flutter.buildFlutterApplication {
   pname = "firmware-updater";
   version = "unstable-2023-04-30";
 
+  # To build for the Web, use the flutterHostPlatform argument.
+  # flutterHostPlatform = "web";
+
   src = fetchFromGitHub {
     owner = "canonical";
     repo = "firmware-updater";
diff --git a/pkgs/build-support/flutter/default.nix b/pkgs/build-support/flutter/default.nix
index 4d00e177370e6..55a234405c6a7 100644
--- a/pkgs/build-support/flutter/default.nix
+++ b/pkgs/build-support/flutter/default.nix
@@ -17,134 +17,160 @@
 
 { pubGetScript ? "flutter pub get"
 , flutterBuildFlags ? [ ]
+, flutterHostPlatform ? "linux"
 , extraWrapProgramArgs ? ""
 , ...
 }@args:
 
-(buildDartApplication.override {
-  dart = flutter;
-}) (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
-    #
-    # Dart does not respect SSL_CERT_FILE...
-    # https://github.com/dart-lang/sdk/issues/48506
-    # ...and Flutter does not support --root-certs-file, so the path cannot be manually set.
-    # https://github.com/flutter/flutter/issues/56607
-    # https://github.com/flutter/flutter/issues/113594
-    #
-    # libredirect is of no use either, as Flutter does not pass any
-    # environment variables (including LD_PRELOAD) to the Pub process.
-    #
-    # Instead, Flutter is patched to allow the path to the Dart binary used for
-    # Pub commands to be overriden.
-    export NIX_FLUTTER_PUB_DART="${runCommand "dart-with-certs" { nativeBuildInputs = [ makeWrapper ]; } ''
-      mkdir -p "$out/bin"
-      makeWrapper ${flutter.dart}/bin/dart "$out/bin/dart" \
-        --add-flags "--root-certs-file=${cacert}/etc/ssl/certs/ca-bundle.crt"
-    ''}/bin/dart"
-
-    export HOME="$NIX_BUILD_TOP"
-    flutter config --no-analytics &>/dev/null # mute first-run
-    flutter config --enable-linux-desktop >/dev/null
-  '';
-
-  inherit pubGetScript;
-
-  sdkSourceBuilders = {
-    # https://github.com/dart-lang/pub/blob/68dc2f547d0a264955c1fa551fa0a0e158046494/lib/src/sdk/flutter.dart#L81
-    "flutter" = name: runCommand "flutter-sdk-${name}" { passthru.packageRoot = "."; } ''
-      for path in '${flutter}/packages/${name}' '${flutter}/bin/cache/pkg/${name}'; do
-        if [ -d "$path" ]; then
-          ln -s "$path" "$out"
-          break
+let
+  hostPlatforms = 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
+        #
+        # Dart does not respect SSL_CERT_FILE...
+        # https://github.com/dart-lang/sdk/issues/48506
+        # ...and Flutter does not support --root-certs-file, so the path cannot be manually set.
+        # https://github.com/flutter/flutter/issues/56607
+        # https://github.com/flutter/flutter/issues/113594
+        #
+        # libredirect is of no use either, as Flutter does not pass any
+        # environment variables (including LD_PRELOAD) to the Pub process.
+        #
+        # Instead, Flutter is patched to allow the path to the Dart binary used for
+        # Pub commands to be overriden.
+        export NIX_FLUTTER_PUB_DART="${runCommand "dart-with-certs" { nativeBuildInputs = [ makeWrapper ]; } ''
+          mkdir -p "$out/bin"
+          makeWrapper ${flutter.dart}/bin/dart "$out/bin/dart" \
+            --add-flags "--root-certs-file=${cacert}/etc/ssl/certs/ca-bundle.crt"
+        ''}/bin/dart"
+
+        export HOME="$NIX_BUILD_TOP"
+        flutter config --no-analytics &>/dev/null # mute first-run
+        flutter config --enable-linux-desktop >/dev/null
+      '';
+
+      inherit pubGetScript;
+
+      sdkSourceBuilders = {
+        # https://github.com/dart-lang/pub/blob/68dc2f547d0a264955c1fa551fa0a0e158046494/lib/src/sdk/flutter.dart#L81
+        "flutter" = name: runCommand "flutter-sdk-${name}" { passthru.packageRoot = "."; } ''
+          for path in '${flutter}/packages/${name}' '${flutter}/bin/cache/pkg/${name}'; do
+            if [ -d "$path" ]; then
+              ln -s "$path" "$out"
+              break
+            fi
+          done
+
+          if [ ! -e "$out" ]; then
+            echo 1>&2 'The Flutter SDK does not contain the requested package: ${name}!'
+            exit 1
+          fi
+        '';
+      };
+
+      extraPackageConfigSetup = ''
+        # https://github.com/flutter/flutter/blob/3.13.8/packages/flutter_tools/lib/src/dart/pub.dart#L755
+        if [ "$('${yq}/bin/yq' '.flutter.generate // false' pubspec.yaml)" = "true" ]; then
+          '${jq}/bin/jq' '.packages |= . + [{
+            name: "flutter_gen",
+            rootUri: "flutter_gen",
+            languageVersion: "2.12",
+          }]' "$out" | '${moreutils}/bin/sponge' "$out"
         fi
-      done
+      '';
+    };
 
-      if [ ! -e "$out" ]; then
-        echo 1>&2 'The Flutter SDK does not contain the requested package: ${name}!'
-        exit 1
-      fi
-    '';
-  };
+    linux = universal // {
+      outputs = universal.outputs or [ ] ++ [ "debug" ];
+
+      nativeBuildInputs = (universal.nativeBuildInputs or [ ]) ++ [
+        wrapGAppsHook
+
+        # Flutter requires pkg-config for Linux desktop support, and many plugins
+        # attempt to use it.
+        #
+        # It is available to the `flutter` tool through its wrapper, but it must be
+        # added here as well so the setup hook adds plugin dependencies to the
+        # pkg-config search paths.
+        pkg-config
+      ];
+
+      buildInputs = (universal.buildInputs or [ ]) ++ [ glib ];
+
+      dontDartBuild = true;
+      buildPhase = universal.buildPhase or ''
+        runHook preBuild
+
+        mkdir -p build/flutter_assets/fonts
+
+        flutter build linux -v --release --split-debug-info="$debug" ${builtins.concatStringsSep " " (map (flag: "\"${flag}\"") flutterBuildFlags)}
+
+        runHook postBuild
+      '';
+
+      dontDartInstall = true;
+      installPhase = universal.installPhase or ''
+        runHook preInstall
+
+        built=build/linux/*/release/bundle
+
+        mkdir -p $out/bin
+        mv $built $out/app
+
+        for f in $(find $out/app -iname "*.desktop" -type f); do
+          install -D $f $out/share/applications/$(basename $f)
+        done
 
-  extraPackageConfigSetup = ''
-    # https://github.com/flutter/flutter/blob/3.13.8/packages/flutter_tools/lib/src/dart/pub.dart#L755
-    if [ "$('${yq}/bin/yq' '.flutter.generate // false' pubspec.yaml)" = "true" ]; then
-      '${jq}/bin/jq' '.packages |= . + [{
-        name: "flutter_gen",
-        rootUri: "flutter_gen",
-        languageVersion: "2.12",
-      }]' "$out" | '${moreutils}/bin/sponge' "$out"
-    fi
-  '';
-
-  nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
-    wrapGAppsHook
-
-    # Flutter requires pkg-config for Linux desktop support, and many plugins
-    # attempt to use it.
-    #
-    # It is available to the `flutter` tool through its wrapper, but it must be
-    # added here as well so the setup hook adds plugin dependencies to the
-    # pkg-config search paths.
-    pkg-config
-  ];
-
-  buildInputs = (args.buildInputs or [ ]) ++ [ glib ];
-
-  dontDartBuild = true;
-  buildPhase = args.buildPhase or ''
-    runHook preBuild
-
-    mkdir -p build/flutter_assets/fonts
-
-    flutter build linux -v --release --split-debug-info="$debug" ${builtins.concatStringsSep " " (map (flag: "\"${flag}\"") flutterBuildFlags)}
-
-    runHook postBuild
-  '';
-
-  dontDartInstall = true;
-  installPhase = args.installPhase or ''
-    runHook preInstall
-
-    built=build/linux/*/release/bundle
-
-    mkdir -p $out/bin
-    mv $built $out/app
-
-    for f in $(find $out/app -iname "*.desktop" -type f); do
-      install -D $f $out/share/applications/$(basename $f)
-    done
-
-    for f in $(find $out/app -maxdepth 1 -type f); do
-      ln -s $f $out/bin/$(basename $f)
-    done
-
-    # make *.so executable
-    find $out/app -iname "*.so" -type f -exec chmod +x {} +
-
-    # remove stuff like /build/source/packages/ubuntu_desktop_installer/linux/flutter/ephemeral
-    for f in $(find $out/app -executable -type f); do
-      if patchelf --print-rpath "$f" | grep /build; then # this ignores static libs (e,g. libapp.so) also
-        echo "strip RPath of $f"
-        newrp=$(patchelf --print-rpath $f | sed -r "s|/build.*ephemeral:||g" | sed -r "s|/build.*profile:||g")
-        patchelf --set-rpath "$newrp" "$f"
-      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
-  '';
-
-  dontWrapGApps = true;
-  extraWrapProgramArgs = ''
-    ''${gappsWrapperArgs[@]} \
-    ${extraWrapProgramArgs}
-  '';
-})
+        for f in $(find $out/app -maxdepth 1 -type f); do
+          ln -s $f $out/bin/$(basename $f)
+        done
+
+        # make *.so executable
+        find $out/app -iname "*.so" -type f -exec chmod +x {} +
+
+        # remove stuff like /build/source/packages/ubuntu_desktop_installer/linux/flutter/ephemeral
+        for f in $(find $out/app -executable -type f); do
+          if patchelf --print-rpath "$f" | grep /build; then # this ignores static libs (e,g. libapp.so) also
+            echo "strip RPath of $f"
+            newrp=$(patchelf --print-rpath $f | sed -r "s|/build.*ephemeral:||g" | sed -r "s|/build.*profile:||g")
+            patchelf --set-rpath "$newrp" "$f"
+          fi
+        done
+
+        runHook postInstall
+      '';
+
+      dontWrapGApps = true;
+      extraWrapProgramArgs = ''
+        ''${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
+      '';
+    };
+  };
+in
+(buildDartApplication.override { dart = flutter.override { supportedTargetFlutterPlatforms = [ "universal" flutterHostPlatform ]; }; })
+  hostPlatforms.${flutterHostPlatform} or "Unsupported Flutter host platform: ${flutterHostPlatform}"
diff --git a/pkgs/development/compilers/flutter/default.nix b/pkgs/development/compilers/flutter/default.nix
index 29d5d415b8a05..6d2d904660338 100644
--- a/pkgs/development/compilers/flutter/default.nix
+++ b/pkgs/development/compilers/flutter/default.nix
@@ -51,12 +51,7 @@ let
     (mkCustomFlutter args).overrideAttrs (prev: next: {
       passthru = next.passthru // rec {
         inherit wrapFlutter mkCustomFlutter mkFlutter;
-        buildFlutterApplication = callPackage ../../../build-support/flutter {
-          # Package a minimal version of Flutter that only uses Linux desktop release artifacts.
-          flutter = (wrapFlutter (mkCustomFlutter args)).override {
-            supportedTargetFlutterPlatforms = [ "universal" "linux" ];
-          };
-        };
+        buildFlutterApplication = callPackage ../../../build-support/flutter { flutter = wrapFlutter (mkCustomFlutter args); };
       };
     });