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