about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
blob: f9a49fec3a2d8d7cd3a2f7cea04d16e6e039a514 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
{ lib
, stdenv
, callPackage
, runCommand
, writeText
, pub2nix
, dartHooks
, makeWrapper
, dart
, nodejs
, darwin
, jq
, yq
}:

{ 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
  # If using jit, you might want to pass some arguments to `dartJitFlags`
, dartOutputType ? "exe"
, dartCompileCommand ? "dart compile"
, dartCompileFlags ? [ ]
  # These come at the end of the command, useful to pass flags to the jit run
, dartJitFlags ? [ ]

  # Attrset of entry point files to build and install.
  # Where key is the final binary path and value is the source file path
  # e.g. { "bin/foo" = "bin/main.dart";  }
  # Set to null to read executables from pubspec.yaml
, 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

, runtimeDependencies ? [ ]
, extraWrapProgramArgs ? ""

, autoPubspecLock ? null
, pubspecLock ? if autoPubspecLock == null then
    throw "The pubspecLock argument is required. If import-from-derivation is allowed (it isn't in Nixpkgs), you can set autoPubspecLock to the path to a pubspec.lock instead."
  else
    assert lib.assertMsg (builtins.pathExists autoPubspecLock) "The pubspec.lock file could not be found!";
    lib.importJSON (runCommand "${lib.getName args}-pubspec-lock-json" { nativeBuildInputs = [ yq ]; } ''yq . '${autoPubspecLock}' > "$out"'')
, ...
}@args:

let
  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;
    };
    extraSetupCommands = extraPackageConfigSetup;
  };

  inherit (dartHooks.override { inherit dart; }) dartConfigHook dartBuildHook dartInstallHook dartFixupHook;

  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;

    runtimeDependencies = map lib.getLib runtimeDependencies;

    nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
      dart
      dartConfigHook
      dartBuildHook
      dartInstallHook
      dartFixupHook
      makeWrapper
      jq
    ] ++ lib.optionals stdenv.isDarwin [
      darwin.sigtool
    ] ++
      # 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");

    passAsFile = [ "pubspecLockFile" ];

    passthru = {
      pubspecLock = pubspecLockData;
    } // (args.passthru or { });

    meta = (args.meta or { }) // { platforms = args.meta.platforms or dart.meta.platforms; };
  });
in
assert !(builtins.isString dartOutputType && dartOutputType != "") ->
throw "dartOutputType must be a non-empty string";
baseDerivation