forked from rarias/jungle
206 lines
6.5 KiB
Nix
206 lines
6.5 KiB
Nix
{ lib
|
|
, stdenv
|
|
, callPackage
|
|
, dpkg
|
|
, fetchurl
|
|
, recurseIntoAttrs
|
|
|
|
, sqlite
|
|
, elfutils
|
|
}:
|
|
|
|
let
|
|
inherit (builtins)
|
|
elem attrNames attrValues concatMap filter fromJSON getAttr groupBy head isNull listToAttrs map mapAttrs readFile replaceStrings splitVersion ;
|
|
inherit (lib)
|
|
converge findFirst groupBy' hasPrefix optional pipe take toInt toList versionAtLeast versionOlder ;
|
|
|
|
aptData = fromJSON (readFile ./packages.json);
|
|
|
|
# Compare versions in debian control file syntax
|
|
# See: https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
|
|
#
|
|
# NOTE: this is not a proper version comparison
|
|
#
|
|
# A proper version solver, should aggregate dependencies with the same name
|
|
# and compute the constraint (e.g. a (>= 2) a (<< 5) -> 2 <= a << 5)
|
|
#
|
|
# But in the intel repo, there are no such "duplicated" dependencies to specify
|
|
# upper limits, which leads to issues when intel-hpckit-2021 depends on things
|
|
# like intel-basekit >= 2021.1.0-2403 and we end up installing the newest
|
|
# basekit instead of the one from 2021.
|
|
#
|
|
# To mitigate this, >= is set to take the latest version with matching major
|
|
# and minor (only revision and patch are allowed to change)
|
|
compareVersions = got: kind: want:
|
|
let
|
|
g0 = take 2 (splitVersion got);
|
|
w0 = take 2 (splitVersion want);
|
|
in if isNull want then true
|
|
else if kind == "=" then got == want
|
|
else if kind == "<<" then versionOlder got want
|
|
else if kind == "<=" then versionAtLeast want got
|
|
else if kind == ">>" then versionOlder want got
|
|
else if kind == ">=" then (g0 == w0) && versionAtLeast got want # always match major version
|
|
else throw "unknown operation: ${kind}";
|
|
|
|
findMatching = { pname, kind, version }:
|
|
findFirst (x: pname == x.pname && compareVersions x.version kind version) null aptData;
|
|
|
|
isIntel = pkg: (hasPrefix "intel-" pkg.pname);
|
|
|
|
expandDeps = pkg: (map findMatching (filter isIntel pkg.dependencies)) ++ (optional (pkg.size != 0) pkg);
|
|
|
|
# get the oldest by major version. If they have the same major version, take
|
|
# the newest. This prevents most issues with resolutions
|
|
# versionOlder b a -> true if b is older than a (b `older` a)
|
|
getNewerInMajor = a: b: let
|
|
va = a.version;
|
|
vb = b.version;
|
|
va0 = head (splitVersion va);
|
|
vb0 = head (splitVersion vb);
|
|
in
|
|
if isNull a then b
|
|
else if va0 != vb0 then
|
|
if va0 > vb0 then b else a
|
|
else if versionOlder vb va then a else b;
|
|
removeDups = l: attrValues (groupBy' getNewerInMajor null (getAttr "provides") l);
|
|
|
|
_resolveDeps = converge (l: removeDups (concatMap expandDeps l));
|
|
resolveDeps = pkg: let deps = _resolveDeps (toList pkg);
|
|
namedDeps = (map (x: "${x.pname}-${x.version}") deps);
|
|
in builtins.traceVerbose (builtins.deepSeq namedDeps namedDeps) deps;
|
|
|
|
blacklist = [
|
|
"intel-basekit-env"
|
|
"intel-basekit-getting-started"
|
|
"intel-hpckit-env"
|
|
"intel-hpckit-getting-started"
|
|
"intel-oneapi-advisor"
|
|
"intel-oneapi-common-licensing"
|
|
"intel-oneapi-common-oneapi-vars"
|
|
"intel-oneapi-common-vars"
|
|
"intel-oneapi-compiler-cpp-eclipse-cfg"
|
|
"intel-oneapi-compiler-dpcpp-eclipse-cfg"
|
|
"intel-oneapi-condaindex"
|
|
"intel-oneapi-dev-utilities-eclipse-cfg"
|
|
"intel-oneapi-dpcpp-ct-eclipse-cfg"
|
|
"intel-oneapi-eclipse-ide"
|
|
"intel-oneapi-hpc-toolkit-getting-started"
|
|
"intel-oneapi-icc-eclipse-plugin-cpp"
|
|
"intel-oneapi-vtune"
|
|
"intel-oneapi-vtune-eclipse-plugin-vtune"
|
|
];
|
|
|
|
isInBlacklist = pkg: elem pkg.provides blacklist;
|
|
removeBlacklist = filter (e: !(isInBlacklist e));
|
|
|
|
dpkgExtractAll = pname: version: {srcs, deps}: stdenv.mkDerivation {
|
|
inherit pname version srcs;
|
|
|
|
nativeBuildInputs = [ dpkg ];
|
|
phases = [ "installPhase" ];
|
|
|
|
passthru = { inherit deps; };
|
|
|
|
installPhase = ''
|
|
mkdir -p $out
|
|
for src in $srcs; do
|
|
echo "Unpacking $src"
|
|
dpkg -x $src $out
|
|
done
|
|
'';
|
|
};
|
|
|
|
apthost = "https://apt.repos.intel.com/oneapi/";
|
|
fetchDeb = p: fetchurl { url = apthost + p.filename; inherit (p) sha256; };
|
|
|
|
buildIntel = pkg: pipe pkg [
|
|
resolveDeps
|
|
removeBlacklist
|
|
(l: {srcs = map fetchDeb l; deps = l; })
|
|
(dpkgExtractAll "${pkg.provides}-extracted" pkg.version)
|
|
];
|
|
|
|
findHpcKit = year: findMatching { pname = "intel-hpckit"; kind = "<<"; version = toString (year+1); };
|
|
years = map toInt (attrNames components);
|
|
|
|
patchIntel = callPackage ./patch_intel.nix { };
|
|
|
|
# Version information for each hpckit. This is used to normalize the paths
|
|
# so that files are in $out/{bin,lib,include...} instead of all over the place
|
|
# in $out/opt/intel/oneapi/*/*/{...}.
|
|
#
|
|
# The most important is the compiler component, which is used to build the
|
|
# stdenv for the hpckit.
|
|
#
|
|
# NOTE: this have to be manually specified, so we can avoid IFD. To add a
|
|
# new version, add a new field with an empty attrset, (e.g. "2026" = {}; ),
|
|
# build hpckit_2026.unpatched and use the values from
|
|
# result/opt/intel/oneapi/* to populate the attrset.
|
|
#
|
|
# WARN: if there are more than one version in the folders of the unpatched
|
|
# components, our dependency resolution hacks have probably failed and the
|
|
# package set may be broken.
|
|
components = {
|
|
"2025" = {
|
|
ishmem = "1.4";
|
|
pti = "0.13";
|
|
tcm = "1.4";
|
|
umf = "0.11";
|
|
|
|
ccl = "2021.16";
|
|
compiler = "2025.2";
|
|
dal = "2025.8";
|
|
debugger = "2025.2";
|
|
dev-utilities = "2025.2";
|
|
dnnl = "2025.2";
|
|
dpcpp-ct = "2025.2";
|
|
dpl = "2022.9";
|
|
ipp = "2022.2";
|
|
ippcp = "2025.2";
|
|
mkl = "2025.2";
|
|
mpi = "2021.16";
|
|
tbb = "2022.2";
|
|
};
|
|
"2024" = {
|
|
tcm = "1.1";
|
|
|
|
ccl = "2021.13";
|
|
compiler = "2024.2";
|
|
dal = "2024.6";
|
|
debugger = "2024.2";
|
|
dev-utilities = "2024.2";
|
|
diagnostics = "2024.2";
|
|
dnnl = "2024.2";
|
|
dpcpp-ct = "2024.2";
|
|
dpl = "2022.6";
|
|
ipp = "2021.12";
|
|
ippcp = "2021.12";
|
|
mkl = "2024.2";
|
|
mpi = "2021.13";
|
|
tbb = "2021.13";
|
|
|
|
extraPackages = [
|
|
sqlite
|
|
elfutils
|
|
];
|
|
};
|
|
};
|
|
|
|
replaceDots = replaceStrings ["."] ["_"];
|
|
|
|
in recurseIntoAttrs (listToAttrs (map (year: let
|
|
year_str = toString year;
|
|
in {
|
|
name = "hpckit_${year_str}";
|
|
value = patchIntel {unpatched = buildIntel (findHpcKit year); components = components.${year_str}; };
|
|
}) years)) // {
|
|
apt = pipe aptData [
|
|
(groupBy (p: replaceDots p.provides))
|
|
(mapAttrs (_: l: listToAttrs (map (pkg: { name = replaceDots ("v" + pkg.version); value = pkg; }) l)))
|
|
] ;
|
|
|
|
inherit resolveDeps patchIntel buildIntel;
|
|
}
|