flutter: Redesign wrapping architecture

The following principles are now in place:

- All wrappers will include SDK file symlinks. There is not much of a reason to not do so, and removing the option to omit it makes it easier to understand what each wrapper does.
- There is no longer a way to get the previous derivation from a wrapper. This could yield unexpected results based on the wrapping order. Instead, "sdk", "unwrapped", and "noFHS" passthru attributes are provided where appropriate.

+161 -143
+1 -2
pkgs/development/compilers/flutter/default.nix
··· 3 mkFlutter = opts: callPackage (import ./flutter.nix opts) { }; 4 wrapFlutter = flutter: callPackage (import ./wrapper.nix) { flutter = flutter; }; 5 mkFlutterFHS = flutter: callPackage (import ./fhs.nix) { flutter = flutter; }; 6 - mkFakeSdk = flutter: callPackage (import ./fake-sdk.nix) { flutter = flutter; }; 7 getPatches = dir: 8 let files = builtins.attrNames (builtins.readDir dir); 9 in map (f: dir + ("/" + f)) files; ··· 29 }; 30 in 31 { 32 - inherit mkFlutter wrapFlutter mkFlutterFHS mkFakeSdk flutterDrv; 33 stable = flutterDrv { 34 version = "3.3.3"; 35 dartVersion = "2.18.2";
··· 3 mkFlutter = opts: callPackage (import ./flutter.nix opts) { }; 4 wrapFlutter = flutter: callPackage (import ./wrapper.nix) { flutter = flutter; }; 5 mkFlutterFHS = flutter: callPackage (import ./fhs.nix) { flutter = flutter; }; 6 getPatches = dir: 7 let files = builtins.attrNames (builtins.readDir dir); 8 in map (f: dir + ("/" + f)) files; ··· 28 }; 29 in 30 { 31 + inherit mkFlutter wrapFlutter mkFlutterFHS flutterDrv; 32 stable = flutterDrv { 33 version = "3.3.3"; 34 dartVersion = "2.18.2";
-15
pkgs/development/compilers/flutter/fake-sdk.nix
··· 1 - { flutter, symlinkJoin }: 2 - 3 - symlinkJoin { 4 - name = "flutter-fake-${flutter.name}"; 5 - paths = [ flutter flutter.unwrapped ]; 6 - 7 - inherit (flutter) passthru; 8 - 9 - meta = flutter.meta // { 10 - longDescription = '' 11 - ${flutter.meta.longDescription} 12 - Modified binaries are linked into the original SDK directory for use with tools that use the whole SDK. 13 - ''; 14 - }; 15 - }
···
+65 -61
pkgs/development/compilers/flutter/fhs.nix
··· 7 , supportsAndroidEmulator ? stdenv.isLinux 8 }: 9 10 - let 11 - # Wrap flutter inside an fhs user env to allow execution of binary, 12 - # like adb from $ANDROID_HOME or java from android-studio. 13 - self = buildFHSUserEnv { 14 - name = flutter.name; 15 16 - multiPkgs = pkgs: with pkgs; ([ 17 - # Flutter only use these certificates 18 - (runCommandLocal "fedoracert" { } '' 19 - mkdir -p $out/etc/pki/tls/ 20 - ln -s ${cacert}/etc/ssl/certs $out/etc/pki/tls/certs 21 - '') 22 - zlib 23 - ]); 24 25 - targetPkgs = pkgs: with pkgs; ([ 26 - flutter 27 28 - # General ecosystem dependencies 29 - bash 30 - curl 31 - git 32 - unzip 33 - which 34 - xz 35 36 - # flutter test requires this lib 37 - libGLU 38 - ] ++ lib.optional supportsAndroidEmulator [ 39 - # for android emulator 40 - alsa-lib 41 - dbus 42 - expat 43 - libpulseaudio 44 - libuuid 45 - xorg.libX11 46 - xorg.libxcb 47 - xorg.libXcomposite 48 - xorg.libXcursor 49 - xorg.libXdamage 50 - xorg.libXext 51 - xorg.libXfixes 52 - xorg.libXi 53 - xorg.libXrender 54 - xorg.libXtst 55 - libGL 56 - nspr 57 - nss 58 - systemd 59 - ]); 60 61 - runScript = "flutter"; 62 63 - passthru = flutter.passthru // { 64 - wrapped = flutter; 65 - mkFlutterApp = callPackage ../../../build-support/flutter { 66 - flutter = callPackage ./fhs.nix { supportsAndroidEmulator = false; }; 67 - }; 68 - fakeSdk = callPackage ./fake-sdk.nix { flutter = self; }; 69 }; 70 71 - meta = flutter.meta // { 72 - longDescription = '' 73 - ${flutter.meta.longDescription} 74 - Wrapped in a FHS environment to improve compatibility with internal tools and tools in the ecosystem. 75 - ''; 76 - }; 77 }; 78 - in 79 - self
··· 7 , supportsAndroidEmulator ? stdenv.isLinux 8 }: 9 10 11 + # Wrap flutter inside an fhs user env to allow execution of binary, 12 + # like adb from $ANDROID_HOME or java from android-studio. 13 + (callPackage ./sdk-symlink.nix { }) (buildFHSUserEnv rec { 14 + name = "${flutter.name}-fhs"; 15 16 + multiPkgs = pkgs: with pkgs; ([ 17 + # Flutter only use these certificates 18 + (runCommandLocal "fedoracert" { } '' 19 + mkdir -p $out/etc/pki/tls/ 20 + ln -s ${cacert}/etc/ssl/certs $out/etc/pki/tls/certs 21 + '') 22 + zlib 23 + ]); 24 25 + targetPkgs = pkgs: with pkgs; ([ 26 + flutter 27 28 + # General ecosystem dependencies 29 + bash 30 + curl 31 + git 32 + unzip 33 + which 34 + xz 35 36 + # flutter test requires this lib 37 + libGLU 38 + ] ++ lib.optional supportsAndroidEmulator [ 39 + # for android emulator 40 + alsa-lib 41 + dbus 42 + expat 43 + libpulseaudio 44 + libuuid 45 + xorg.libX11 46 + xorg.libxcb 47 + xorg.libXcomposite 48 + xorg.libXcursor 49 + xorg.libXdamage 50 + xorg.libXext 51 + xorg.libXfixes 52 + xorg.libXi 53 + xorg.libXrender 54 + xorg.libXtst 55 + libGL 56 + nspr 57 + nss 58 + systemd 59 + ]); 60 + 61 + runScript = "flutter"; 62 + 63 + extraInstallCommands = '' 64 + # By default, the derivation name is used as the binary name. 65 + # This is not the desired behaviour in this case. 66 + # https://github.com/NixOS/nixpkgs/blob/cb4536bf3606a7b6b54b69afe22ccd82e2906d92/pkgs/build-support/build-fhs-userenv/default.nix#L43 67 + mv $out/bin/${name} $out/bin/flutter 68 + ''; 69 70 + passthru = flutter.passthru // { 71 + nonFHS = flutter; 72 + mkFlutterApp = callPackage ../../../build-support/flutter { 73 + flutter = callPackage ./fhs.nix { supportsAndroidEmulator = false; }; 74 }; 75 + }; 76 77 + meta = flutter.meta // { 78 + longDescription = '' 79 + ${flutter.meta.longDescription} 80 + Wrapped in a FHS environment to improve compatibility with internal tools and tools in the ecosystem. 81 + ''; 82 }; 83 + })
+69 -59
pkgs/development/compilers/flutter/flutter.nix
··· 10 , which 11 }: 12 13 - stdenv.mkDerivation { 14 - name = "$flutter-${version}-unwrapped"; 15 16 - buildInputs = [ git ]; 17 18 - inherit src patches version; 19 20 - postPatch = '' 21 - patchShebangs --build ./bin/ 22 - ''; 23 24 - buildPhase = '' 25 - export FLUTTER_ROOT="$(pwd)" 26 - export FLUTTER_TOOLS_DIR="$FLUTTER_ROOT/packages/flutter_tools" 27 - export SCRIPT_PATH="$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart" 28 29 - export SNAPSHOT_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.snapshot" 30 - export STAMP_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.stamp" 31 32 - export DART_SDK_PATH="${dart}" 33 34 - HOME=../.. # required for pub upgrade --offline, ~/.pub-cache 35 - # path is relative otherwise it's replaced by /build/flutter 36 37 - pushd "$FLUTTER_TOOLS_DIR" 38 - ${dart}/bin/dart pub get --offline 39 - popd 40 41 - local revision="$(cd "$FLUTTER_ROOT"; git rev-parse HEAD)" 42 - ${dart}/bin/dart --snapshot="$SNAPSHOT_PATH" --packages="$FLUTTER_TOOLS_DIR/.dart_tool/package_config.json" "$SCRIPT_PATH" 43 - echo "$revision" > "$STAMP_PATH" 44 - echo -n "${version}" > version 45 46 - rm -r bin/cache/{artifacts,dart-sdk,downloads} 47 - rm bin/cache/*.stamp 48 - ''; 49 50 - installPhase = '' 51 - runHook preInstall 52 53 - mkdir -p $out 54 - cp -r . $out 55 - mkdir -p $out/bin/cache/ 56 - ln -sf ${dart} $out/bin/cache/dart-sdk 57 58 - runHook postInstall 59 - ''; 60 61 - doInstallCheck = true; 62 - installCheckInputs = [ which ]; 63 - installCheckPhase = '' 64 - runHook preInstallCheck 65 66 - export HOME="$(mktemp -d)" 67 - $out/bin/flutter config --android-studio-dir $HOME 68 - $out/bin/flutter config --android-sdk $HOME 69 - $out/bin/flutter --version | fgrep -q '${version}' 70 71 - runHook postInstallCheck 72 - ''; 73 74 - passthru = { 75 - inherit dart; 76 - }; 77 78 - meta = with lib; { 79 - description = "Flutter is Google's SDK for building mobile, web and desktop with Dart"; 80 - longDescription = '' 81 - Flutter is Google’s UI toolkit for building beautiful, 82 - natively compiled applications for mobile, web, and desktop from a single codebase. 83 - ''; 84 - homepage = "https://flutter.dev"; 85 - license = licenses.bsd3; 86 - platforms = [ "x86_64-linux" "aarch64-linux" ]; 87 - maintainers = with maintainers; [ babariviere ericdallo ]; 88 - }; 89 - }
··· 10 , which 11 }: 12 13 + let 14 + self = 15 + stdenv.mkDerivation { 16 + name = "$flutter-${version}-unwrapped"; 17 18 + buildInputs = [ git ]; 19 20 + inherit src patches version; 21 22 + postPatch = '' 23 + patchShebangs --build ./bin/ 24 + ''; 25 26 + buildPhase = '' 27 + export FLUTTER_ROOT="$(pwd)" 28 + export FLUTTER_TOOLS_DIR="$FLUTTER_ROOT/packages/flutter_tools" 29 + export SCRIPT_PATH="$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart" 30 31 + export SNAPSHOT_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.snapshot" 32 + export STAMP_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.stamp" 33 34 + export DART_SDK_PATH="${dart}" 35 36 + HOME=../.. # required for pub upgrade --offline, ~/.pub-cache 37 + # path is relative otherwise it's replaced by /build/flutter 38 39 + pushd "$FLUTTER_TOOLS_DIR" 40 + ${dart}/bin/dart pub get --offline 41 + popd 42 43 + local revision="$(cd "$FLUTTER_ROOT"; git rev-parse HEAD)" 44 + ${dart}/bin/dart --snapshot="$SNAPSHOT_PATH" --packages="$FLUTTER_TOOLS_DIR/.dart_tool/package_config.json" "$SCRIPT_PATH" 45 + echo "$revision" > "$STAMP_PATH" 46 + echo -n "${version}" > version 47 48 + rm -r bin/cache/{artifacts,dart-sdk,downloads} 49 + rm bin/cache/*.stamp 50 + ''; 51 52 + installPhase = '' 53 + runHook preInstall 54 55 + mkdir -p $out 56 + cp -r . $out 57 + mkdir -p $out/bin/cache/ 58 + ln -sf ${dart} $out/bin/cache/dart-sdk 59 60 + runHook postInstall 61 + ''; 62 63 + doInstallCheck = true; 64 + installCheckInputs = [ which ]; 65 + installCheckPhase = '' 66 + runHook preInstallCheck 67 68 + export HOME="$(mktemp -d)" 69 + $out/bin/flutter config --android-studio-dir $HOME 70 + $out/bin/flutter config --android-sdk $HOME 71 + $out/bin/flutter --version | fgrep -q '${version}' 72 73 + runHook postInstallCheck 74 + ''; 75 76 + passthru = { 77 + inherit dart; 78 79 + # The derivation containing the original Flutter SDK files. 80 + # When other derivations wrap this one, any unmodified files 81 + # found here should be included as-is, for tooling compatibility. 82 + sdk = self; 83 + }; 84 + 85 + meta = with lib; { 86 + description = "Flutter is Google's SDK for building mobile, web and desktop with Dart"; 87 + longDescription = '' 88 + Flutter is Google’s UI toolkit for building beautiful, 89 + natively compiled applications for mobile, web, and desktop from a single codebase. 90 + ''; 91 + homepage = "https://flutter.dev"; 92 + license = licenses.bsd3; 93 + platforms = [ "x86_64-linux" "aarch64-linux" ]; 94 + maintainers = with maintainers; [ babariviere ericdallo ]; 95 + }; 96 + } 97 + ; 98 + in 99 + self
+24
pkgs/development/compilers/flutter/sdk-symlink.nix
···
··· 1 + { symlinkJoin }: flutter: 2 + 3 + let 4 + self = 5 + symlinkJoin { 6 + name = "${flutter.name}-sdk-links"; 7 + paths = [ flutter flutter.sdk ]; 8 + 9 + passthru = flutter.passthru // { 10 + # Update the SDK attribute. 11 + # This allows any modified SDK files to be included 12 + # in future invocations. 13 + sdk = self; 14 + }; 15 + 16 + meta = flutter.meta // { 17 + longDescription = '' 18 + ${flutter.meta.longDescription} 19 + Modified binaries are linked into the original SDK directory for use with tools that use the whole SDK. 20 + ''; 21 + }; 22 + }; 23 + in 24 + self
+2 -6
pkgs/development/compilers/flutter/wrapper.nix
··· 79 cppFlags = map (pkg: "-isystem ${lib.getOutput "dev" pkg}/include") appStaticBuildDeps; 80 linkerFlags = map (pkg: "-rpath,${lib.getOutput "lib" pkg}/lib") appRuntimeDeps; 81 in 82 - runCommandLocal "flutter" 83 { 84 buildInputs = [ makeWrapper ]; 85 ··· 90 inherit (flutter) meta; 91 } '' 92 mkdir -p $out/bin 93 - 94 - mkdir -p $out/bin/cache/ 95 - ln -sf ${flutter.dart} $out/bin/cache/dart-sdk 96 - 97 makeWrapper '${immutableFlutter}' $out/bin/flutter \ 98 --set-default ANDROID_EMULATOR_USE_SYSTEM_LIBS 1 \ 99 --prefix PATH : '${lib.makeBinPath buildTools}' \ ··· 101 --prefix CXXFLAGS "''\t" '${builtins.concatStringsSep " " cppFlags}' \ 102 --prefix LDFLAGS "''\t" '${builtins.concatStringsSep " " (map (flag: "-Wl,${flag}") linkerFlags)}' \ 103 --suffix LD_LIBRARY_PATH : '${lib.makeLibraryPath appPrebuiltDeps}' 104 - ''
··· 79 cppFlags = map (pkg: "-isystem ${lib.getOutput "dev" pkg}/include") appStaticBuildDeps; 80 linkerFlags = map (pkg: "-rpath,${lib.getOutput "lib" pkg}/lib") appRuntimeDeps; 81 in 82 + (callPackage ./sdk-symlink.nix { }) (runCommandLocal "flutter-wrapped" 83 { 84 buildInputs = [ makeWrapper ]; 85 ··· 90 inherit (flutter) meta; 91 } '' 92 mkdir -p $out/bin 93 makeWrapper '${immutableFlutter}' $out/bin/flutter \ 94 --set-default ANDROID_EMULATOR_USE_SYSTEM_LIBS 1 \ 95 --prefix PATH : '${lib.makeBinPath buildTools}' \ ··· 97 --prefix CXXFLAGS "''\t" '${builtins.concatStringsSep " " cppFlags}' \ 98 --prefix LDFLAGS "''\t" '${builtins.concatStringsSep " " (map (flag: "-Wl,${flag}") linkerFlags)}' \ 99 --suffix LD_LIBRARY_PATH : '${lib.makeLibraryPath appPrebuiltDeps}' 100 + '')