nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 callPackage,
4 stdenv,
5 ncurses5,
6 bc,
7 bubblewrap,
8 autoPatchelfHook,
9 python3,
10 libgcc,
11 glibc,
12 writeShellScript,
13 writeText,
14 writeTextFile,
15
16 # For the updater script
17 writeShellApplication,
18 curl,
19 jq,
20 htmlq,
21 common-updater-scripts,
22 writableTmpDirAsHomeHook,
23}:
24
25{
26 mkIntelOneApi = lib.extendMkDerivation {
27 constructDrv = stdenv.mkDerivation;
28
29 excludeDrvArgNames = [
30 "depsByComponent"
31 "components"
32 ];
33
34 extendDrvArgs =
35 finalAttrs:
36 {
37 pname,
38 versionYear,
39 versionMajor,
40 versionMinor,
41 versionRel,
42 src,
43 meta,
44 depsByComponent ? { },
45 postInstall ? "",
46 components ? [ "default" ],
47 ...
48 }@args:
49 let
50 shortName = name: builtins.elemAt (lib.splitString "." name) 3;
51 in
52 {
53 version = "${finalAttrs.versionYear}.${finalAttrs.versionMajor}.${finalAttrs.versionMinor}.${finalAttrs.versionRel}";
54
55 nativeBuildInputs = [
56 # Installer wants tput
57 ncurses5
58 # Used to check if there's enough disk space
59 bc
60 bubblewrap
61
62 autoPatchelfHook
63 writableTmpDirAsHomeHook
64 ];
65
66 buildInputs = [
67 # For patchShebangs
68 python3
69 ]
70 # autoPatchelfHook will add these libraries to RPATH as required
71 ++ lib.concatMap (
72 comp:
73 if comp == "all" || comp == "default" then
74 lib.concatLists (builtins.attrValues depsByComponent)
75 else
76 depsByComponent.${shortName comp} or [ ]
77 ) components;
78
79 phases = [
80 "installPhase"
81 "fixupPhase"
82 ];
83
84 # See https://software.intel.com/content/www/us/en/develop/documentation/installation-guide-for-intel-oneapi-toolkits-linux/top/installation/install-with-command-line.html
85 installPhase = ''
86 runHook preInstall
87 # The installer expects that the installation directory is already present
88 mkdir -p "$out"
89
90 # Required for the installer to find libstdc++
91 export LD_LIBRARY_PATH="${lib.makeLibraryPath [ libgcc.lib ]}"
92
93 # The installer is an insane four-stage rube goldberg machine:
94 # 1. Our $src (bash script) unpacks install.sh (bash script)
95 # 2. install.sh unpacks bootstrapper (dylinked binary with hardcoded interpreter in /lib)
96 # 3. bootstrapper unpacks installer (dylinked binary with hardcoded interpreter and libraries in /lib)
97 # 4. installer installs the actual components we need
98 #
99 # While stage 1 allows to "only extract", other stages always try running the next executable down, and remove stuff if they fail.
100 # I'm afraid this is the cleanest solution for now.
101 mkdir -p fhs-root/{lib,lib64}
102 ln -s "${glibc}/lib/"* fhs-root/lib/
103 ln -s "${glibc}/lib/"* fhs-root/lib64/
104 bwrap \
105 --bind fhs-root / \
106 --bind /nix /nix \
107 --ro-bind /bin /bin \
108 --dev /dev \
109 --proc /proc \
110 bash "$src" \
111 -a \
112 --silent \
113 --eula accept \
114 --install-dir "$out" \
115 --components ${lib.concatStringsSep ":" components}
116
117 # Non-reproducible
118 rm -rf "$out"/logs
119 # This contains broken symlinks and doesn't seem to be useful
120 rm -rf "$out"/.toolkit_linking_tool
121
122 ln -s "$out/$versionYear.$versionMajor"/{lib,etc,bin,share,opt} "$out"
123
124 runHook postInstall
125 '';
126 };
127 };
128
129 mkUpdateScript =
130 {
131 pname,
132 downloadPage,
133 file,
134 }:
135 writeShellApplication {
136 name = "update-intel-oneapi";
137 runtimeInputs = [
138 curl
139 jq
140 htmlq
141 common-updater-scripts
142 ];
143 text = ''
144 download_page=${lib.escapeShellArg downloadPage}
145 pname=${lib.escapeShellArg pname}
146 nixpkgs="$(git rev-parse --show-toplevel)"
147 packageDir="$nixpkgs/pkgs/by-name/in/intel-oneapi"
148 file="$packageDir"/${lib.escapeShellArg file}
149
150 echo 'Figuring out the download URL' >&2
151
152 # Intel helpfully gives us a wget command to run so that we can download the toolkit installer, as part of their product page.
153 # This variable will contain that command (wget https://...), we will extract the URL from it.
154 wget_command="$(curl "$download_page" \
155 | htmlq 'code' --text \
156 | grep "wget.*$pname.*sh")"
157
158 regex="wget (.*$pname.([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)_offline[.]sh)"
159 if [[ "$wget_command" =~ $regex ]]; then
160 url="''${BASH_REMATCH[1]}"
161 versionYear="''${BASH_REMATCH[2]}"
162 versionMajor="''${BASH_REMATCH[3]}"
163 versionMinor="''${BASH_REMATCH[4]}"
164 versionRel="''${BASH_REMATCH[5]}"
165 else
166 echo "'$wget_command' does not match the expected format $regex" >&2
167 exit 1
168 fi
169
170 if [[ "$(grep 'url =' "$file")" =~ "$url" ]] && [[ "''${BASH_REMATCH[0]}" == "$url" ]]; then
171 echo "The URL is the same ($url), skipping update" >&2
172 else
173 echo "The new download URL is $url, prefetching it to store" >&2
174 hash="$(nix-hash --to-sri --type sha256 "$(nix-prefetch-url --quiet "$url")")"
175 fi
176
177 sed -i "s|versionYear = \".*\";|versionYear = \"$versionYear\";|" "$file"
178 sed -i "s|versionMajor = \".*\";|versionMajor = \"$versionMajor\";|" "$file"
179 sed -i "s|versionMinor = \".*\";|versionMinor = \"$versionMinor\";|" "$file"
180 sed -i "s|versionRel = \".*\";|versionRel = \"$versionRel\";|" "$file"
181 sed -i "s|url = \".*\";|url = \"$url\";|" "$file"
182 sed -i "s|hash = \".*\";|hash = \"$hash\";|" "$file"
183 '';
184 };
185
186 base = callPackage ./base.nix { };
187 hpc = callPackage ./hpc.nix { };
188}