nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 _cuda,
3 config,
4 lib,
5 pkgs,
6 # Manually provided arguments
7 manifests,
8}:
9let
10 inherit (lib.customisation) callPackagesWith;
11 inherit (lib.filesystem) packagesFromDirectoryRecursive;
12 inherit (lib.fixedPoints) composeManyExtensions extends;
13 inherit (lib.lists) optionals;
14 inherit (lib.strings) versionAtLeast versionOlder;
15 inherit (lib.versions) major majorMinor;
16 inherit (_cuda.lib)
17 dropDots
18 formatCapabilities
19 mkVersionedName
20 ;
21
22 # NOTE: This value is considered an implementation detail and should not be exposed in the attribute set.
23 cudaMajorMinorPatchVersion = manifests.cuda.release_label;
24 cudaMajorMinorVersion = majorMinor cudaMajorMinorPatchVersion;
25 cudaMajorVersion = major cudaMajorMinorPatchVersion;
26
27 # We must use an instance of Nixpkgs where the CUDA package set we're building is the default; if we do not, members
28 # of the versioned, non-default package sets may rely on (transitively) members of the default, unversioned CUDA
29 # package set.
30 # See `Using cudaPackages.pkgs` in doc/languages-frameworks/cuda.section.md for more information.
31 pkgs' =
32 let
33 cudaPackagesUnversionedName = "cudaPackages";
34 cudaPackagesMajorVersionedName = mkVersionedName cudaPackagesUnversionedName cudaMajorVersion;
35 cudaPackagesMajorMinorVersionedName = mkVersionedName cudaPackagesUnversionedName cudaMajorMinorVersion;
36 in
37 if
38 # If the default CUDA package set is the same as the one we're constructing, pass through pkgs unchanged.
39 # This is a handy speedup for cases where we're using the default CUDA package set and don't need to pay for
40 # a re-instantiation of Nixpkgs.
41 pkgs.${cudaPackagesMajorMinorVersionedName}.manifests
42 == pkgs.${cudaPackagesMajorVersionedName}.manifests
43 &&
44 pkgs.${cudaPackagesMajorMinorVersionedName}.manifests
45 == pkgs.${cudaPackagesUnversionedName}.manifests
46 then
47 pkgs
48 else
49 pkgs.extend (
50 final: _: {
51 recurseForDerivations = false;
52 # The CUDA package set will be available as cudaPackages_x_y, so we need only update the aliases for the
53 # minor-versioned and unversioned package sets.
54 # However, if we do not replace the major-minor-versioned CUDA package set with our own, our use of splicing
55 # causes the package set to be re-evaluated for each build/host/target!
56
57 # cudaPackages_x_y = <package set created in this file>
58 ${cudaPackagesMajorMinorVersionedName} = cudaPackages;
59 # cudaPackages_x = cudaPackages_x_y
60 ${cudaPackagesMajorVersionedName} = final.${cudaPackagesMajorMinorVersionedName};
61 # cudaPackages = cudaPackages_x
62 ${cudaPackagesUnversionedName} = final.${cudaPackagesMajorVersionedName};
63 }
64 );
65
66 cudaPackagesFixedPoint =
67 finalCudaPackages:
68 {
69 # NOTE:
70 # It is important that _cuda is not part of the package set fixed-point. As described by
71 # @SomeoneSerge:
72 # > The layering should be: configuration -> (identifies/is part of) cudaPackages -> (is built using) cudaLib.
73 # > No arrows should point in the reverse directions.
74 # That is to say that cudaLib should only know about package sets and configurations, because it implements
75 # functionality for interpreting configurations, resolving them against data, and constructing package sets.
76 # This decision is driven both by a separation of concerns and by "NAMESET STRICTNESS" (see above).
77 # Also see the comment in `pkgs/top-level/all-packages.nix` about the `_cuda` attribute.
78
79 inherit
80 cudaMajorMinorPatchVersion
81 cudaMajorMinorVersion
82 cudaMajorVersion
83 ;
84
85 pkgs = pkgs';
86
87 # Core
88 callPackages = callPackagesWith (pkgs' // finalCudaPackages);
89
90 cudaNamePrefix = "cuda${cudaMajorMinorVersion}";
91
92 cudaOlder = versionOlder cudaMajorMinorVersion;
93 cudaAtLeast = versionAtLeast cudaMajorMinorVersion;
94
95 # These must be modified through callPackage, not by overriding the scope, since we cannot
96 # depend on them recursively as they are used to add top-level attributes.
97 inherit manifests;
98
99 # Construct without relying on the fixed-point to allow the use of backendStdenv in creating CUDA package sets.
100 # For example, this allows selecting manifests by predicating on values like
101 # `backendStdenv.hasJetsonCudaCapability`, which would otherwise result in infinite recursion due to the reliance
102 # on `pkgs'`, which in turn depends on the manifests provided to this file (which can depend on `backendStdenv`).
103 backendStdenv = import ./backendStdenv {
104 inherit
105 _cuda
106 config
107 cudaMajorMinorVersion
108 lib
109 pkgs
110 ;
111 inherit (pkgs)
112 stdenv
113 stdenvAdapters
114 ;
115 };
116
117 # Create backendStdenv variants for different host compilers, since users may want to build a CUDA project with
118 # Clang or GCC specifically.
119 # TODO(@connorbaker): Because of the way our setup hooks and patching of NVCC works, the user's choice of
120 # backendStdenv is largely disregarded or will cause build failures; fixing this would require the setup hooks
121 # and patching to be made aware of the current environment (perhaps by reading certain environment variables set
122 # by our backendStdenv).
123 # backendClangStdenv = finalCudaPackages.callPackage ./packages/backendStdenv.nix {
124 # stdenv = pkgs'.clangStdenv;
125 # };
126 # backendGccStdenv = finalCudaPackages.callPackage ./packages/backendStdenv.nix {
127 # stdenv = pkgs'.gccStdenv;
128 # };
129
130 # Must be constructed without `callPackage` to avoid replacing the `override` attribute with that of
131 # `callPackage`'s.
132 buildRedist = import ./buildRedist {
133 inherit
134 _cuda
135 lib
136 ;
137 inherit (pkgs)
138 autoAddDriverRunpath
139 autoPatchelfHook
140 fetchurl
141 srcOnly
142 stdenv
143 stdenvNoCC
144 ;
145 inherit (finalCudaPackages)
146 autoAddCudaCompatRunpath
147 backendStdenv
148 cudaMajorMinorVersion
149 cudaMajorVersion
150 cudaNamePrefix
151 manifests
152 markForCudatoolkitRootHook
153 removeStubsFromRunpathHook
154 ;
155 };
156
157 flags =
158 formatCapabilities {
159 inherit (finalCudaPackages.backendStdenv) cudaCapabilities cudaForwardCompat;
160 inherit (_cuda.db) cudaCapabilityToInfo;
161 }
162 # TODO(@connorbaker): Enable the corresponding warnings in `./aliases.nix` after some
163 # time to allow users to migrate to cudaLib and backendStdenv.
164 // {
165 inherit dropDots;
166 cudaComputeCapabilityToName =
167 cudaCapability: _cuda.db.cudaCapabilityToInfo.${cudaCapability}.archName;
168 dropDot = dropDots;
169 isJetsonBuild = finalCudaPackages.backendStdenv.hasJetsonCudaCapability;
170 };
171 }
172 // packagesFromDirectoryRecursive {
173 inherit (finalCudaPackages) callPackage;
174 directory = ./packages;
175 };
176
177 composedExtensions = composeManyExtensions (
178 optionals config.allowAliases [
179 (import ./aliases.nix { inherit lib; })
180 ]
181 ++ _cuda.extensions
182 );
183
184 # Using lib.makeScopeWithSplicing' instead of the templated one from pkgs' allows us to defer calling pkgs.extend.
185 cudaPackages =
186 lib.makeScopeWithSplicing'
187 {
188 splicePackages = pkgs'.splicePackages;
189 newScope = pkgs'.newScope;
190 }
191 {
192 # In pkgs', the default CUDA package set is always the one we've constructed here.
193 otherSplices = pkgs'.generateSplicesForMkScope [ "cudaPackages" ];
194 f = extends composedExtensions cudaPackagesFixedPoint;
195 };
196in
197cudaPackages