summary refs log tree commit diff
path: root/pkgs/build-support/dart/build-dart-application/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/build-support/dart/build-dart-application/default.nix')
-rw-r--r--pkgs/build-support/dart/build-dart-application/default.nix125
1 files changed, 89 insertions, 36 deletions
diff --git a/pkgs/build-support/dart/build-dart-application/default.nix b/pkgs/build-support/dart/build-dart-application/default.nix
index be1fd727767..1a98f98fb8e 100644
--- a/pkgs/build-support/dart/build-dart-application/default.nix
+++ b/pkgs/build-support/dart/build-dart-application/default.nix
@@ -1,6 +1,7 @@
-{ lib, stdenv, fetchDartDeps, runCommand, writeText, dartHooks, makeWrapper, dart, cacert, nodejs, darwin }:
+{ lib, stdenv, callPackage, fetchDartDeps, writeText, symlinkJoin, dartHooks, makeWrapper, dart, cacert, nodejs, darwin, jq }:
 
-{ pubGetScript ? "dart pub get"
+{ sdkSetupScript ? ""
+, pubGetScript ? "dart pub get"
 
   # Output type to produce. Can be any kind supported by dart
   # https://dart.dev/tools/dart-compile#types-of-output
@@ -18,12 +19,16 @@
 , dartEntryPoints ? null
   # Used when wrapping aot, jit, kernel, and js builds.
   # Set to null to disable wrapping.
-, dartRuntimeCommand ?
-    if dartOutputType == "aot-snapshot" then "${dart}/bin/dartaotruntime"
-    else if (dartOutputType == "jit-snapshot" || dartOutputType == "kernel") then "${dart}/bin/dart"
-    else if dartOutputType == "js" then "${nodejs}/bin/node"
-    else null
+, dartRuntimeCommand ? if dartOutputType == "aot-snapshot" then "${dart}/bin/dartaotruntime"
+  else if (dartOutputType == "jit-snapshot" || dartOutputType == "kernel") then "${dart}/bin/dart"
+  else if dartOutputType == "js" then "${nodejs}/bin/node"
+  else null
 
+, runtimeDependencies ? [ ]
+, extraWrapProgramArgs ? ""
+, customPackageOverrides ? { }
+, autoDepsList ? false
+, depsListFile ? null
 , pubspecLockFile ? null
 , vendorHash ? ""
 , ...
@@ -31,44 +36,92 @@
 
 let
   dartDeps = (fetchDartDeps.override {
-    dart = 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 = symlinkJoin {
+      name = "dart-fod";
+      paths = [ dart ];
+      nativeBuildInputs = [ makeWrapper ];
+      postBuild = ''
+        wrapProgram "$out/bin/dart" \
+          --add-flags "--root-certs-file=${cacert}/etc/ssl/certs/ca-bundle.crt"
+      '';
+    };
   }) {
     buildDrvArgs = args;
-    inherit pubGetScript vendorHash pubspecLockFile;
+    inherit sdkSetupScript pubGetScript vendorHash pubspecLockFile;
   };
-  inherit (dartHooks.override { inherit dart; }) dartConfigHook dartBuildHook dartInstallHook;
-in
-assert !(builtins.isString dartOutputType && dartOutputType != "") ->
-  throw "dartOutputType must be a non-empty string";
-stdenv.mkDerivation (args // {
-  inherit pubGetScript dartCompileCommand dartOutputType dartRuntimeCommand
-    dartCompileFlags dartJitFlags;
+  inherit (dartHooks.override { inherit dart; }) dartConfigHook dartBuildHook dartInstallHook dartFixupHook;
+
+  baseDerivation = stdenv.mkDerivation (finalAttrs: args // {
+    inherit sdkSetupScript pubGetScript dartCompileCommand dartOutputType
+      dartRuntimeCommand dartCompileFlags dartJitFlags runtimeDependencies;
 
     dartEntryPoints =
       if (dartEntryPoints != null)
       then writeText "entrypoints.json" (builtins.toJSON dartEntryPoints)
       else null;
 
-  nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
-    dart
-    dartDeps
-    dartConfigHook
-    dartBuildHook
-    dartInstallHook
-    makeWrapper
-  ] ++ lib.optionals stdenv.isDarwin [
-    darwin.sigtool
-  ];
+    runtimeDependencyLibraryPath = lib.makeLibraryPath finalAttrs.runtimeDependencies;
+
+    nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
+      dart
+      dartDeps
+      dartConfigHook
+      dartBuildHook
+      dartInstallHook
+      dartFixupHook
+      makeWrapper
+      jq
+    ] ++ lib.optionals stdenv.isDarwin [
+      darwin.sigtool
+    ];
 
-  # 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");
+    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 ""}
+    '';
+
+    # 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 { });
 
-  passthru = { inherit dartDeps; } // (args.passthru or { });
+    meta = (args.meta or { }) // { platforms = args.meta.platforms or dart.meta.platforms; };
+  });
 
-  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