Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at flake-libs 242 lines 7.8 kB view raw
1{ 2 lib, 3 callPackage, 4 runCommand, 5 makeWrapper, 6 wrapGAppsHook3, 7 buildDartApplication, 8 cacert, 9 glib, 10 flutter, 11 pkg-config, 12 jq, 13 yq, 14}: 15 16# absolutely no mac support for now 17 18{ 19 pubGetScript ? null, 20 flutterBuildFlags ? [ ], 21 targetFlutterPlatform ? "linux", 22 extraWrapProgramArgs ? "", 23 flutterMode ? null, 24 ... 25}@args: 26 27let 28 hasEngine = flutter ? engine && flutter.engine != null && flutter.engine.meta.available; 29 flutterMode = args.flutterMode or (if hasEngine then flutter.engine.runtimeMode else "release"); 30 31 flutterFlags = lib.optional hasEngine "--local-engine host_${flutterMode}${ 32 lib.optionalString (!flutter.engine.isOptimized) "_unopt" 33 }"; 34 35 flutterBuildFlags = 36 [ 37 "--${flutterMode}" 38 ] 39 ++ (args.flutterBuildFlags or [ ]) 40 ++ flutterFlags; 41 42 builderArgs = 43 rec { 44 universal = args // { 45 inherit flutterMode flutterFlags flutterBuildFlags; 46 47 sdkSetupScript = '' 48 # Pub needs SSL certificates. Dart normally looks in a hardcoded path. 49 # https://github.com/dart-lang/sdk/blob/3.1.0/runtime/bin/security_context_linux.cc#L48 50 # 51 # Dart does not respect SSL_CERT_FILE... 52 # https://github.com/dart-lang/sdk/issues/48506 53 # ...and Flutter does not support --root-certs-file, so the path cannot be manually set. 54 # https://github.com/flutter/flutter/issues/56607 55 # https://github.com/flutter/flutter/issues/113594 56 # 57 # libredirect is of no use either, as Flutter does not pass any 58 # environment variables (including LD_PRELOAD) to the Pub process. 59 # 60 # Instead, Flutter is patched to allow the path to the Dart binary used for 61 # Pub commands to be overriden. 62 export NIX_FLUTTER_PUB_DART="${ 63 runCommand "dart-with-certs" { nativeBuildInputs = [ makeWrapper ]; } '' 64 mkdir -p "$out/bin" 65 makeWrapper ${flutter.dart}/bin/dart "$out/bin/dart" \ 66 --add-flags "--root-certs-file=${cacert}/etc/ssl/certs/ca-bundle.crt" 67 '' 68 }/bin/dart" 69 70 export HOME="$NIX_BUILD_TOP" 71 flutter config $flutterFlags --no-analytics &>/dev/null # mute first-run 72 flutter config $flutterFlags --enable-linux-desktop >/dev/null 73 ''; 74 75 pubGetScript = 76 args.pubGetScript 77 or "flutter${lib.optionalString hasEngine " --local-engine $flutterMode"} pub get"; 78 79 sdkSourceBuilders = { 80 # https://github.com/dart-lang/pub/blob/68dc2f547d0a264955c1fa551fa0a0e158046494/lib/src/sdk/flutter.dart#L81 81 "flutter" = 82 name: 83 runCommand "flutter-sdk-${name}" { passthru.packageRoot = "."; } '' 84 for path in '${flutter}/packages/${name}' '${flutter}/bin/cache/pkg/${name}'; do 85 if [ -d "$path" ]; then 86 ln -s "$path" "$out" 87 break 88 fi 89 done 90 91 if [ ! -e "$out" ]; then 92 echo 1>&2 'The Flutter SDK does not contain the requested package: ${name}!' 93 exit 1 94 fi 95 ''; 96 # https://github.com/dart-lang/pub/blob/e1fbda73d1ac597474b82882ee0bf6ecea5df108/lib/src/sdk/dart.dart#L80 97 "dart" = 98 name: 99 runCommand "dart-sdk-${name}" { passthru.packageRoot = "."; } '' 100 for path in '${flutter.dart}/pkg/${name}'; do 101 if [ -d "$path" ]; then 102 ln -s "$path" "$out" 103 break 104 fi 105 done 106 107 if [ ! -e "$out" ]; then 108 echo 1>&2 'The Dart SDK does not contain the requested package: ${name}!' 109 exit 1 110 fi 111 ''; 112 }; 113 114 extraPackageConfigSetup = '' 115 # https://github.com/flutter/flutter/blob/3.13.8/packages/flutter_tools/lib/src/dart/pub.dart#L755 116 if [ "$('${yq}/bin/yq' '.flutter.generate // false' pubspec.yaml)" = "true" ]; then 117 export TEMP_PACKAGES=$(mktemp) 118 '${jq}/bin/jq' '.packages |= . + [{ 119 name: "flutter_gen", 120 rootUri: "flutter_gen", 121 languageVersion: "2.12", 122 }]' "$out" > "$TEMP_PACKAGES" 123 cp "$TEMP_PACKAGES" "$out" 124 rm "$TEMP_PACKAGES" 125 unset TEMP_PACKAGES 126 fi 127 ''; 128 }; 129 130 linux = universal // { 131 outputs = universal.outputs or [ ] ++ [ "debug" ]; 132 133 nativeBuildInputs = (universal.nativeBuildInputs or [ ]) ++ [ 134 wrapGAppsHook3 135 136 # Flutter requires pkg-config for Linux desktop support, and many plugins 137 # attempt to use it. 138 # 139 # It is available to the `flutter` tool through its wrapper, but it must be 140 # added here as well so the setup hook adds plugin dependencies to the 141 # pkg-config search paths. 142 pkg-config 143 ]; 144 145 buildInputs = (universal.buildInputs or [ ]) ++ [ glib ]; 146 147 dontDartBuild = true; 148 buildPhase = 149 universal.buildPhase or '' 150 runHook preBuild 151 152 mkdir -p build/flutter_assets/fonts 153 154 flutter build linux -v --split-debug-info="$debug" $flutterBuildFlags 155 156 runHook postBuild 157 ''; 158 159 dontDartInstall = true; 160 installPhase = 161 universal.installPhase or '' 162 runHook preInstall 163 164 built=build/linux/*/$flutterMode/bundle 165 166 mkdir -p $out/bin 167 mkdir -p $out/app 168 mv $built $out/app/$pname 169 170 for f in $(find $out/app/$pname -iname "*.desktop" -type f); do 171 install -D $f $out/share/applications/$(basename $f) 172 done 173 174 for f in $(find $out/app/$pname -maxdepth 1 -type f); do 175 ln -s $f $out/bin/$(basename $f) 176 done 177 178 # make *.so executable 179 find $out/app/$pname -iname "*.so" -type f -exec chmod +x {} + 180 181 # remove stuff like /build/source/packages/ubuntu_desktop_installer/linux/flutter/ephemeral 182 for f in $(find $out/app/$pname -executable -type f); do 183 if patchelf --print-rpath "$f" | grep /build; then # this ignores static libs (e,g. libapp.so) also 184 echo "strip RPath of $f" 185 newrp=$(patchelf --print-rpath $f | sed -r "s|/build.*ephemeral:||g" | sed -r "s|/build.*profile:||g") 186 patchelf --set-rpath "$newrp" "$f" 187 fi 188 done 189 190 runHook postInstall 191 ''; 192 193 dontWrapGApps = true; 194 extraWrapProgramArgs = '' 195 ''${gappsWrapperArgs[@]} \ 196 ${extraWrapProgramArgs} 197 ''; 198 }; 199 200 web = universal // { 201 dontDartBuild = true; 202 buildPhase = 203 universal.buildPhase or '' 204 runHook preBuild 205 206 mkdir -p build/flutter_assets/fonts 207 208 flutter build web -v $flutterBuildFlags 209 210 runHook postBuild 211 ''; 212 213 dontDartInstall = true; 214 installPhase = 215 universal.installPhase or '' 216 runHook preInstall 217 218 cp -r build/web "$out" 219 220 runHook postInstall 221 ''; 222 }; 223 } 224 .${targetFlutterPlatform} or (throw "Unsupported Flutter host platform: ${targetFlutterPlatform}"); 225 226 minimalFlutter = flutter.override { 227 supportedTargetFlutterPlatforms = [ 228 "universal" 229 targetFlutterPlatform 230 ]; 231 }; 232 233 buildAppWith = flutter: buildDartApplication.override { dart = flutter; }; 234in 235buildAppWith minimalFlutter ( 236 builderArgs 237 // { 238 passthru = builderArgs.passthru or { } // { 239 multiShell = buildAppWith flutter builderArgs; 240 }; 241 } 242)