6cecfa12b5
flutter: Use wrapGAppsHook
189 lines
5.8 KiB
Nix
189 lines
5.8 KiB
Nix
{ lib
|
|
, callPackage
|
|
, stdenvNoCC
|
|
, runCommand
|
|
, makeWrapper
|
|
, wrapGAppsHook
|
|
, llvmPackages_13
|
|
, cacert
|
|
, glib
|
|
, flutter
|
|
, jq
|
|
}:
|
|
|
|
# absolutely no mac support for now
|
|
|
|
{ pubGetScript ? "flutter pub get"
|
|
, flutterBuildFlags ? [ ]
|
|
, runtimeDependencies ? [ ]
|
|
, customPackageOverrides ? { }
|
|
, autoDepsList ? false
|
|
, depsListFile ? null
|
|
, vendorHash ? ""
|
|
, pubspecLockFile ? null
|
|
, nativeBuildInputs ? [ ]
|
|
, preUnpack ? ""
|
|
, postFixup ? ""
|
|
, extraWrapProgramArgs ? ""
|
|
, ...
|
|
}@args:
|
|
let
|
|
flutterSetupScript = ''
|
|
# Pub needs SSL certificates. Dart normally looks in a hardcoded path.
|
|
# https://github.com/dart-lang/sdk/blob/3.1.0/runtime/bin/security_context_linux.cc#L48
|
|
#
|
|
# Dart does not respect SSL_CERT_FILE...
|
|
# https://github.com/dart-lang/sdk/issues/48506
|
|
# ...and Flutter does not support --root-certs-file, so the path cannot be manually set.
|
|
# https://github.com/flutter/flutter/issues/56607
|
|
# https://github.com/flutter/flutter/issues/113594
|
|
#
|
|
# libredirect is of no use either, as Flutter does not pass any
|
|
# environment variables (including LD_PRELOAD) to the Pub process.
|
|
#
|
|
# Instead, Flutter is patched to allow the path to the Dart binary used for
|
|
# Pub commands to be overriden.
|
|
export NIX_FLUTTER_PUB_DART="${runCommand "dart-with-certs" { nativeBuildInputs = [ makeWrapper ]; } ''
|
|
mkdir -p "$out/bin"
|
|
makeWrapper ${flutter.dart}/bin/dart "$out/bin/dart" \
|
|
--add-flags "--root-certs-file=${cacert}/etc/ssl/certs/ca-bundle.crt"
|
|
''}/bin/dart"
|
|
|
|
export HOME="$NIX_BUILD_TOP"
|
|
flutter config --no-analytics &>/dev/null # mute first-run
|
|
flutter config --enable-linux-desktop >/dev/null
|
|
'';
|
|
|
|
deps = callPackage ../dart/fetch-dart-deps { dart = flutter; } {
|
|
sdkSetupScript = flutterSetupScript;
|
|
inherit pubGetScript vendorHash pubspecLockFile;
|
|
buildDrvArgs = args;
|
|
};
|
|
|
|
baseDerivation = llvmPackages_13.stdenv.mkDerivation (finalAttrs: args // {
|
|
inherit flutterBuildFlags runtimeDependencies;
|
|
|
|
outputs = [ "out" "debug" ];
|
|
|
|
nativeBuildInputs = [
|
|
makeWrapper
|
|
deps
|
|
flutter
|
|
jq
|
|
glib
|
|
wrapGAppsHook
|
|
] ++ nativeBuildInputs;
|
|
|
|
dontWrapGApps = true;
|
|
|
|
preUnpack = ''
|
|
${lib.optionalString (!autoDepsList) ''
|
|
if ! { [ '${lib.boolToString (depsListFile != null)}' = 'true' ] ${lib.optionalString (depsListFile != null) "&& cmp -s <(jq -Sc . '${depsListFile}') <(jq -Sc . '${finalAttrs.passthru.depsListFile}')"}; }; then
|
|
echo 1>&2 -e '\nThe dependency list file was either not given or differs from the expected result.' \
|
|
'\nPlease choose one of the following solutions:' \
|
|
'\n - Duplicate the following file and pass it to the depsListFile argument.' \
|
|
'\n ${finalAttrs.passthru.depsListFile}' \
|
|
'\n - Set autoDepsList to true (not supported by Hydra or permitted in Nixpkgs)'.
|
|
exit 1
|
|
fi
|
|
''}
|
|
|
|
${preUnpack}
|
|
'';
|
|
|
|
configurePhase = ''
|
|
runHook preConfigure
|
|
|
|
${flutterSetupScript}
|
|
|
|
runHook postConfigure
|
|
'';
|
|
|
|
buildPhase = ''
|
|
runHook preBuild
|
|
|
|
mkdir -p build/flutter_assets/fonts
|
|
|
|
doPubGet flutter pub get --offline -v
|
|
flutter build linux -v --release --split-debug-info="$debug" ${builtins.concatStringsSep " " (map (flag: "\"${flag}\"") finalAttrs.flutterBuildFlags)}
|
|
|
|
runHook postBuild
|
|
'';
|
|
|
|
installPhase = ''
|
|
runHook preInstall
|
|
|
|
built=build/linux/*/release/bundle
|
|
|
|
mkdir -p $out/bin
|
|
mv $built $out/app
|
|
|
|
for f in $(find $out/app -iname "*.desktop" -type f); do
|
|
install -D $f $out/share/applications/$(basename $f)
|
|
done
|
|
|
|
for f in $(find $out/app -maxdepth 1 -type f); do
|
|
ln -s $f $out/bin/$(basename $f)
|
|
done
|
|
|
|
# make *.so executable
|
|
find $out/app -iname "*.so" -type f -exec chmod +x {} +
|
|
|
|
# remove stuff like /build/source/packages/ubuntu_desktop_installer/linux/flutter/ephemeral
|
|
for f in $(find $out/app -executable -type f); do
|
|
if patchelf --print-rpath "$f" | grep /build; then # this ignores static libs (e,g. libapp.so) also
|
|
echo "strip RPath of $f"
|
|
newrp=$(patchelf --print-rpath $f | sed -r "s|/build.*ephemeral:||g" | sed -r "s|/build.*profile:||g")
|
|
patchelf --set-rpath "$newrp" "$f"
|
|
fi
|
|
done
|
|
|
|
runHook postInstall
|
|
'';
|
|
|
|
postFixup = ''
|
|
# Add runtime library dependencies to the LD_LIBRARY_PATH.
|
|
# For some reason, the RUNPATH of the executable is not used to load dynamic libraries in dart:ffi with DynamicLibrary.open().
|
|
#
|
|
# This could alternatively be fixed with patchelf --add-needed, but this would cause all the libraries to be opened immediately,
|
|
# which is not what application authors expect.
|
|
for f in "$out"/bin/*; do
|
|
wrapProgram "$f" \
|
|
--suffix LD_LIBRARY_PATH : '${lib.makeLibraryPath finalAttrs.runtimeDependencies}' \
|
|
''${gappsWrapperArgs[@]} \
|
|
${extraWrapProgramArgs}
|
|
done
|
|
|
|
${postFixup}
|
|
'';
|
|
|
|
passthru = (args.passthru or {}) // {
|
|
inherit (deps) depsListFile;
|
|
};
|
|
});
|
|
|
|
packageOverrideRepository = (callPackage ../../development/compilers/flutter/package-overrides { }) // customPackageOverrides;
|
|
productPackages = builtins.filter (package: package.kind != "dev")
|
|
(if autoDepsList
|
|
then lib.importJSON deps.depsListFile
|
|
else
|
|
if depsListFile == null
|
|
then [ ]
|
|
else lib.importJSON depsListFile);
|
|
in
|
|
builtins.foldl'
|
|
(prev: package:
|
|
if packageOverrideRepository ? ${package.name}
|
|
then
|
|
prev.overrideAttrs
|
|
(packageOverrideRepository.${package.name} {
|
|
inherit (package)
|
|
name
|
|
version
|
|
kind
|
|
source
|
|
dependencies;
|
|
})
|
|
else prev)
|
|
baseDerivation
|
|
productPackages
|