flutter.mkFlutterApp: init
Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
This commit is contained in:
parent
ba83787f0d
commit
fd41185d86
277
pkgs/build-support/flutter/default.nix
Normal file
277
pkgs/build-support/flutter/default.nix
Normal file
|
@ -0,0 +1,277 @@
|
|||
{ flutter
|
||||
, lib
|
||||
, llvmPackages_13
|
||||
, cmake
|
||||
, ninja
|
||||
, pkg-config
|
||||
, wrapGAppsHook
|
||||
, autoPatchelfHook
|
||||
, util-linux
|
||||
, libselinux
|
||||
, libsepol
|
||||
, libthai
|
||||
, libdatrie
|
||||
, libxkbcommon
|
||||
, at-spi2-core
|
||||
, libsecret
|
||||
, jsoncpp
|
||||
, xorg
|
||||
, dbus
|
||||
, gtk3
|
||||
, glib
|
||||
, pcre
|
||||
, libepoxy
|
||||
, stdenvNoCC
|
||||
, cacert
|
||||
, git
|
||||
, dart
|
||||
, nukeReferences
|
||||
, targetPlatform
|
||||
, bash
|
||||
, curl
|
||||
, unzip
|
||||
, which
|
||||
, xz
|
||||
}:
|
||||
|
||||
# absolutely no mac support for now
|
||||
|
||||
args:
|
||||
let
|
||||
pl = n: "##FLUTTER_${n}_PLACEHOLDER_MARKER##";
|
||||
placeholder_deps = pl "DEPS";
|
||||
placeholder_flutter = pl "FLUTTER";
|
||||
fetchAttrs = [ "src" "sourceRoot" "setSourceRoot" "unpackPhase" "patches" ];
|
||||
getAttrsOrNull = names: attrs: lib.genAttrs names (name: if attrs ? ${name} then attrs.${name} else null);
|
||||
flutterDeps = [
|
||||
# flutter deps
|
||||
flutter.unwrapped
|
||||
bash
|
||||
curl
|
||||
flutter.dart
|
||||
git
|
||||
unzip
|
||||
which
|
||||
xz
|
||||
];
|
||||
self =
|
||||
(self: llvmPackages_13.stdenv.mkDerivation (args // {
|
||||
deps = stdenvNoCC.mkDerivation (lib.recursiveUpdate (getAttrsOrNull fetchAttrs args) {
|
||||
name = "${self.name}-deps-flutter-v${flutter.unwrapped.version}-${targetPlatform.system}.tar.gz";
|
||||
|
||||
nativeBuildInputs = flutterDeps ++ [
|
||||
nukeReferences
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
. ${../fetchgit/deterministic-git}
|
||||
|
||||
TMP=$(mktemp -d)
|
||||
|
||||
export HOME="$TMP"
|
||||
export PUB_CACHE=''${PUB_CACHE:-"$HOME/.pub-cache"}
|
||||
export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1
|
||||
|
||||
flutter config --no-analytics &>/dev/null # mute first-run
|
||||
flutter config --enable-linux-desktop
|
||||
flutter packages get
|
||||
flutter build linux || true # so it downloads tools
|
||||
|
||||
RES="$TMP"
|
||||
|
||||
mkdir -p "$RES/f"
|
||||
|
||||
# so we can use lock, diff yaml
|
||||
cp "pubspec.yaml" "$RES"
|
||||
cp "pubspec.lock" "$RES"
|
||||
mv .dart_tool .flutter-plugins .flutter-plugins-dependencies .packages "$RES/f"
|
||||
|
||||
# replace paths with placeholders
|
||||
find "$RES" -type f -exec sed -i \
|
||||
-e s,$TMP,${placeholder_deps},g \
|
||||
-e s,${flutter.unwrapped},${placeholder_flutter},g \
|
||||
{} +
|
||||
|
||||
remove_line_matching() {
|
||||
replace_line_matching "$1" "$2" ""
|
||||
}
|
||||
|
||||
replace_line_matching() {
|
||||
sed "s|.*$2.*|$3|g" -r -i "$1"
|
||||
}
|
||||
|
||||
# nuke nondeterminism
|
||||
|
||||
# clientId is random
|
||||
remove_line_matching "$RES/.flutter" clientId
|
||||
|
||||
# deterministic git repos
|
||||
find "$RES" -iname .git -type d | while read -r repoGit; do
|
||||
make_deterministic_repo "$(dirname "$repoGit")"
|
||||
done
|
||||
|
||||
# dart _fetchedAt, etc
|
||||
DART_DATE=$(date --date="@$SOURCE_DATE_EPOCH" -In | sed "s|,|.|g" | sed "s|+.*||g")
|
||||
find "$RES/.pub-cache" -iname "*.json" -exec sed -r 's|.*_fetchedAt.*| "_fetchedAt": "'"$DART_DATE"'",|g' -i {} +
|
||||
replace_line_matching "$RES/f/.dart_tool/package_config.json" '"generated"' '"generated": "'"$DART_DATE"'",'
|
||||
replace_line_matching "$RES/f/.flutter-plugins-dependencies" '"date_created"' '"date_created": "'"$DART_DATE"'",'
|
||||
remove_line_matching "$RES/f/.packages" "Generated by pub"
|
||||
|
||||
# nuke refs
|
||||
find "$RES" -type f -exec nuke-refs {} +
|
||||
|
||||
# Build a reproducible tar, per instructions at https://reproducible-builds.org/docs/archives/
|
||||
tar --owner=0 --group=0 --numeric-owner --format=gnu \
|
||||
--sort=name --mtime="@$SOURCE_DATE_EPOCH" \
|
||||
-czf "$out" -C "$RES" .
|
||||
'';
|
||||
|
||||
GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
|
||||
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
|
||||
"GIT_PROXY_COMMAND" "NIX_GIT_SSL_CAINFO" "SOCKS_SERVER"
|
||||
];
|
||||
|
||||
# unnecesarry
|
||||
dontFixup = true;
|
||||
|
||||
outputHashAlgo = if self ? vendorHash then null else "sha256";
|
||||
# outputHashMode = "recursive";
|
||||
outputHash = if self ? vendorHash then
|
||||
self.vendorHash
|
||||
else if self ? vendorSha256 then
|
||||
self.vendorSha256
|
||||
else
|
||||
lib.fakeSha256;
|
||||
|
||||
});
|
||||
|
||||
nativeBuildInputs = flutterDeps ++ [
|
||||
# flutter dev tools
|
||||
cmake
|
||||
ninja
|
||||
pkg-config
|
||||
wrapGAppsHook
|
||||
# flutter likes dynamic linking
|
||||
autoPatchelfHook
|
||||
] ++ lib.optionals (args ? nativeBuildInputs) args.nativeBuildInputs;
|
||||
|
||||
buildInputs = [
|
||||
# cmake deps
|
||||
gtk3
|
||||
glib
|
||||
pcre
|
||||
util-linux
|
||||
# also required by cmake, not sure if really needed or dep of all packages
|
||||
libselinux
|
||||
libsepol
|
||||
libthai
|
||||
libdatrie
|
||||
xorg.libXdmcp
|
||||
xorg.libXtst
|
||||
libxkbcommon
|
||||
dbus
|
||||
at-spi2-core
|
||||
libsecret
|
||||
jsoncpp
|
||||
# build deps
|
||||
xorg.libX11
|
||||
# directly required by build
|
||||
libepoxy
|
||||
] ++ lib.optionals (args ? buildInputs) args.buildInputs;
|
||||
|
||||
# TODO: do we need this?
|
||||
NIX_LDFLAGS = "-rpath ${lib.makeLibraryPath self.buildInputs}";
|
||||
NIX_CFLAGS_COMPILE = "-I${xorg.libX11}/include";
|
||||
LD_LIBRARY_PATH = lib.makeLibraryPath self.buildInputs;
|
||||
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
|
||||
# for some reason fluffychat build breaks without this - seems file gets overriden by some tool
|
||||
cp pubspec.yaml pubspec-backup
|
||||
|
||||
# we get this from $depsFolder so disabled for now, but we might need it again once deps are fetched properly
|
||||
# flutter config --no-analytics >/dev/null 2>/dev/null # mute first-run
|
||||
# flutter config --enable-linux-desktop
|
||||
|
||||
# extract deps
|
||||
depsFolder=$(mktemp -d)
|
||||
tar xzf "$deps" -C "$depsFolder"
|
||||
|
||||
# after extracting update paths to point to real paths
|
||||
find "$depsFolder" -type f -exec sed -i \
|
||||
-e s,${placeholder_deps},$depsFolder,g \
|
||||
-e s,${placeholder_flutter},${flutter.unwrapped},g \
|
||||
{} +
|
||||
|
||||
# ensure we're using a lockfile for the right package version
|
||||
if [ -e pubspec.lock ]; then
|
||||
# diff -u pubspec.lock $depsFolder/pubspec.lock
|
||||
true
|
||||
else
|
||||
cp -v "$depsFolder/pubspec.lock" .
|
||||
fi
|
||||
diff -u pubspec.yaml $depsFolder/pubspec.yaml
|
||||
|
||||
mv -v $(find $depsFolder/f -type f) .
|
||||
|
||||
# prepare
|
||||
export HOME=$depsFolder
|
||||
export PUB_CACHE=''${PUB_CACHE:-"$HOME/.pub-cache"}
|
||||
export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1
|
||||
|
||||
# binaries need to be patched
|
||||
autoPatchelf -- "$depsFolder"
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
# for some reason fluffychat build breaks without this - seems file gets overriden by some tool
|
||||
mv pubspec-backup pubspec.yaml
|
||||
mkdir -p build/flutter_assets/fonts
|
||||
|
||||
flutter packages get --offline -v
|
||||
flutter build linux --release -v
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
built=build/linux/*/release/bundle
|
||||
|
||||
mkdir -p $out/bin
|
||||
mv $built $out/app
|
||||
|
||||
for f in $built/data/flutter_assets/assets/*.desktop; 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
|
||||
|
||||
# this confuses autopatchelf hook otherwise
|
||||
rm -rf "$depsFolder"
|
||||
|
||||
# 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
|
||||
'';
|
||||
})) self;
|
||||
in
|
||||
self
|
|
@ -32,6 +32,7 @@
|
|||
, nss
|
||||
, systemd
|
||||
, which
|
||||
, callPackage
|
||||
}:
|
||||
let
|
||||
drvName = "flutter-${version}";
|
||||
|
@ -146,6 +147,8 @@ let
|
|||
};
|
||||
|
||||
in
|
||||
let
|
||||
self = (self:
|
||||
runCommand drvName
|
||||
{
|
||||
startScript = ''
|
||||
|
@ -159,6 +162,9 @@ runCommand drvName
|
|||
passthru = {
|
||||
unwrapped = flutter;
|
||||
inherit dart;
|
||||
mkFlutterApp = callPackage ../../../build-support/flutter {
|
||||
flutter = self;
|
||||
};
|
||||
};
|
||||
meta = with lib; {
|
||||
description = "Flutter is Google's SDK for building mobile, web and desktop with Dart";
|
||||
|
@ -179,4 +185,6 @@ runCommand drvName
|
|||
|
||||
echo -n "$startScript" > $out/bin/${pname}
|
||||
chmod +x $out/bin/${pname}
|
||||
''
|
||||
'') self;
|
||||
in
|
||||
self
|
||||
|
|
Loading…
Reference in a new issue