mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-22 23:13:19 +00:00
Merge pull request #281662 from hacker1024/feature/flutter-build-web
Support Web builds in buildFlutterApplication
This commit is contained in:
commit
45308f5528
@ -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`.
|
||||
|
@ -1,4 +1,5 @@
|
||||
{ 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
|
||||
'';
|
||||
})
|
||||
|
@ -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)
|
||||
|
@ -19,15 +19,25 @@ dartInstallHook() {
|
||||
fi
|
||||
done < <(_getDartEntryPoints)
|
||||
|
||||
# Install the package_config.json file.
|
||||
mkdir -p "$pubcache"
|
||||
cp .dart_tool/package_config.json "$pubcache/package_config.json"
|
||||
|
||||
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"
|
||||
|
||||
echo "Finished dartInstallCacheHook"
|
||||
}
|
||||
|
||||
if [ -z "${dontDartInstall-}" ] && [ -z "${installPhase-}" ]; then
|
||||
installPhase=dartInstallHook
|
||||
fi
|
||||
|
||||
if [ -z "${dontDartInstallCache-}" ]; then
|
||||
postInstallHooks+=(dartInstallCacheHook)
|
||||
fi
|
||||
|
@ -17,134 +17,163 @@
|
||||
|
||||
{ pubGetScript ? "flutter pub get"
|
||||
, flutterBuildFlags ? [ ]
|
||||
, targetFlutterPlatform ? "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"
|
||||
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
|
||||
#
|
||||
# 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
|
||||
'';
|
||||
export HOME="$NIX_BUILD_TOP"
|
||||
flutter config --no-analytics &>/dev/null # mute first-run
|
||||
flutter config --enable-linux-desktop >/dev/null
|
||||
'';
|
||||
|
||||
inherit pubGetScript;
|
||||
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
|
||||
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" ];
|
||||
|
||||
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 = (universal.nativeBuildInputs or [ ]) ++ [
|
||||
wrapGAppsHook
|
||||
|
||||
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
|
||||
];
|
||||
|
||||
# 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 ];
|
||||
|
||||
buildInputs = (args.buildInputs or [ ]) ++ [ glib ];
|
||||
dontDartBuild = true;
|
||||
buildPhase = universal.buildPhase or ''
|
||||
runHook preBuild
|
||||
|
||||
dontDartBuild = true;
|
||||
buildPhase = args.buildPhase or ''
|
||||
runHook preBuild
|
||||
mkdir -p build/flutter_assets/fonts
|
||||
|
||||
mkdir -p build/flutter_assets/fonts
|
||||
flutter build linux -v --release --split-debug-info="$debug" ${builtins.concatStringsSep " " (map (flag: "\"${flag}\"") flutterBuildFlags)}
|
||||
|
||||
flutter build linux -v --release --split-debug-info="$debug" ${builtins.concatStringsSep " " (map (flag: "\"${flag}\"") flutterBuildFlags)}
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
dontDartInstall = true;
|
||||
installPhase = universal.installPhase or ''
|
||||
runHook preInstall
|
||||
|
||||
dontDartInstall = true;
|
||||
installPhase = args.installPhase or ''
|
||||
runHook preInstall
|
||||
built=build/linux/*/release/bundle
|
||||
|
||||
built=build/linux/*/release/bundle
|
||||
mkdir -p $out/bin
|
||||
mv $built $out/app
|
||||
|
||||
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 -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
|
||||
|
||||
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 {} +
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
'';
|
||||
|
||||
# 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"
|
||||
dontWrapGApps = true;
|
||||
extraWrapProgramArgs = ''
|
||||
''${gappsWrapperArgs[@]} \
|
||||
${extraWrapProgramArgs}
|
||||
'';
|
||||
};
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
web = universal // {
|
||||
dontDartBuild = true;
|
||||
buildPhase = universal.buildPhase or ''
|
||||
runHook preBuild
|
||||
|
||||
dontWrapGApps = true;
|
||||
extraWrapProgramArgs = ''
|
||||
''${gappsWrapperArgs[@]} \
|
||||
${extraWrapProgramArgs}
|
||||
'';
|
||||
})
|
||||
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; }; })
|
||||
|
@ -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); };
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -3848,6 +3848,8 @@ with pkgs;
|
||||
|
||||
fluffychat = callPackage ../applications/networking/instant-messengers/fluffychat { };
|
||||
|
||||
fluffychat-web = fluffychat.override { targetFlutterPlatform = "web"; };
|
||||
|
||||
fxlinuxprintutil = callPackage ../tools/misc/fxlinuxprintutil { };
|
||||
|
||||
gbl = callPackage ../tools/archivers/gbl {
|
||||
|
Loading…
Reference in New Issue
Block a user