{ lib, llvmPackages, ninja, cmake, hwloc, ocl-icd, opencl-headers, getconf, pkg-config, spirv-llvm-translator, spirv-tools, libxml2, # required for statically linked llvm python3, writableTmpDirAsHomeHook, writeText, runCommand, opencl-cts, fetchFromGitHub, useGit ? false, gitUrl ? "git@gitlab-internal.bsc.es:task-awareness/pocl/pocl.git", gitBranch ? "new-device", gitCommit ? "dd10c2221b31223cbb796182df6a07f11c7541f5", staticLLVM ? true, enableICD ? true, enableSPIRV ? true, enableHWLOC ? true, enableRemoteServer ? false, enableRemoteClient ? false, enableDistroVariants ? false, lttng-ust, enableLTTNG ? false, onetbb, enableTBB ? false, nosv ? null, ovni ? null, enableNOSV ? useGit, enableOVNI ? useGit, buildPackages, targetPackages, nix-update-script, }: assert (enableNOSV || enableOVNI) -> useGit; let release = rec { version = "7.1"; src = fetchFromGitHub { owner = "pocl"; repo = "pocl"; tag = "v${version}"; hash = "sha256-bS6vTIjLO7YLs7qYLKW0cYYbEJ/hRS/+IjjAKbkj8ac="; }; }; git = rec { version = src.shortRev; src = builtins.fetchGit { url = gitUrl; ref = gitBranch; rev = gitCommit; }; }; source = if (useGit) then git else release; stdenv = llvmPackages.stdenv; buildLlvmPackages = buildPackages.llvmPackages; isCross = stdenv.hostPlatform != stdenv.buildPlatform; featureList = lib.concatStringsSep "+" ( (lib.optionals enableICD [ "icd" ]) ++ (lib.optionals enableNOSV [ "nosv" ]) ++ (lib.optionals enableOVNI [ "ovni" ]) ++ (lib.optionals enableSPIRV [ "spirv" ]) ++ (lib.optionals enableTBB [ "tbb" ]) ++ (lib.optionals enableRemoteClient [ "server" ]) ++ (lib.optionals enableRemoteServer [ "client" ]) ); in stdenv.mkDerivation (finalAttrs: { pname = "pocl"; version = featureList + "-" + source.version; inherit (source) src; patches = lib.optionals useGit [ ./0001-cmake-use-clang-from-cmake-variable.patch ./0001-cmake-do-not-use-suffix.patch ./0001-cmake-native-build-tools.patch ]; cmakeFlags = [ # TODO: all these are broken when cross compiling. Upstream has refactored # all the cmake infra for cross compilation, but it's not in a release yet (lib.cmakeOptionType "filepath" "WITH_LLVM_CONFIG" ( lib.getExe' buildLlvmPackages.llvm.dev "llvm-config" )) (lib.cmakeOptionType "filepath" "CLANG" (lib.getExe' buildLlvmPackages.clangUseLLVM "clang")) (lib.cmakeOptionType "filepath" "CLANGXX" (lib.getExe' buildLlvmPackages.clangUseLLVM "clang++")) (lib.cmakeOptionType "path" "CLANG_RESOURCE_DIR" "${llvmPackages.stdenv.cc}/resource-root") (lib.cmakeBool "ENABLE_TESTS" finalAttrs.finalPackage.doCheck) (lib.cmakeBool "ENABLE_RELOCATION" true) (lib.cmakeBool "ENABLE_POCL_BUILDING" true) (lib.cmakeBool "POCL_ICD_ABSOLUTE_PATH" true) (lib.cmakeBool "ENABLE_TBB_DEVICE" enableTBB) (lib.cmakeBool "ENABLE_ICD" enableICD) (lib.cmakeBool "ENABLE_HWLOC" enableHWLOC) (lib.cmakeBool "ENABLE_LTTNG" enableLTTNG) (lib.cmakeBool "ENABLE_REMOTE_CLIENT" enableRemoteClient) (lib.cmakeBool "ENABLE_REMOTE_SERVER" enableRemoteServer) # avoid the runtime linker pulling in a different llvm e.g. from graphics drivers (lib.cmakeBool "STATIC_LLVM" staticLLVM) ] ++ lib.optionals (enableNOSV || enableOVNI) [ (lib.cmakeBool "ENABLE_NOSV" enableNOSV) (lib.cmakeBool "ENABLE_OVNI" enableOVNI) ] ++ lib.optionals (!isCross && enableDistroVariants) [ (lib.cmakeFeature "KERNELLIB_HOST_CPU_VARIANTS" "distro") # TODO: check if we can do it when cross compiling ] ++ lib.optionals isCross [ (lib.cmakeFeature "CMAKE_SYSTEM_NAME" "Linux") (lib.cmakeFeature "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM" "NEVER") (lib.cmakeFeature "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY" "ONLY") (lib.cmakeFeature "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE" "ONLY") (lib.cmakeFeature "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE" "ONLY") ] ++ lib.optionals stdenv.hostPlatform.isRiscV [ (lib.cmakeFeature "LLC_TRIPLE" "riscv64-unknown-linux-gnu") (lib.cmakeFeature "LLC_HOST_CPU" "rv64g") (lib.cmakeFeature "CLANG_MARCH_FLAG" "-march=") ]; # Fixes error: ld: cannot find -lgcc / -lgcc_s when linking from libpocl on # host preConfigure = '' cmakeFlagsArray+=( -DEXTRA_HOST_LD_FLAGS="${lib.escapeShellArg (builtins.readFile "${targetPackages.stdenv.cc}/nix-support/cc-ldflags")}" -DEXTRA_KERNEL_FLAGS="${lib.escapeShellArg (builtins.readFile "${targetPackages.stdenv.cc}/nix-support/cc-ldflags")}" ) ''; nativeBuildInputs = [ cmake getconf ninja pkg-config python3 ]; buildInputs = [ opencl-headers llvmPackages.libclang llvmPackages.llvm ] ++ lib.optionals staticLLVM [ libxml2 ] ++ lib.optionals enableNOSV [ nosv ] ++ lib.optionals enableOVNI [ ovni ] ++ lib.optionals enableHWLOC [ hwloc ] ++ lib.optionals enableTBB [ onetbb ] ++ lib.optionals enableICD [ ocl-icd ] ++ lib.optionals enableLTTNG [ lttng-ust ] ++ lib.optionals enableSPIRV [ (spirv-llvm-translator.override { inherit (llvmPackages) llvm; }) spirv-tools ]; nativeInstallCheckInputs = [ writableTmpDirAsHomeHook # needed for POCL_CACHE_DIR ]; doInstallCheck = true; installCheckPhase = lib.optionalString enableICD '' runHook preInstallCheck export OCL_ICD_VENDORS=$out/etc/OpenCL/vendors $out/bin/poclcc -o poclcc.cl.pocl $src/examples/poclcc/poclcc.cl runHook postInstallCheck ''; setupHook = lib.optionalDrvAttr enableICD ( writeText "setup-hook" '' addToSearchPath OCL_ICD_VENDORS @out@/etc/OpenCL/vendors '' ); passthru = let self = finalAttrs.finalPackage; in { updateScript = nix-update-script { }; git = self.override { useGit = true; }; withICD = enableICD; test = { # Run builtin tests (causes a rebuild) self = self.overrideAttrs { doCheck = true; }; # Run basic test from Khronos OpenCL Conformance Test Suite # WARN: despite its name, test_basic is very exhaustive, and can take more # than 1 hour in a marenostrum5 node. cts = assert enableICD; lib.genAttrs [ "api" "basic" "c11_atomics" "printf" "svm" ] ( name: runCommand "pocl-cts-test_${name}" { nativeBuildInputs = [ self ]; requiredSystemFeatures = [ "sys-devices" ]; env = { POCL_DEBUG = "error,warn"; POCL_CACHE_DIR = "/build/pocl_cache"; }; } "${opencl-cts}/bin/Release/test_${name} | tee $out" ); }; }; env.HWLOC_SYNTHETIC = lib.optionalDrvAttr enableHWLOC "node:1 core:1 pu:1"; propagatedBuildInputs = [ stdenv.cc.cc ]; meta = with lib; { description = "A portable open source (MIT-licensed) implementation of the OpenCL standard"; homepage = "http://portablecl.org"; license = licenses.mit; maintainers = with maintainers; [ leixb jansol xddxdd bsc.maintainers.leixb ]; platforms = platforms.linux ++ platforms.darwin; }; })