1{ lib
2, stdenv
3, hostPlatform
4, engineVersion
5, fetchurl
6, fetchzip
7, autoPatchelfHook
8, gtk3
9, flutterVersion
10, unzip
11, stdenvNoCC
12}:
13
14let
15 hashes = (import ./hashes.nix).${engineVersion} or
16 (throw "There are no known artifact hashes for Flutter engine version ${engineVersion}.");
17 noticeText = stdenvNoCC.mkDerivation (finalAttrs: {
18 pname = "flutter-notice";
19 version = engineVersion;
20 dontUnpack = true;
21 src = fetchurl {
22 pname = "flutter-sky_engine-LICENSE";
23 version = engineVersion;
24 url = "https://raw.githubusercontent.com/flutter/engine/${engineVersion}/sky/packages/sky_engine/LICENSE";
25 sha256 = hashes.skyNotice;
26 };
27 flutterNotice = fetchurl {
28 pname = "flutter-LICENSE";
29 version = engineVersion;
30 url = "https://raw.githubusercontent.com/flutter/flutter/${flutterVersion}/LICENSE";
31 sha256 = hashes.flutterNotice;
32 };
33 installPhase =
34 ''
35 SRC_TEXT="$(cat $src)"
36 FLUTTER_NOTICE_TEXT="$(cat $flutterNotice)"
37 cat << EOF > $out
38 This artifact is from the Flutter SDK's engine.
39 This file carries third-party notices for its dependencies.
40 See also other files, that have LICENSE in the name, in the artifact directory.
41
42 Appendix 1/2: merged sky_engine LICENSE file (also found at ${finalAttrs.src.url})
43 $SRC_TEXT
44
45 Appendix 2/2: Flutter license (also found at ${finalAttrs.flutterNotice.url})
46 $FLUTTER_NOTICE_TEXT
47 EOF
48 '';
49 });
50 artifacts =
51 {
52 common = {
53 flutter_patched_sdk = { archive = "flutter_patched_sdk.zip"; };
54 flutter_patched_sdk_product = { archive = "flutter_patched_sdk_product.zip"; };
55 };
56 platform = {
57 android =
58 (lib.genAttrs
59 [ "arm" "arm64" "x64" ]
60 (arch:
61 {
62 base = [
63 { archive = "artifacts.zip"; }
64 ];
65 variants = lib.genAttrs [ "profile" "release" ]
66 (variant: [
67 { archive = "artifacts.zip"; }
68 { subdirectory = true; archive = "${lib.toLower hostPlatform.uname.system}-x64.zip"; }
69 ]);
70 })) //
71 {
72 "x86" = {
73 base = [
74 { archive = "artifacts.zip"; }
75 ];
76 variants.jit-release = [
77 { archive = "artifacts.zip"; }
78 ];
79 };
80 };
81
82 darwin = {
83 "arm64" = {
84 base = [
85 { archive = "artifacts.zip"; }
86 { archive = "font-subset.zip"; }
87 ];
88 variants = lib.genAttrs [ "profile" "release" ]
89 (variant: [
90 { archive = "artifacts.zip"; }
91 ]);
92 };
93 "x64" = {
94 base = [
95 { archive = "FlutterEmbedder.framework.zip"; }
96 { archive = "FlutterMacOS.framework.zip"; }
97 { archive = "artifacts.zip"; }
98 { archive = "font-subset.zip"; }
99 { archive = "gen_snapshot.zip"; }
100 ];
101 variants.profile = [
102 { archive = "FlutterMacOS.framework.zip"; }
103 { archive = "artifacts.zip"; }
104 { archive = "gen_snapshot.zip"; }
105 ];
106 variants.release = [
107 { archive = "FlutterMacOS.dSYM.zip"; }
108 { archive = "FlutterMacOS.framework.zip"; }
109 { archive = "artifacts.zip"; }
110 { archive = "gen_snapshot.zip"; }
111 ];
112 };
113 };
114
115 ios =
116 (lib.genAttrs
117 [ "" ]
118 (arch:
119 {
120 base = [
121 { archive = "artifacts.zip"; }
122 ];
123 variants.profile = [
124 { archive = "artifacts.zip"; }
125 ];
126 variants.release = [
127 { archive = "artifacts.zip"; }
128 { archive = "Flutter.dSYM.zip"; }
129 ];
130 }));
131
132 linux = lib.genAttrs
133 [ "arm64" "x64" ]
134 (arch:
135 let
136 linux-flutter-gtk = {
137 archive = "linux-${arch}-flutter-gtk.zip";
138 buildInputs = [ gtk3 ];
139 };
140 in
141 {
142 base = [
143 ({ archive = "artifacts.zip"; } // lib.optionalAttrs (arch == "arm64") {
144 # For some reason, the arm64 artifacts are missing shader code in Flutter < 3.10.0.
145 postPatch = ''
146 if [ ! -d shader_lib ]; then
147 ln -s ${lib.findSingle
148 (pkg: lib.getName pkg == "flutter-artifact-linux-x64-artifacts")
149 (throw "Could not find the x64 artifact archive.")
150 (throw "Could not find the correct x64 artifact archive.")
151 artifactDerivations.platform.linux.x64.base
152 }/shader_lib .
153 fi
154 '';
155 })
156 { archive = "font-subset.zip"; }
157 (linux-flutter-gtk // {
158 # https://github.com/flutter/flutter/commit/9d94a51b607600a39c14470c35c676eb3e30eed6
159 variant = "debug";
160 })
161 ];
162 variants = lib.genAttrs [ "debug" "profile" "release" ] (variant: [
163 linux-flutter-gtk
164 ]);
165 });
166 };
167 };
168
169 mkArtifactDerivation = { platform ? null, variant ? null, subdirectory ? null, archive, ... }@args:
170 let
171 artifactDirectory = if platform == null then null else "${platform}${lib.optionalString (variant != null) "-${variant}"}";
172 archiveBasename = lib.removeSuffix ".${(lib.last (lib.splitString "." archive))}" archive;
173 overrideUnpackCmd = builtins.elem archive [ "FlutterEmbedder.framework.zip" "FlutterMacOS.framework.zip" ];
174 in
175 stdenv.mkDerivation ({
176 pname = "flutter-artifact${lib.optionalString (platform != null) "-${artifactDirectory}"}-${archiveBasename}";
177 version = engineVersion;
178
179 nativeBuildInputs = [ unzip ]
180 ++ lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
181
182 src =
183 if overrideUnpackCmd then
184 (fetchurl {
185 url = "https://storage.googleapis.com/flutter_infra_release/flutter/${engineVersion}${lib.optionalString (platform != null) "/${artifactDirectory}"}/${archive}";
186 hash = (if artifactDirectory == null then hashes else hashes.${artifactDirectory}).${archive};
187 }) else
188 (fetchzip {
189 url = "https://storage.googleapis.com/flutter_infra_release/flutter/${engineVersion}${lib.optionalString (platform != null) "/${artifactDirectory}"}/${archive}";
190 stripRoot = false;
191 hash = (if artifactDirectory == null then hashes else hashes.${artifactDirectory}).${archive};
192 });
193
194 sourceRoot = if overrideUnpackCmd then "." else null;
195 unpackCmd = if overrideUnpackCmd then "unzip -o $src -d $out" else null;
196
197 installPhase =
198 let
199 destination = "$out/${if subdirectory == true then archiveBasename else if subdirectory != null then subdirectory else "."}";
200 in
201 ''
202 # ship the notice near all artifacts. if the artifact directory is / multiple directories are nested in $src, link it there. If there isn't a directory, link it in root
203 # this *isn't the same as the subdirectory variable above*
204 DIR_CNT="$(echo */ | wc -w)"
205 if [[ "$DIR_CNT" == 0 ]]; then
206 ln -s ${noticeText} LICENSE.README
207 else
208 for dir in */
209 do
210 ln -s ${noticeText} "$dir/LICENSE.README"
211 done
212 fi
213 mkdir -p "${destination}"
214 cp -r . "${destination}"
215 '';
216 } // args);
217
218 artifactDerivations = {
219 common = builtins.mapAttrs (name: mkArtifactDerivation) artifacts.common;
220 platform =
221 builtins.mapAttrs
222 (os: architectures:
223 builtins.mapAttrs
224 (architecture: variants: {
225 base = map
226 (args: mkArtifactDerivation ({
227 platform = "${os}${lib.optionalString (architecture != "") "-${architecture}"}";
228 } // args))
229 variants.base;
230 variants = builtins.mapAttrs
231 (variant: variantArtifacts: map
232 (args: mkArtifactDerivation ({
233 platform = "${os}${lib.optionalString (architecture != "") "-${architecture}"}";
234 inherit variant;
235 } // args))
236 variantArtifacts)
237 variants.variants;
238 })
239 architectures)
240 artifacts.platform;
241 };
242in
243artifactDerivations