nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 callPackage,
5 runCommand,
6 writeText,
7 pub2nix,
8 dartHooks,
9 makeWrapper,
10 dart,
11 nodejs,
12 darwin,
13 jq,
14 yq,
15}:
16
17{
18 src,
19 sourceRoot ? "source",
20 packageRoot ? (lib.removePrefix "/" (lib.removePrefix "source" sourceRoot)),
21 gitHashes ? { },
22 sdkSourceBuilders ? { },
23 customSourceBuilders ? { },
24
25 sdkSetupScript ? "",
26 extraPackageConfigSetup ? "",
27
28 # Output type to produce. Can be any kind supported by dart
29 # https://dart.dev/tools/dart-compile#types-of-output
30 # If using jit, you might want to pass some arguments to `dartJitFlags`
31 dartOutputType ? "exe",
32 dartCompileCommand ? "dart compile",
33 dartCompileFlags ? [ ],
34 # These come at the end of the command, useful to pass flags to the jit run
35 dartJitFlags ? [ ],
36
37 # Attrset of entry point files to build and install.
38 # Where key is the final binary path and value is the source file path
39 # e.g. { "bin/foo" = "bin/main.dart"; }
40 # Set to null to read executables from pubspec.yaml
41 dartEntryPoints ? null,
42 # Used when wrapping aot, jit, kernel, and js builds.
43 # Set to null to disable wrapping.
44 dartRuntimeCommand ?
45 if dartOutputType == "aot-snapshot" then
46 "${dart}/bin/dartaotruntime"
47 else if (dartOutputType == "jit-snapshot" || dartOutputType == "kernel") then
48 "${dart}/bin/dart"
49 else if dartOutputType == "js" then
50 "${nodejs}/bin/node"
51 else
52 null,
53
54 runtimeDependencies ? [ ],
55 extraWrapProgramArgs ? "",
56
57 autoPubspecLock ? null,
58 pubspecLock ?
59 if autoPubspecLock == null then
60 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."
61 else
62 assert lib.assertMsg (builtins.pathExists autoPubspecLock)
63 "The pubspec.lock file could not be found!";
64 lib.importJSON (
65 runCommand "${lib.getName args}-pubspec-lock-json" {
66 nativeBuildInputs = [ yq ];
67 } ''yq . '${autoPubspecLock}' > "$out"''
68 ),
69 ...
70}@args:
71
72let
73 generators = callPackage ./generators.nix { inherit dart; } { buildDrvArgs = args; };
74
75 pubspecLockFile = builtins.toJSON pubspecLock;
76 pubspecLockData = pub2nix.readPubspecLock {
77 inherit
78 src
79 packageRoot
80 pubspecLock
81 gitHashes
82 customSourceBuilders
83 ;
84 sdkSourceBuilders = {
85 # https://github.com/dart-lang/pub/blob/e1fbda73d1ac597474b82882ee0bf6ecea5df108/lib/src/sdk/dart.dart#L80
86 "dart" =
87 name:
88 runCommand "dart-sdk-${name}" { passthru.packageRoot = "."; } ''
89 for path in '${dart}/pkg/${name}'; do
90 if [ -d "$path" ]; then
91 ln -s "$path" "$out"
92 break
93 fi
94 done
95
96 if [ ! -e "$out" ]; then
97 echo 1>&2 'The Dart SDK does not contain the requested package: ${name}!'
98 exit 1
99 fi
100 '';
101 }
102 // sdkSourceBuilders;
103 };
104 packageConfig = generators.linkPackageConfig {
105 inherit pubspecLock;
106 packageConfig = pub2nix.generatePackageConfig {
107 pname = if args.pname != null then "${args.pname}-${args.version}" else null;
108
109 dependencies =
110 # Ideally, we'd only include the main dependencies and their transitive
111 # dependencies.
112 #
113 # The pubspec.lock file does not contain information about where
114 # transitive dependencies come from, though, and it would be weird to
115 # include the transitive dependencies of dev and override dependencies
116 # without including the dev and override dependencies themselves.
117 builtins.concatLists (builtins.attrValues pubspecLockData.dependencies);
118
119 inherit (pubspecLockData) dependencySources;
120 };
121 extraSetupCommands = extraPackageConfigSetup;
122 };
123
124 inherit (dartHooks.override { inherit dart; })
125 dartConfigHook
126 dartBuildHook
127 dartInstallHook
128 dartFixupHook
129 ;
130
131 baseDerivation = stdenv.mkDerivation (
132 finalAttrs:
133 (builtins.removeAttrs args [
134 "gitHashes"
135 "sdkSourceBuilders"
136 "pubspecLock"
137 "customSourceBuilders"
138 ])
139 // {
140 inherit
141 pubspecLockFile
142 packageConfig
143 sdkSetupScript
144 dartCompileCommand
145 dartOutputType
146 dartRuntimeCommand
147 dartCompileFlags
148 dartJitFlags
149 ;
150
151 outputs = [
152 "out"
153 "pubcache"
154 ]
155 ++ args.outputs or [ ];
156
157 dartEntryPoints =
158 if (dartEntryPoints != null) then
159 writeText "entrypoints.json" (builtins.toJSON dartEntryPoints)
160 else
161 null;
162
163 runtimeDependencies = map lib.getLib runtimeDependencies;
164
165 nativeBuildInputs =
166 (args.nativeBuildInputs or [ ])
167 ++ [
168 dart
169 dartConfigHook
170 dartBuildHook
171 dartInstallHook
172 dartFixupHook
173 makeWrapper
174 jq
175 ]
176 ++ lib.optionals stdenv.hostPlatform.isDarwin [
177 darwin.sigtool
178 ]
179 ++
180 # Ensure that we inherit the propagated build inputs from the dependencies.
181 builtins.attrValues pubspecLockData.dependencySources;
182
183 preConfigure = args.preConfigure or "" + ''
184 ln -sf "$pubspecLockFilePath" pubspec.lock
185 '';
186
187 # When stripping, it seems some ELF information is lost and the dart VM cli
188 # runs instead of the expected program. Don't strip if it's an exe output.
189 dontStrip = args.dontStrip or (dartOutputType == "exe");
190
191 passAsFile = [ "pubspecLockFile" ];
192
193 passthru = {
194 pubspecLock = pubspecLockData;
195 }
196 // (args.passthru or { });
197
198 meta = (args.meta or { }) // {
199 platforms = args.meta.platforms or dart.meta.platforms;
200 };
201 }
202 );
203in
204assert
205 !(builtins.isString dartOutputType && dartOutputType != "")
206 -> throw "dartOutputType must be a non-empty string";
207baseDerivation