From 072d508a71dcc4ca4b79edb54f2f8b8650d4e9c8 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Tue, 23 Sep 2025 17:22:55 +0000 Subject: [PATCH] cudaPackages.tests.cmake: init Signed-off-by: Connor Baker --- .../packages/tests/cmake/package.nix | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 pkgs/development/cuda-modules/packages/tests/cmake/package.nix diff --git a/pkgs/development/cuda-modules/packages/tests/cmake/package.nix b/pkgs/development/cuda-modules/packages/tests/cmake/package.nix new file mode 100644 index 000000000000..3a1ce899624d --- /dev/null +++ b/pkgs/development/cuda-modules/packages/tests/cmake/package.nix @@ -0,0 +1,203 @@ +{ + backendStdenv, + cmake, + cuda_cudart, + cuda_nvcc, + cudaNamePrefix, + fetchpatch2, + flags, + lib, + srcOnly, + stdenv, + stdenvNoCC, +}: +let + inherit (backendStdenv) cc; + inherit (lib.attrsets) mapAttrs optionalAttrs recurseIntoAttrs; + inherit (lib.fixedPoints) composeExtensions toExtension; + inherit (lib.lists) optionals; + inherit (lib.strings) + cmakeBool + cmakeFeature + optionalString + versionAtLeast + ; + + cmake' = cmake.overrideAttrs (prevAttrs: { + patches = prevAttrs.patches or [ ] ++ [ + # Fix errors during configuration when C/CXX is not loaded + # https://gitlab.kitware.com/cmake/cmake/-/merge_requests/10354 + (fetchpatch2 { + name = "find-cuda-toolkit-check-for-language-enablement.patch"; + url = "https://gitlab.kitware.com/cmake/cmake/-/commit/c5d81a246852e1ad81a3d55fcaff7e6feb779db7.patch"; + hash = "sha256-oGxzbp+x88+79V+Cyx0l7+nMxX+n3ixzAFKPK26NMI8="; + }) + # https://gitlab.kitware.com/cmake/cmake/-/merge_requests/10289 + (fetchpatch2 { + name = "update-arch-supported-by-cuda-12_8.patch"; + url = "https://gitlab.kitware.com/cmake/cmake/-/commit/a745b6869ee3681e39544d96d936c95c196c7398.patch"; + hash = "sha256-B6ny6AZFIcyFhsEnzNk7+vJTb36HeguM53sk/LCnjS4="; + }) + ]; + }); + + isBroken = _: prevAttrs: { + meta = prevAttrs.meta or { } // { + broken = true; + }; + }; + + cmakeSrc = srcOnly { + name = "cmake-unpacked"; + inherit (cmake) src version; + stdenv = stdenvNoCC; + }; + + mkTest = + let + generic = stdenv.mkDerivation (finalAttrs: { + __structuredAttrs = true; + strictDeps = true; + + testSuiteName = builtins.throw "testSuiteName must be set"; + testName = builtins.throw "testName must be set"; + + name = "${cudaNamePrefix}-${finalAttrs.pname}-${finalAttrs.version}"; + pname = "tests-cmake-${finalAttrs.testSuiteName}-${finalAttrs.testName}"; + inherit (cmakeSrc) version; + + src = cmakeSrc; + + setSourceRoot = '' + sourceRoot="$(echo */Tests/${finalAttrs.testSuiteName}/${finalAttrs.testName})" + ''; + + nativeBuildInputs = [ + cmake' + cuda_nvcc + ]; + + # If our compiler uses C++14, we must modify the CMake files so they don't hardcode C++11. + # This behavior has only been seen with GCC 14, but it's possible Clang would also require this. + requireCxxStandard14 = cc.isGNU && versionAtLeast cc.version "14"; + + cmakeListsReplacements = optionalAttrs finalAttrs.requireCxxStandard14 { + "cuda_std_11" = "cuda_std_14"; + "cxx_std_11" = "cxx_std_14"; + "set(CMAKE_CUDA_STANDARD 11)" = "set(CMAKE_CUDA_STANDARD 14)"; + "set(CMAKE_CXX_STANDARD 11)" = "set(CMAKE_CXX_STANDARD 14)"; + }; + + prePatch = optionalString finalAttrs.requireCxxStandard14 '' + for key in "''${!cmakeListsReplacements[@]}"; do + if grep -q "$key" CMakeLists.txt; then + nixLog "replacing occurrences of \"$key\" with \"''${cmakeListsReplacements[$key]}\" in $PWD/CMakeLists.txt" + substituteInPlace CMakeLists.txt --replace-fail "$key" "''${cmakeListsReplacements[$key]}" + fi + done + ''; + + buildInputs = [ + cuda_cudart + ]; + + cmakeFlags = [ + (cmakeBool "CMAKE_VERBOSE_MAKEFILE" true) + (cmakeFeature "CMAKE_CUDA_ARCHITECTURES" flags.cmakeCudaArchitecturesString) + ] + ++ optionals finalAttrs.requireCxxStandard14 [ + (cmakeFeature "CMAKE_CXX_STANDARD" "14") + (cmakeFeature "CMAKE_CUDA_STANDARD" "14") + ]; + + # The build *is* the check. + doCheck = false; + + installPhase = '' + runHook preInstall + touch "$out" + runHook postInstall + ''; + + # Don't try to run stuff in the patch phase as the setup hooks will error on empty output. + dontFixup = true; + + meta = { + description = "Generic builder for running CMake tests"; + license = lib.licenses.mit; + maintainers = lib.teams.cuda.members; + platforms = [ + "aarch64-linux" + "x86_64-linux" + ]; + }; + }); + in + testSuiteName: testName: overrideAttrsArg: + generic.overrideAttrs ( + composeExtensions (toExtension { inherit testSuiteName testName; }) (toExtension overrideAttrsArg) + ); +in +recurseIntoAttrs ( + mapAttrs (testSuiteName: testSuite: recurseIntoAttrs (mapAttrs (mkTest testSuiteName) testSuite)) { + # TODO: Handle set(Cuda.Toolkit_BUILD_OPTIONS -DHAS_CUPTI:BOOL=${CMake_TEST_CUDA_CUPTI}) + # from Tests/Cuda/CMakeLists.txt + Cuda = { + Complex = { }; + CXXStandardSetTwice = { }; + IncludePathNoToolkit = { }; + MixedStandardLevels1 = { }; + MixedStandardLevels2 = { }; + MixedStandardLevels3 = { }; + MixedStandardLevels4 = if cc.isClang then isBroken else { }; + MixedStandardLevels5 = if cc.isClang then isBroken else { }; + NotEnabled = { }; + ObjectLibrary = { }; + ProperDeviceLibraries = + if cc.isClang then + isBroken # Clang lacks __CUDACC_VER*__ defines. + else + isBroken; # TODO: Fix + ProperLinkFlags = { }; + SeparableCompCXXOnly = { }; + SharedRuntimePlusToolkit = isBroken; # TODO: Fix + StaticRuntimePlusToolkit = isBroken; # TODO: Fix + StubRPATH = { }; + Toolkit = isBroken; # TODO: Fix + ToolkitBeforeLang = if cc.isClang then isBroken else { }; # Clang lacks __CUDACC_VER*__ defines. + WithC = { }; + }; + # TODO: Handle set(CudaOnly.Toolkit_BUILD_OPTIONS -DHAS_CUPTI:BOOL=${CMake_TEST_CUDA_CUPTI}) + # from Tests/CudaOnly/CMakeLists.txt + CudaOnly = { + Architecture = { }; + ArchSpecial = isBroken; # Tries to detect the native architecture, which is impure. + CircularLinkLine = { }; + CompileFlags = { }; + CUBIN = if cc.isClang then isBroken else { }; # Only NVCC defines __CUDACC_DEBUG__ when compiling in debug mode. + DeviceLTO = isBroken; # TODO: Fix + DontResolveDeviceSymbols = { }; + EnableStandard = { }; + ExportPTX = { }; + Fatbin = if cc.isClang then isBroken else { }; # Only NVCC defines __CUDACC_DEBUG__ when compiling in debug mode. + GPUDebugFlag = if cc.isClang then isBroken else { }; # Only NVCC defines __CUDACC_DEBUG__ when compiling in debug mode. + OptixIR = if cc.isClang then isBroken else { }; # Only NVCC defines __CUDACC_DEBUG__ when compiling in debug mode. + PDB = isBroken; # Tests for features that only work with MSVC + ResolveDeviceSymbols = { }; + RuntimeControls = { }; + SeparateCompilation = { }; + SeparateCompilationPTX = isBroken; # TODO: Fix + SeparateCompilationTargetObjects = { }; + SharedRuntimePlusToolkit = isBroken; # TODO: Fix + SharedRuntimeViaCUDAFlags = if cc.isClang then isBroken else { }; # Clang doesn't have flags for selecting the runtime. + Standard98 = if cc.isClang then isBroken else { }; + StaticRuntimePlusToolkit = isBroken; # TODO: Fix + Toolkit = isBroken; # TODO: Fix + ToolkitBeforeLang = { }; + ToolkitMultipleDirs = { }; + TryCompileTargetStatic = { }; + Unity = { }; + WithDefs = { }; + }; + } +)