1{
2 lib,
3 stdenv,
4 darwin,
5 callPackage,
6 flutter,
7 supportedTargetFlutterPlatforms ?
8 [
9 "universal"
10 "web"
11 ]
12 ++ lib.optional (stdenv.hostPlatform.isLinux && !(flutter ? engine)) "linux"
13 ++ lib.optional (stdenv.hostPlatform.isx86_64 || stdenv.hostPlatform.isDarwin) "android"
14 ++ lib.optionals stdenv.hostPlatform.isDarwin [
15 "macos"
16 "ios"
17 ],
18 artifactHashes ? flutter.artifactHashes,
19 extraPkgConfigPackages ? [ ],
20 extraLibraries ? [ ],
21 extraIncludes ? [ ],
22 extraCxxFlags ? [ ],
23 extraCFlags ? [ ],
24 extraLinkerFlags ? [ ],
25 makeWrapper,
26 writeShellScript,
27 wrapGAppsHook3,
28 git,
29 which,
30 pkg-config,
31 atk,
32 cairo,
33 gdk-pixbuf,
34 glib,
35 gtk3,
36 harfbuzz,
37 libepoxy,
38 pango,
39 libX11,
40 xorgproto,
41 libdeflate,
42 zlib,
43 cmake,
44 ninja,
45 clang,
46 symlinkJoin,
47}:
48
49let
50 supportsLinuxDesktopTarget = builtins.elem "linux" supportedTargetFlutterPlatforms;
51
52 flutterPlatformArtifacts = lib.genAttrs supportedTargetFlutterPlatforms (
53 flutterPlatform:
54 (callPackage ./artifacts/prepare-artifacts.nix {
55 src = callPackage ./artifacts/fetch-artifacts.nix {
56 inherit flutterPlatform;
57 systemPlatform = stdenv.hostPlatform.system;
58 flutter = callPackage ./wrapper.nix { inherit flutter; };
59 hash = artifactHashes.${flutterPlatform}.${stdenv.hostPlatform.system} or "";
60 };
61 })
62 );
63
64 cacheDir = symlinkJoin {
65 name = "flutter-cache-dir";
66 paths = builtins.attrValues flutterPlatformArtifacts;
67 postBuild = ''
68 mkdir -p "$out/bin/cache"
69 ln -s '${flutter}/bin/cache/dart-sdk' "$out/bin/cache"
70 '';
71 passthru.flutterPlatform = flutterPlatformArtifacts;
72 };
73
74 # By default, Flutter stores downloaded files (such as the Pub cache) in the SDK directory.
75 # Wrap it to ensure that it does not do that, preferring home directories instead.
76 immutableFlutter = writeShellScript "flutter_immutable" ''
77 export PUB_CACHE=''${PUB_CACHE:-"$HOME/.pub-cache"}
78 ${flutter}/bin/flutter "$@"
79 '';
80
81 # Tools that the Flutter tool depends on.
82 tools = [
83 git
84 which
85 ];
86
87 # Libraries that Flutter apps depend on at runtime.
88 appRuntimeDeps = lib.optionals supportsLinuxDesktopTarget [
89 atk
90 cairo
91 gdk-pixbuf
92 glib
93 gtk3
94 harfbuzz
95 libepoxy
96 pango
97 libX11
98 libdeflate
99 ];
100
101 # Development packages required for compilation.
102 appBuildDeps =
103 let
104 # https://discourse.nixos.org/t/handling-transitive-c-dependencies/5942/3
105 deps =
106 pkg:
107 builtins.filter lib.isDerivation ((pkg.buildInputs or [ ]) ++ (pkg.propagatedBuildInputs or [ ]));
108 collect = pkg: lib.unique ([ pkg ] ++ deps pkg ++ builtins.concatMap collect (deps pkg));
109 in
110 builtins.concatMap collect appRuntimeDeps;
111
112 # Some header files and libraries are not properly located by the Flutter SDK.
113 # They must be manually included.
114 appStaticBuildDeps =
115 (lib.optionals supportsLinuxDesktopTarget [
116 libX11
117 xorgproto
118 zlib
119 ])
120 ++ extraLibraries;
121
122 # Tools used by the Flutter SDK to compile applications.
123 buildTools = lib.optionals supportsLinuxDesktopTarget [
124 pkg-config
125 cmake
126 ninja
127 clang
128 ];
129
130 # Nix-specific compiler configuration.
131 pkgConfigPackages = map (lib.getOutput "dev") (appBuildDeps ++ extraPkgConfigPackages);
132 includeFlags = map (pkg: "-isystem ${lib.getOutput "dev" pkg}/include") (
133 appStaticBuildDeps ++ extraIncludes
134 );
135 linkerFlags =
136 (map (pkg: "-rpath,${lib.getOutput "lib" pkg}/lib") appRuntimeDeps) ++ extraLinkerFlags;
137in
138(callPackage ./sdk-symlink.nix { }) (
139 stdenv.mkDerivation {
140 pname = "flutter-wrapped";
141 inherit (flutter) version;
142
143 nativeBuildInputs =
144 [ makeWrapper ]
145 ++ lib.optionals stdenv.hostPlatform.isDarwin [ darwin.DarwinTools ]
146 ++ lib.optionals supportsLinuxDesktopTarget [
147 glib
148 wrapGAppsHook3
149 ];
150
151 passthru = flutter.passthru // {
152 inherit (flutter) version;
153 unwrapped = flutter;
154 updateScript = ./update/update.py;
155 inherit cacheDir;
156 };
157
158 dontUnpack = true;
159 dontWrapGApps = true;
160
161 installPhase =
162 ''
163 runHook preInstall
164
165 for path in ${
166 builtins.concatStringsSep " " (
167 builtins.foldl' (
168 paths: pkg:
169 paths
170 ++ (map (directory: "'${pkg}/${directory}/pkgconfig'") [
171 "lib"
172 "share"
173 ])
174 ) [ ] pkgConfigPackages
175 )
176 }; do
177 addToSearchPath FLUTTER_PKG_CONFIG_PATH "$path"
178 done
179
180 mkdir -p $out/bin
181 makeWrapper '${immutableFlutter}' $out/bin/flutter \
182 --set-default ANDROID_EMULATOR_USE_SYSTEM_LIBS 1 \
183 ''
184 + lib.optionalString (flutter ? engine && flutter.engine.meta.available) ''
185 --set-default FLUTTER_ENGINE "${flutter.engine}" \
186 --add-flags "--local-engine-host ${flutter.engine.outName}" \
187 ''
188 + ''
189 --suffix PATH : '${lib.makeBinPath (tools ++ buildTools)}' \
190 --suffix PKG_CONFIG_PATH : "$FLUTTER_PKG_CONFIG_PATH" \
191 --suffix LIBRARY_PATH : '${lib.makeLibraryPath appStaticBuildDeps}' \
192 --prefix CXXFLAGS "''\t" '${builtins.concatStringsSep " " (includeFlags ++ extraCxxFlags)}' \
193 --prefix CFLAGS "''\t" '${builtins.concatStringsSep " " (includeFlags ++ extraCFlags)}' \
194 --prefix LDFLAGS "''\t" '${
195 builtins.concatStringsSep " " (map (flag: "-Wl,${flag}") linkerFlags)
196 }' \
197 ''${gappsWrapperArgs[@]}
198
199 runHook postInstall
200 '';
201
202 inherit (flutter) meta;
203 }
204)