mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-11-17 06:06:13 +03:00
flutter.buildFlutterApplication: Refactor dependency setup as a standalone derivation with an output hook
This allows anything that needs to build a Dart application (such as a future `buildDartApplication` function) to use the same setup.
This commit is contained in:
parent
607a57d48e
commit
915a6779fc
133
pkgs/build-support/dart/fetch-dart-deps/default.nix
Normal file
133
pkgs/build-support/dart/fetch-dart-deps/default.nix
Normal file
@ -0,0 +1,133 @@
|
||||
{ stdenvNoCC
|
||||
, lib
|
||||
, makeSetupHook
|
||||
, dart
|
||||
, git
|
||||
, cacert
|
||||
}:
|
||||
|
||||
{
|
||||
# The output hash of the dependencies for this project.
|
||||
vendorHash ? ""
|
||||
# Commands to run once before using Dart or pub.
|
||||
, sdkSetupScript ? ""
|
||||
# Commands to run to populate the pub cache.
|
||||
, pubGetScript ? "dart pub get"
|
||||
# Arguments used in the derivation that builds the Dart package.
|
||||
# Passing these is recommended to ensure that the same steps are made to prepare the sources in both this
|
||||
# derivation and the one that builds the Dart package.
|
||||
, buildDrvArgs ? { }
|
||||
, ...
|
||||
}@args:
|
||||
|
||||
# This is a fixed-output derivation and setup hook that can be used to fetch dependencies for Dart projects.
|
||||
# It is designed to be placed in the nativeBuildInputs of a derivation that builds a Dart package.
|
||||
# Providing the buildDrvArgs argument is highly recommended.
|
||||
let
|
||||
buildDrvInheritArgNames = [
|
||||
"name"
|
||||
"pname"
|
||||
"version"
|
||||
"src"
|
||||
"sourceRoot"
|
||||
"setSourceRoot"
|
||||
"preUnpack"
|
||||
"unpackPhase"
|
||||
"unpackCmd"
|
||||
"postUnpack"
|
||||
"prePatch"
|
||||
"patchPhase"
|
||||
"patches"
|
||||
"patchFlags"
|
||||
"postPatch"
|
||||
];
|
||||
|
||||
buildDrvInheritArgs = builtins.foldl'
|
||||
(attrs: arg:
|
||||
if buildDrvArgs ? ${arg}
|
||||
then attrs // { ${arg} = buildDrvArgs.${arg}; }
|
||||
else attrs)
|
||||
{ }
|
||||
buildDrvInheritArgNames;
|
||||
|
||||
drvArgs = buildDrvInheritArgs // (removeAttrs args [ "buildDrvArgs" ]);
|
||||
name = (if drvArgs ? name then drvArgs.name else "${drvArgs.pname}-${drvArgs.version}");
|
||||
|
||||
deps =
|
||||
# This
|
||||
stdenvNoCC.mkDerivation ({
|
||||
name = "${name}-dart-deps";
|
||||
|
||||
nativeBuildInputs = [
|
||||
dart
|
||||
git
|
||||
];
|
||||
|
||||
# avoid pub phase
|
||||
dontBuild = true;
|
||||
|
||||
configurePhase = ''
|
||||
# Configure the package cache
|
||||
export PUB_CACHE="$out/cache/.pub-cache"
|
||||
mkdir -p "$PUB_CACHE"
|
||||
|
||||
${sdkSetupScript}
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
${pubGetScript}
|
||||
|
||||
# so we can use lock, diff yaml
|
||||
mkdir -p "$out/pubspec"
|
||||
cp "pubspec.yaml" "$out/pubspec"
|
||||
cp "pubspec.lock" "$out/pubspec"
|
||||
|
||||
# nuke nondeterminism
|
||||
|
||||
# Remove Git directories in the Git package cache - these are rarely used by Pub,
|
||||
# which instead maintains a corresponsing mirror and clones cached packages through it.
|
||||
find "$PUB_CACHE" -name .git -type d -prune -exec rm -rf {} +
|
||||
|
||||
# Remove continuously updated package metadata caches
|
||||
rm -rf "$PUB_CACHE"/hosted/*/.cache # Not pinned by pubspec.lock
|
||||
rm -rf "$PUB_CACHE"/git/cache/*/* # Recreate this on the other end. See: https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/source/git.dart#L531
|
||||
|
||||
# Miscelaneous transient package cache files
|
||||
rm -f "$PUB_CACHE"/README.md # May change with different Dart versions
|
||||
rm -rf "$PUB_CACHE"/_temp # https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/system_cache.dart#L131
|
||||
rm -rf "$PUB_CACHE"/log # https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/command.dart#L348
|
||||
'';
|
||||
|
||||
GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
|
||||
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
|
||||
"GIT_PROXY_COMMAND"
|
||||
"NIX_GIT_SSL_CAINFO"
|
||||
"SOCKS_SERVER"
|
||||
];
|
||||
|
||||
# Patching shebangs introduces input references to this fixed-output derivation.
|
||||
# This triggers a bug in Nix, causing the output path to change unexpectedly.
|
||||
# https://github.com/NixOS/nix/issues/6660
|
||||
dontPatchShebangs = true;
|
||||
|
||||
# The following operations are not generally useful for this derivation.
|
||||
# If a package does contain some native components used at build time,
|
||||
# please file an issue.
|
||||
dontStrip = true;
|
||||
dontMoveSbin = true;
|
||||
dontPatchELF = true;
|
||||
|
||||
outputHashAlgo = "sha256";
|
||||
outputHashMode = "recursive";
|
||||
outputHash = if vendorHash != "" then vendorHash else lib.fakeSha256;
|
||||
} // drvArgs);
|
||||
in
|
||||
(makeSetupHook {
|
||||
# The setup hook should not be part of the fixed-output derivation.
|
||||
# Updates to the hook script should not change vendor hashes, and it won't
|
||||
# work at all anyway due to https://github.com/NixOS/nix/issues/6660.
|
||||
name = "${name}-dart-deps-setup-hook";
|
||||
substitutions = { inherit deps; };
|
||||
}) ./setup-hook.sh
|
42
pkgs/build-support/dart/fetch-dart-deps/setup-hook.sh
Normal file
42
pkgs/build-support/dart/fetch-dart-deps/setup-hook.sh
Normal file
@ -0,0 +1,42 @@
|
||||
preConfigureHooks+=(_setupPubCache)
|
||||
|
||||
_setupPubCache() {
|
||||
deps="@deps@"
|
||||
|
||||
# Configure the package cache.
|
||||
export PUB_CACHE="$(mktemp -d)"
|
||||
mkdir -p "$PUB_CACHE"
|
||||
|
||||
if [ -d "$deps/cache/.pub-cache/git" ]; then
|
||||
# Link the Git package cache.
|
||||
mkdir -p "$PUB_CACHE/git"
|
||||
ln -s "$deps/cache/.pub-cache/git"/* "$PUB_CACHE/git"
|
||||
|
||||
# Recreate the internal Git cache subdirectory.
|
||||
# See: https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/source/git.dart#L339)
|
||||
# Blank repositories are created instead of attempting to match the cache mirrors to checkouts.
|
||||
# This is not an issue, as pub does not need the mirrors in the Flutter build process.
|
||||
rm "$PUB_CACHE/git/cache" && mkdir "$PUB_CACHE/git/cache"
|
||||
for mirror in $(ls -A "$deps/cache/.pub-cache/git/cache"); do
|
||||
git --git-dir="$PUB_CACHE/git/cache/$mirror" init --bare --quiet
|
||||
done
|
||||
fi
|
||||
|
||||
# Link the remaining package cache directories.
|
||||
# At this point, any subdirectories that must be writable must have been taken care of.
|
||||
for file in $(comm -23 <(ls -A "$deps/cache/.pub-cache") <(ls -A "$PUB_CACHE")); do
|
||||
ln -s "$deps/cache/.pub-cache/$file" "$PUB_CACHE/$file"
|
||||
done
|
||||
|
||||
# ensure we're using a lockfile for the right package version
|
||||
if [ -e pubspec.lock ]; then
|
||||
# FIXME: currently this is broken. in theory this should not break, but flutter has it's own way of doing things.
|
||||
# diff -u pubspec.lock "$deps/pubspec/pubspec.lock"
|
||||
true
|
||||
else
|
||||
cp -v "$deps/pubspec/pubspec.lock" .
|
||||
# Sometimes the pubspec.lock will get opened in write mode, even when offline.
|
||||
chmod u+w pubspec.lock
|
||||
fi
|
||||
diff -u pubspec.yaml "$deps/pubspec/pubspec.yaml"
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
{ lib
|
||||
, callPackage
|
||||
, stdenvNoCC
|
||||
, llvmPackages_13
|
||||
, cacert
|
||||
@ -8,135 +9,35 @@
|
||||
|
||||
# absolutely no mac support for now
|
||||
|
||||
args:
|
||||
{ pubGetScript ? "flutter pub get"
|
||||
, vendorHash
|
||||
, nativeBuildInputs ? [ ]
|
||||
, ...
|
||||
}@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);
|
||||
flutterSetupScript = ''
|
||||
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;
|
||||
buildDrvArgs = args;
|
||||
};
|
||||
self =
|
||||
(self: llvmPackages_13.stdenv.mkDerivation (args // {
|
||||
deps = stdenvNoCC.mkDerivation (lib.recursiveUpdate (getAttrsOrNull fetchAttrs args) {
|
||||
name = "${self.name}-deps-flutter";
|
||||
|
||||
nativeBuildInputs = [
|
||||
flutter
|
||||
git
|
||||
];
|
||||
|
||||
# avoid pub phase
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
TMP=$(mktemp -d)
|
||||
export HOME="$TMP"
|
||||
|
||||
# Configure the package cache
|
||||
export PUB_CACHE="$out/cache/.pub-cache"
|
||||
mkdir -p "$PUB_CACHE"
|
||||
|
||||
flutter config --no-analytics &>/dev/null # mute first-run
|
||||
flutter config --enable-linux-desktop
|
||||
flutter packages get
|
||||
${lib.optionalString (args ? flutterExtraFetchCommands) args.flutterExtraFetchCommands}
|
||||
|
||||
# so we can use lock, diff yaml
|
||||
mkdir -p "$out/pubspec"
|
||||
cp "pubspec.yaml" "$out/pubspec"
|
||||
cp "pubspec.lock" "$out/pubspec"
|
||||
|
||||
# nuke nondeterminism
|
||||
|
||||
# Remove Git directories in the Git package cache - these are rarely used by Pub,
|
||||
# which instead maintains a corresponsing mirror and clones cached packages through it.
|
||||
find "$PUB_CACHE" -name .git -type d -prune -exec rm -rf {} +
|
||||
|
||||
# Remove continuously updated package metadata caches
|
||||
rm -rf "$PUB_CACHE"/hosted/*/.cache # Not pinned by pubspec.lock
|
||||
rm -rf "$PUB_CACHE"/git/cache/*/* # Recreate this on the other end. See: https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/source/git.dart#L531
|
||||
|
||||
# Miscelaneous transient package cache files
|
||||
rm -f "$PUB_CACHE"/README.md # May change with different Dart versions
|
||||
rm -rf "$PUB_CACHE"/_temp # https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/system_cache.dart#L131
|
||||
rm -rf "$PUB_CACHE"/log # https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/command.dart#L348
|
||||
'';
|
||||
|
||||
GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
|
||||
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
|
||||
"GIT_PROXY_COMMAND" "NIX_GIT_SSL_CAINFO" "SOCKS_SERVER"
|
||||
];
|
||||
|
||||
# unnecesarry
|
||||
dontFixup = true;
|
||||
|
||||
# Patching shebangs introduces input references to this fixed-output derivation.
|
||||
# This triggers a bug in Nix, causing the output path to change unexpectedly.
|
||||
# https://github.com/NixOS/nix/issues/6660
|
||||
dontPatchShebangs = 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 = [
|
||||
deps
|
||||
flutter
|
||||
git
|
||||
] ++ lib.optionals (args ? nativeBuildInputs) args.nativeBuildInputs;
|
||||
|
||||
buildInputs = lib.optionals (args ? buildInputs) args.buildInputs;
|
||||
] ++ nativeBuildInputs;
|
||||
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
|
||||
TMP=$(mktemp -d)
|
||||
export HOME="$TMP"
|
||||
|
||||
flutter config --no-analytics &>/dev/null # mute first-run
|
||||
flutter config --enable-linux-desktop
|
||||
|
||||
# Configure the package cache
|
||||
export PUB_CACHE="$TMP/.pub-cache"
|
||||
mkdir -p "$PUB_CACHE"
|
||||
|
||||
# Link the Git package cache.
|
||||
mkdir -p "$PUB_CACHE/git"
|
||||
ln -s "$deps/cache/.pub-cache/git"/* "$PUB_CACHE/git"
|
||||
|
||||
# Recreate the internal Git cache subdirectory.
|
||||
# See: https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/source/git.dart#L339)
|
||||
# Blank repositories are created instead of attempting to match the cache mirrors to checkouts.
|
||||
# This is not an issue, as pub does not need the mirrors in the Flutter build process.
|
||||
rm "$PUB_CACHE/git/cache" && mkdir "$PUB_CACHE/git/cache"
|
||||
for mirror in $(ls -A "$deps/cache/.pub-cache/git/cache"); do
|
||||
git --git-dir="$PUB_CACHE/git/cache/$mirror" init --bare --quiet
|
||||
done
|
||||
|
||||
# Link the remaining package cache directories.
|
||||
# At this point, any subdirectories that must be writable must have been taken care of.
|
||||
for file in $(comm -23 <(ls -A "$deps/cache/.pub-cache") <(ls -A "$PUB_CACHE")); do
|
||||
ln -s "$deps/cache/.pub-cache/$file" "$PUB_CACHE/$file"
|
||||
done
|
||||
|
||||
# ensure we're using a lockfile for the right package version
|
||||
if [ -e pubspec.lock ]; then
|
||||
# FIXME: currently this is broken. in theory this should not break, but flutter has it's own way of doing things.
|
||||
# diff -u pubspec.lock "$deps/pubspec/pubspec.lock"
|
||||
true
|
||||
else
|
||||
cp -v "$deps/pubspec/pubspec.lock" .
|
||||
# Sometimes the pubspec.lock will get opened in write mode, even when offline.
|
||||
chmod u+w pubspec.lock
|
||||
fi
|
||||
diff -u pubspec.yaml "$deps/pubspec/pubspec.yaml"
|
||||
${flutterSetupScript}
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
Loading…
Reference in New Issue
Block a user