about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2024-01-07 14:58:29 +0100
committerAlyssa Ross <hi@alyssa.is>2024-01-07 14:58:29 +0100
commitad899504860973e98351c922ecb934595f2c0f19 (patch)
treeb1260cc90947e834af941c6cb6aed51dc68f50b5 /nixpkgs/pkgs/build-support
parentf34a1b70eb86e4a63cfb88ea460345bb1aed88e3 (diff)
parentdc676e1b5014069a2b06e236242e2f0990384934 (diff)
downloadnixlib-ad899504860973e98351c922ecb934595f2c0f19.tar
nixlib-ad899504860973e98351c922ecb934595f2c0f19.tar.gz
nixlib-ad899504860973e98351c922ecb934595f2c0f19.tar.bz2
nixlib-ad899504860973e98351c922ecb934595f2c0f19.tar.lz
nixlib-ad899504860973e98351c922ecb934595f2c0f19.tar.xz
nixlib-ad899504860973e98351c922ecb934595f2c0f19.tar.zst
nixlib-ad899504860973e98351c922ecb934595f2c0f19.zip
Merge branch 'nixos-unstable-small' of https://github.com/NixOS/nixpkgs
Diffstat (limited to 'nixpkgs/pkgs/build-support')
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix129
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/generators.nix74
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-config-hook.sh57
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-fixup-hook.sh9
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-install-hook.sh6
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/dart/fetch-dart-deps/default.nix248
-rw-r--r--nixpkgs/pkgs/build-support/dart/fetch-dart-deps/setup-hook.sh46
-rw-r--r--nixpkgs/pkgs/build-support/dart/pub2nix/default.nix6
-rw-r--r--nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix68
-rw-r--r--nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix119
-rw-r--r--nixpkgs/pkgs/build-support/fetchpijul/default.nix7
-rw-r--r--nixpkgs/pkgs/build-support/flutter/default.nix53
13 files changed, 452 insertions, 372 deletions
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix b/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
index 2cb193ac6f16..e8e6bd16b168 100644
--- a/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
@@ -1,7 +1,25 @@
-{ lib, stdenv, callPackage, fetchDartDeps, runCommand, symlinkJoin, writeText, dartHooks, makeWrapper, dart, cacert, nodejs, darwin, jq }:
+{ lib
+, stdenv
+, callPackage
+, writeText
+, pub2nix
+, dartHooks
+, makeWrapper
+, dart
+, nodejs
+, darwin
+, jq
+}:
 
-{ sdkSetupScript ? ""
-, pubGetScript ? "dart pub get"
+{ src
+, sourceRoot ? "source"
+, packageRoot ? (lib.removePrefix "/" (lib.removePrefix "source" sourceRoot))
+, gitHashes ? { }
+, sdkSourceBuilders ? { }
+, customSourceBuilders ? { }
+
+, sdkSetupScript ? ""
+, extraPackageConfigSetup ? ""
 
   # Output type to produce. Can be any kind supported by dart
   # https://dart.dev/tools/dart-compile#types-of-output
@@ -26,47 +44,52 @@
 
 , runtimeDependencies ? [ ]
 , extraWrapProgramArgs ? ""
-, customPackageOverrides ? { }
-, autoDepsList ? false
-, depsListFile ? null
-, pubspecLockFile ? null
-, vendorHash ? ""
+, pubspecLock
 , ...
 }@args:
 
 let
-  dartDeps = (fetchDartDeps.override {
-    dart = symlinkJoin {
-      name = "dart-sdk-fod";
-      paths = [
-        (runCommand "dart-fod" { nativeBuildInputs = [ makeWrapper ]; } ''
-          mkdir -p "$out/bin"
-          makeWrapper "${dart}/bin/dart" "$out/bin/dart" \
-            --add-flags "--root-certs-file=${cacert}/etc/ssl/certs/ca-bundle.crt"
-        '')
-        dart
-      ];
+  generators = callPackage ./generators.nix { inherit dart; } { buildDrvArgs = args; };
+
+  pubspecLockFile = builtins.toJSON pubspecLock;
+  pubspecLockData = pub2nix.readPubspecLock { inherit src packageRoot pubspecLock gitHashes sdkSourceBuilders customSourceBuilders; };
+  packageConfig = generators.linkPackageConfig {
+    packageConfig = pub2nix.generatePackageConfig {
+      pname = if args.pname != null then "${args.pname}-${args.version}" else null;
+
+      dependencies =
+        # Ideally, we'd only include the main dependencies and their transitive
+        # dependencies.
+        #
+        # The pubspec.lock file does not contain information about where
+        # transitive dependencies come from, though, and it would be weird to
+        # include the transitive dependencies of dev and override dependencies
+        # without including the dev and override dependencies themselves.
+        builtins.concatLists (builtins.attrValues pubspecLockData.dependencies);
+
+      inherit (pubspecLockData) dependencySources;
     };
-  }) {
-    buildDrvArgs = args;
-    inherit sdkSetupScript pubGetScript vendorHash pubspecLockFile;
+    extraSetupCommands = extraPackageConfigSetup;
   };
+
   inherit (dartHooks.override { inherit dart; }) dartConfigHook dartBuildHook dartInstallHook dartFixupHook;
 
-  baseDerivation = stdenv.mkDerivation (finalAttrs: args // {
-    inherit sdkSetupScript pubGetScript dartCompileCommand dartOutputType
-      dartRuntimeCommand dartCompileFlags dartJitFlags runtimeDependencies;
+  baseDerivation = stdenv.mkDerivation (finalAttrs: (builtins.removeAttrs args [ "gitHashes" "sdkSourceBuilders" "pubspecLock" "customSourceBuilders" ]) // {
+    inherit pubspecLockFile packageConfig sdkSetupScript
+      dartCompileCommand dartOutputType dartRuntimeCommand dartCompileFlags
+      dartJitFlags;
+
+    outputs = args.outputs or [ ] ++ [ "out" "pubcache" ];
 
     dartEntryPoints =
       if (dartEntryPoints != null)
       then writeText "entrypoints.json" (builtins.toJSON dartEntryPoints)
       else null;
 
-    runtimeDependencyLibraryPath = lib.makeLibraryPath finalAttrs.runtimeDependencies;
+    runtimeDependencies = map lib.getLib runtimeDependencies;
 
     nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
       dart
-      dartDeps
       dartConfigHook
       dartBuildHook
       dartInstallHook
@@ -75,55 +98,27 @@ let
       jq
     ] ++ lib.optionals stdenv.isDarwin [
       darwin.sigtool
-    ];
-
-    preUnpack = ''
-      ${lib.optionalString (!autoDepsList) ''
-        if ! { [ '${lib.boolToString (depsListFile != null)}' = 'true' ] ${lib.optionalString (depsListFile != null) "&& cmp -s <(jq -Sc . '${depsListFile}') <(jq -Sc . '${finalAttrs.passthru.dartDeps.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.dartDeps.depsListFile}' \
-                      '\n - Set autoDepsList to true (not supported by Hydra or permitted in Nixpkgs)'.
-          exit 1
-        fi
-      ''}
-      ${args.preUnpack or ""}
+    ] ++
+      # Ensure that we inherit the propagated build inputs from the dependencies.
+      builtins.attrValues pubspecLockData.dependencySources;
+
+    preConfigure = args.preConfigure or "" + ''
+      ln -sf "$pubspecLockFilePath" pubspec.lock
     '';
 
     # When stripping, it seems some ELF information is lost and the dart VM cli
     # runs instead of the expected program. Don't strip if it's an exe output.
     dontStrip = args.dontStrip or (dartOutputType == "exe");
 
-    passthru = { inherit dartDeps; } // (args.passthru or { });
+    passAsFile = [ "pubspecLockFile" ];
+
+    passthru = {
+      pubspecLock = pubspecLockData;
+    } // (args.passthru or { });
 
     meta = (args.meta or { }) // { platforms = args.meta.platforms or dart.meta.platforms; };
   });
-
-  packageOverrideRepository = (callPackage ../../../development/compilers/dart/package-overrides { }) // customPackageOverrides;
-  productPackages = builtins.filter (package: package.kind != "dev")
-    (if autoDepsList
-    then lib.importJSON dartDeps.depsListFile
-    else
-      if depsListFile == null
-      then [ ]
-      else lib.importJSON depsListFile);
 in
 assert !(builtins.isString dartOutputType && dartOutputType != "") ->
 throw "dartOutputType must be a non-empty string";
-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
+baseDerivation
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/generators.nix b/nixpkgs/pkgs/build-support/dart/build-dart-application/generators.nix
new file mode 100644
index 000000000000..f01a09305dba
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/generators.nix
@@ -0,0 +1,74 @@
+{ lib
+, stdenvNoCC
+, dart
+, dartHooks
+, jq
+, yq
+, cacert
+}:
+
+{
+  # 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 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}");
+
+  # Adds the root package to a dependency package_config.json file from pub2nix.
+  linkPackageConfig = { packageConfig, extraSetupCommands ? "" }: stdenvNoCC.mkDerivation (drvArgs // {
+    name = "${name}-package-config-with-root.json";
+
+    nativeBuildInputs = drvArgs.nativeBuildInputs or [ ] ++ args.nativeBuildInputs or [ ] ++ [ jq yq ];
+
+    dontBuild = true;
+
+    installPhase = ''
+      runHook preInstall
+
+      packageName="$(yq --raw-output .name pubspec.yaml)"
+      jq --arg name "$packageName" '.packages |= . + [{ name: $name, rootUri: "../", packageUri: "lib/" }]' '${packageConfig}' > "$out"
+      ${extraSetupCommands}
+
+      runHook postInstall
+    '';
+  });
+in
+{
+  inherit
+    linkPackageConfig;
+}
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-config-hook.sh b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-config-hook.sh
index f22d7d2ce64d..50754a7b56d4 100644
--- a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-config-hook.sh
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-config-hook.sh
@@ -7,7 +7,62 @@ dartConfigHook() {
     eval "$sdkSetupScript"
 
     echo "Installing dependencies"
-    eval doPubGet "$pubGetScript" --offline
+    mkdir -p .dart_tool
+    cp "$packageConfig" .dart_tool/package_config.json
+
+    packagePath() {
+        jq --raw-output --arg name "$1" '.packages.[] | select(.name == $name) .rootUri | sub("file://"; "")' .dart_tool/package_config.json
+    }
+
+    # Runs a Dart executable from a package with a custom path.
+    #
+    # Usage:
+    # packageRunCustom <package> [executable] [bin_dir]
+    #
+    # By default, [bin_dir] is "bin", and [executable] is <package>.
+    # i.e. `packageRunCustom build_runner` is equivalent to `packageRunCustom build_runner build_runner bin`, which runs `bin/build_runner.dart` from the build_runner package.
+    packageRunCustom() {
+        local args=()
+        local passthrough=()
+
+        while [ $# -gt 0 ]; do
+            if [ "$1" != "--" ]; then
+                args+=("$1")
+                shift
+            else
+                shift
+                passthrough=("$@")
+                break
+            fi
+        done
+
+        local name="${args[0]}"
+        local path="${args[1]:-$name}"
+        local prefix="${args[2]:-bin}"
+
+        dart --packages=.dart_tool/package_config.json "$(packagePath "$name")/$prefix/$path.dart" "${passthrough[@]}"
+    }
+
+    # Runs a Dart executable from a package.
+    #
+    # Usage:
+    # packageRun <package> [-e executable] [...]
+    #
+    # To run an executable from an unconventional location, use packageRunCustom.
+    packageRun() {
+        local name="$1"
+        shift
+
+        local executableName="$name"
+        if [ "$1" = "-e" ]; then
+          shift
+          executableName="$1"
+          shift
+        fi
+
+        fileName="$(@yq@ --raw-output --arg name "$executableName" '.executables.[$name] // $name' "$(packagePath "$name")/pubspec.yaml")"
+        packageRunCustom "$name" "$fileName" -- "$@"
+    }
 
     echo "Finished dartConfigHook"
 }
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-fixup-hook.sh b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-fixup-hook.sh
index c5a9bedd0665..60bd74871c92 100644
--- a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-fixup-hook.sh
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-fixup-hook.sh
@@ -10,9 +10,12 @@ dartFixupHook() {
     #
     # 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.
-    echo "$runtimeDependencyLibraryPath"
-    if [[ ! -z "$runtimeDependencyLibraryPath" ]]; then
-        wrapProgramArgs+=(--suffix LD_LIBRARY_PATH : \"$runtimeDependencyLibraryPath\")
+    APPLICATION_LD_LIBRARY_PATH=""
+    for runtimeDependency in "${runtimeDependencies[@]}"; do
+      addToSearchPath APPLICATION_LD_LIBRARY_PATH "${runtimeDependency}/lib"
+    done
+    if [[ ! -z "$APPLICATION_LD_LIBRARY_PATH" ]]; then
+        wrapProgramArgs+=(--suffix LD_LIBRARY_PATH : \"$APPLICATION_LD_LIBRARY_PATH\")
     fi
 
     if [[ ! -z "$extraWrapProgramArgs" ]]; then
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-install-hook.sh b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-install-hook.sh
index 1906bcfbca4c..888e12a07d83 100644
--- a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-install-hook.sh
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/dart-install-hook.sh
@@ -5,8 +5,8 @@ dartInstallHook() {
 
     runHook preInstall
 
+    # Install snapshots and executables.
     mkdir -p "$out"
-
     while IFS=$'\t' read -ra target; do
         dest="${target[0]}"
         # Wrap with runtime command, if it's defined
@@ -19,6 +19,10 @@ dartInstallHook() {
         fi
     done < <(_getDartEntryPoints)
 
+    # Install the package_config.json file.
+    mkdir -p "$pubcache"
+    cp .dart_tool/package_config.json "$pubcache/package_config.json"
+
     runHook postInstall
 
     echo "Finished dartInstallHook"
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/default.nix b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/default.nix
index 134989426d96..253d3132ad02 100644
--- a/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/default.nix
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/hooks/default.nix
@@ -3,6 +3,8 @@
 {
   dartConfigHook = makeSetupHook {
     name = "dart-config-hook";
+    substitutions.yq = "${yq}/bin/yq";
+    substitutions.jq = "${jq}/bin/jq";
   } ./dart-config-hook.sh;
   dartBuildHook = makeSetupHook {
     name = "dart-build-hook";
diff --git a/nixpkgs/pkgs/build-support/dart/fetch-dart-deps/default.nix b/nixpkgs/pkgs/build-support/dart/fetch-dart-deps/default.nix
deleted file mode 100644
index 29e5209a2877..000000000000
--- a/nixpkgs/pkgs/build-support/dart/fetch-dart-deps/default.nix
+++ /dev/null
@@ -1,248 +0,0 @@
-{ stdenvNoCC
-, lib
-, makeSetupHook
-, writeShellScriptBin
-, dart
-, git
-, cacert
-, jq
-}:
-
-{
-  # 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"
-  # A path to a pubspec.lock file to use instead of the one in the source directory.
-, pubspecLockFile ? null
-  # 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 =
-    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 = ''
-        _pub_get() {
-          ${pubGetScript}
-        }
-
-        # so we can use lock, diff yaml
-        mkdir -p "$out/pubspec"
-        cp "pubspec.yaml" "$out/pubspec"
-        ${lib.optionalString (pubspecLockFile != null) "install -m644 ${pubspecLockFile} pubspec.lock"}
-        if ! cp "pubspec.lock" "$out/pubspec"; then
-          echo 1>&2 -e '\nThe pubspec.lock file is missing. This is a requirement for reproducible builds.' \
-                       '\nThe following steps should be taken to fix this issue:' \
-                       '\n  1. If you are building an application, contact the developer(s).' \
-                       '\n     The pubspec.lock file should be provided with the source code.' \
-                       '\n     https://dart.dev/guides/libraries/private-files#pubspeclock' \
-                       '\n  2. An attempt to generate and print a compressed pubspec.lock file will be made now.' \
-                       '\n     It is compressed with gzip and base64 encoded.' \
-                       '\n     Paste it to a file and extract it with `base64 -d pubspec.lock.in | gzip -d > pubspec.lock`.' \
-                       '\n     Provide the path to the pubspec.lock file in the pubspecLockFile argument.' \
-                       '\n     This must be updated whenever the application is updated.' \
-                       '\n'
-          _pub_get
-          echo ""
-          gzip --to-stdout --best pubspec.lock | base64 1>&2
-          echo 1>&2 -e '\nA gzipped pubspec.lock file has been printed. Please see the informational message above.'
-          exit 1
-        fi
-
-        _pub_get
-
-        # 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.
-        #
-        # An exception is made to keep .git/pub-packages files, which are important.
-        # https://github.com/dart-lang/pub/blob/c890afa1d65b340fa59308172029680c2f8b0fc6/lib/src/source/git.dart#L621
-        if [ -d "$PUB_CACHE"/git ]; then
-          find "$PUB_CACHE"/git -maxdepth 4 -path "*/.git/*" ! -name "pub-packages" -prune -exec rm -rf {} +
-        fi
-
-        # 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;
-    } // (removeAttrs drvArgs [ "name" "pname" ]));
-
-  mkDepsDrv = args: stdenvNoCC.mkDerivation (args // {
-    nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [ hook dart ];
-
-    configurePhase = args.configurePhase or ''
-      runHook preConfigure
-
-      ${sdkSetupScript}
-
-      _pub_get() {
-        ${pubGetScript} --offline
-      }
-      doPubGet _pub_get
-
-      runHook postConfigure
-    '';
-  } // (removeAttrs buildDrvInheritArgs [ "name" "pname" ]));
-
-  depsListDrv = mkDepsDrv {
-    name = "${name}-dart-deps-list.json";
-
-    nativeBuildInputs = [ jq ];
-
-    buildPhase = ''
-      runHook preBuild
-      if [ -e ${dart}/bin/flutter ]; then
-        flutter pub deps --json | jq .packages > $out
-      else
-        dart pub deps --json | jq .packages > $out
-      fi
-      runHook postBuild
-    '';
-
-    dontInstall = true;
-  };
-
-  packageConfigDrv = mkDepsDrv {
-    name = "${name}-package-config.json";
-
-    nativeBuildInputs = [ jq ];
-
-    buildPhase = ''
-      runHook preBuild
-
-      # Canonicalise the package_config.json, and replace references to the
-      # reconstructed package cache with the original FOD.
-      #
-      # The reconstructed package cache is not reproducible. The intended
-      # use-case of this derivation is for use with tools that use a
-      # package_config.json to load assets from packages, and not for use with
-      # Pub directly, which requires the setup performed by the hook before
-      # usage.
-      jq -S '
-        .packages[] |= . + { rootUri: .rootUri | gsub("'"$PUB_CACHE"'"; "${hook.deps}/cache/.pub-cache") }
-      | .generated |= "1970-01-01T00:00:00.000Z"
-      ' .dart_tool/package_config.json > $out
-
-      runHook postBuild
-    '';
-
-    dontInstall = true;
-  };
-
-  # As of Dart 3.0.0, Pub checks the revision of cached Git-sourced packages.
-  # Git must be wrapped to return a positive result, as the real .git directory is wiped
-  # to produce a deteministic dependency derivation output.
-  # https://github.com/dart-lang/pub/pull/3791/files#diff-1639c4669c428c26e68cfebd5039a33f87ba568795f2c058c303ca8528f62b77R631
-  gitSourceWrapper = writeShellScriptBin "git" ''
-    args=("$@")
-    if [[ "''${args[0]}" == "rev-list" && "''${args[1]}" == "--max-count=1" ]]; then
-      revision="''${args[''${#args[@]}-1]}"
-      echo "$revision"
-    else
-      ${git}/bin/git "''${args[@]}"
-    fi
-  '';
-
-  hook = (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 gitSourceWrapper deps; };
-    propagatedBuildInputs = [ dart git ];
-    passthru = {
-      inherit deps;
-      files = deps.outPath;
-      depsListFile = depsListDrv.outPath;
-      packageConfig = packageConfigDrv;
-    };
-  }) ./setup-hook.sh;
-in
-hook
diff --git a/nixpkgs/pkgs/build-support/dart/fetch-dart-deps/setup-hook.sh b/nixpkgs/pkgs/build-support/dart/fetch-dart-deps/setup-hook.sh
deleted file mode 100644
index 689e0e8c5b5f..000000000000
--- a/nixpkgs/pkgs/build-support/dart/fetch-dart-deps/setup-hook.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-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
-        cp -v "$deps/pubspec/pubspec.lock" .
-        # Sometimes the pubspec.lock will get opened in write mode, even when offline.
-        chmod u+w pubspec.lock
-    elif ! { diff -u pubspec.lock "$deps/pubspec/pubspec.lock" && diff -u pubspec.yaml "$deps/pubspec/pubspec.yaml"; }; then
-        echo 1>&2 -e 'The pubspec.lock or pubspec.yaml of the project derivation differs from the one in the dependency derivation.' \
-                   '\nYou most likely forgot to update the vendorHash while updating the sources.'
-        exit 1
-    fi
-}
-
-# Performs the given pub get command with an appropriate environment.
-doPubGet() {
-    PATH="@gitSourceWrapper@/bin:$PATH" "$@"
-}
diff --git a/nixpkgs/pkgs/build-support/dart/pub2nix/default.nix b/nixpkgs/pkgs/build-support/dart/pub2nix/default.nix
new file mode 100644
index 000000000000..ace2cc5a1e0c
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/dart/pub2nix/default.nix
@@ -0,0 +1,6 @@
+{ callPackage }:
+
+{
+  readPubspecLock = callPackage ./pubspec-lock.nix { };
+  generatePackageConfig = callPackage ./package-config.nix { };
+}
diff --git a/nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix b/nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix
new file mode 100644
index 000000000000..309e51ec84a1
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/dart/pub2nix/package-config.nix
@@ -0,0 +1,68 @@
+{ lib
+, runCommand
+, jq
+, yq
+}:
+
+{ pname ? null
+
+  # A list of dependency package names.
+, dependencies
+
+  # An attribute set of package names to sources.
+, dependencySources
+}:
+
+let
+  packages = lib.genAttrs dependencies (dependency: rec {
+    src = dependencySources.${dependency};
+    inherit (src) packageRoot;
+  });
+in
+(runCommand "${lib.optionalString (pname != null) "${pname}-"}package-config.json" {
+  inherit packages;
+
+  nativeBuildInputs = [ jq yq ];
+
+  __structuredAttrs = true;
+}) ''
+  declare -A packageSources
+  declare -A packageRoots
+  while IFS=',' read -r name src packageRoot; do
+    packageSources["$name"]="$src"
+    packageRoots["$name"]="$packageRoot"
+  done < <(jq -r '.packages | to_entries | map("\(.key),\(.value.src),\(.value.packageRoot)") | .[]' "$NIX_ATTRS_JSON_FILE")
+
+  for package in "''${!packageSources[@]}"; do
+    if [ ! -e "''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml" ]; then
+      echo >&2 "The package sources for $package are missing. Is the following path inside the source derivation?"
+      echo >&2 "Source path: ''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml"
+      exit 1
+    fi
+
+    languageConstraint="$(yq -r .environment.sdk "''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml")"
+    if [[ "$languageConstraint" =~ ^[[:space:]]*(\^|>=|>|)[[:space:]]*([[:digit:]]+\.[[:digit:]]+)\.[[:digit:]]+.*$ ]]; then
+      languageVersionJson="\"''${BASH_REMATCH[2]}\""
+    elif [ "$languageConstraint" = 'any' ]; then
+      languageVersionJson='null'
+    else
+      # https://github.com/dart-lang/pub/blob/68dc2f547d0a264955c1fa551fa0a0e158046494/lib/src/language_version.dart#L106C35-L106C35
+      languageVersionJson='"2.7"'
+    fi
+
+    jq --null-input \
+      --arg name "$package" \
+      --arg path "''${packageSources["$package"]}/''${packageRoots["$package"]}" \
+      --argjson languageVersion "$languageVersionJson" \
+      '{
+        name: $name,
+        rootUri: "file://\($path)",
+        packageUri: "lib/",
+        languageVersion: $languageVersion,
+      }'
+  done | jq > "$out" --slurp '{
+    configVersion: 2,
+    generator: "nixpkgs",
+    packages: .,
+  }'
+''
diff --git a/nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix b/nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
new file mode 100644
index 000000000000..e1ab4d7d2359
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
@@ -0,0 +1,119 @@
+{ lib
+, callPackage
+, fetchurl
+, fetchgit
+, runCommand
+}:
+
+{
+  # The source directory of the package.
+  src
+
+  # The package subdirectory within src.
+  # Useful if the package references sibling packages with relative paths.
+, packageRoot ? "."
+
+  # The pubspec.lock file, in attribute set form.
+, pubspecLock
+
+  # Hashes for Git dependencies.
+  # Pub does not record these itself, so they must be manually provided.
+, gitHashes ? { }
+
+  # Functions to generate SDK package sources.
+  # The function names should match the SDK names, and the package name is given as an argument.
+, sdkSourceBuilders ? { }
+
+  # Functions that create custom package source derivations.
+  #
+  # The function names should match the package names, and the package version,
+  # source, and source files are given in an attribute set argument.
+  #
+  # The passthru of the source derivation should be propagated.
+, customSourceBuilders ? { }
+}:
+
+let
+  dependencyVersions = builtins.mapAttrs (name: details: details.version) pubspecLock.packages;
+
+  dependencyTypes = {
+    "direct main" = "main";
+    "direct dev" = "dev";
+    "direct overridden" = "overridden";
+    "transitive" = "transitive";
+  };
+
+  dependencies = lib.foldlAttrs
+    (dependencies: name: details: dependencies // { ${dependencyTypes.${details.dependency}} = dependencies.${dependencyTypes.${details.dependency}} ++ [ name ]; })
+    (lib.genAttrs (builtins.attrValues dependencyTypes) (dependencyType: [ ]))
+    pubspecLock.packages;
+
+  # fetchTarball fails with "tarball contains an unexpected number of top-level files". This is a workaround.
+  # https://discourse.nixos.org/t/fetchtarball-with-multiple-top-level-directories-fails/20556
+  mkHostedDependencySource = name: details:
+    let
+      archive = fetchurl {
+        name = "pub-${name}-${details.version}.tar.gz";
+        url = "${details.description.url}/packages/${details.description.name}/versions/${details.version}.tar.gz";
+        sha256 = details.description.sha256;
+      };
+    in
+    runCommand "pub-${name}-${details.version}" { passthru.packageRoot = "."; } ''
+      mkdir -p "$out"
+      tar xf '${archive}' -C "$out"
+    '';
+
+  mkGitDependencySource = name: details: (fetchgit {
+    name = "pub-${name}-${details.version}";
+    url = details.description.url;
+    rev = details.description.resolved-ref;
+    hash = gitHashes.${name} or (throw "A Git hash is required for ${name}! Set to an empty string to obtain it.");
+  }).overrideAttrs ({ passthru ? { }, ... }: {
+    passthru = passthru // {
+      packageRoot = details.description.path;
+    };
+  });
+
+  mkPathDependencySource = name: details:
+    assert lib.assertMsg details.description.relative "Only relative paths are supported - ${name} has an absolue path!";
+    (if lib.isDerivation src then src else (runCommand "pub-${name}-${details.version}" { } ''cp -r '${src}' "$out"'')).overrideAttrs ({ passthru ? { }, ... }: {
+      passthru = passthru // {
+        packageRoot = "${packageRoot}/${details.description.path}";
+      };
+    });
+
+  mkSdkDependencySource = name: details:
+    (sdkSourceBuilders.${details.description} or (throw "No SDK source builder has been given for ${details.description}!")) name;
+
+  addDependencySourceUtils = dependencySource: details: dependencySource.overrideAttrs ({ passthru, ... }: {
+    passthru = passthru // {
+      inherit (details) version;
+    };
+  });
+
+  sourceBuilders = callPackage ../../../development/compilers/dart/package-source-builders { } // customSourceBuilders;
+
+  dependencySources = lib.filterAttrs (name: src: src != null) (builtins.mapAttrs
+    (name: details:
+      (sourceBuilders.${name} or ({ src, ... }: src)) {
+        inherit (details) version source;
+        src = ((addDependencySourceUtils (({
+          "hosted" = mkHostedDependencySource;
+          "git" = mkGitDependencySource;
+          "path" = mkPathDependencySource;
+          "sdk" = mkSdkDependencySource;
+        }.${details.source} name) details)) details);
+      })
+    pubspecLock.packages);
+in
+{
+  inherit
+    # An attribute set of dependency categories to package name lists.
+    dependencies
+
+    # An attribute set of package names to their versions.
+    dependencyVersions
+
+    # An attribute set of package names to their sources.
+    dependencySources;
+}
diff --git a/nixpkgs/pkgs/build-support/fetchpijul/default.nix b/nixpkgs/pkgs/build-support/fetchpijul/default.nix
index ca7e1a7926e8..fd41cfa55355 100644
--- a/nixpkgs/pkgs/build-support/fetchpijul/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchpijul/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenvNoCC, pijul }:
+{ lib, stdenvNoCC, pijul, cacert }:
 
 lib.makeOverridable (
 { url
@@ -17,7 +17,8 @@ if change != null && state != null then
 else
   stdenvNoCC.mkDerivation {
     inherit name;
-    nativeBuildInputs = [ pijul ];
+    nativeBuildInputs = [ pijul cacert ];
+    strictDeps = true;
 
     dontUnpack = true;
     dontConfigure = true;
@@ -52,5 +53,7 @@ else
       lib.fakeSha256;
 
     inherit url change state channel;
+
+    impureEnvVars = lib.fetchers.proxyImpureEnvVars;
   }
 )
diff --git a/nixpkgs/pkgs/build-support/flutter/default.nix b/nixpkgs/pkgs/build-support/flutter/default.nix
index bcee31506df1..4d00e177370e 100644
--- a/nixpkgs/pkgs/build-support/flutter/default.nix
+++ b/nixpkgs/pkgs/build-support/flutter/default.nix
@@ -3,11 +3,14 @@
 , runCommand
 , makeWrapper
 , wrapGAppsHook
-, fetchDartDeps
 , buildDartApplication
 , cacert
 , glib
 , flutter
+, pkg-config
+, jq
+, yq
+, moreutils
 }:
 
 # absolutely no mac support for now
@@ -20,7 +23,6 @@
 
 (buildDartApplication.override {
   dart = flutter;
-  fetchDartDeps = fetchDartDeps.override { dart = flutter; };
 }) (args // {
   sdkSetupScript = ''
     # Pub needs SSL certificates. Dart normally looks in a hardcoded path.
@@ -50,7 +52,46 @@
 
   inherit pubGetScript;
 
-  nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [ wrapGAppsHook ];
+  sdkSourceBuilders = {
+    # https://github.com/dart-lang/pub/blob/68dc2f547d0a264955c1fa551fa0a0e158046494/lib/src/sdk/flutter.dart#L81
+    "flutter" = name: runCommand "flutter-sdk-${name}" { passthru.packageRoot = "."; } ''
+      for path in '${flutter}/packages/${name}' '${flutter}/bin/cache/pkg/${name}'; do
+        if [ -d "$path" ]; then
+          ln -s "$path" "$out"
+          break
+        fi
+      done
+
+      if [ ! -e "$out" ]; then
+        echo 1>&2 'The Flutter SDK does not contain the requested package: ${name}!'
+        exit 1
+      fi
+    '';
+  };
+
+  extraPackageConfigSetup = ''
+    # https://github.com/flutter/flutter/blob/3.13.8/packages/flutter_tools/lib/src/dart/pub.dart#L755
+    if [ "$('${yq}/bin/yq' '.flutter.generate // false' pubspec.yaml)" = "true" ]; then
+      '${jq}/bin/jq' '.packages |= . + [{
+        name: "flutter_gen",
+        rootUri: "flutter_gen",
+        languageVersion: "2.12",
+      }]' "$out" | '${moreutils}/bin/sponge' "$out"
+    fi
+  '';
+
+  nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
+    wrapGAppsHook
+
+    # Flutter requires pkg-config for Linux desktop support, and many plugins
+    # attempt to use it.
+    #
+    # It is available to the `flutter` tool through its wrapper, but it must be
+    # added here as well so the setup hook adds plugin dependencies to the
+    # pkg-config search paths.
+    pkg-config
+  ];
+
   buildInputs = (args.buildInputs or [ ]) ++ [ glib ];
 
   dontDartBuild = true;
@@ -59,7 +100,6 @@
 
     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}\"") flutterBuildFlags)}
 
     runHook postBuild
@@ -94,6 +134,11 @@
       fi
     done
 
+    # Install the package_config.json file.
+    # This is normally done by dartInstallHook, but we disable it.
+    mkdir -p "$pubcache"
+    cp .dart_tool/package_config.json "$pubcache/package_config.json"
+
     runHook postInstall
   '';