2023-10-09 19:29:22 +00:00
# Type Aliases
#
# See ./extension.nix:
# - ReleaseAttrs
# - ReleaseFeaturesAttrs
#
# General callPackage-supplied arguments
2022-04-15 01:41:22 +00:00
{ lib
2023-04-12 12:48:02 +00:00
, stdenv
2023-03-08 16:32:21 +00:00
, backendStdenv
2022-04-15 01:41:22 +00:00
, fetchurl
, autoPatchelfHook
, autoAddOpenGLRunpathHook
2023-08-04 22:07:22 +00:00
, markForCudatoolkitRootHook
2023-10-09 19:29:22 +00:00
, lndir
, symlinkJoin
} :
# Function arguments
{
# Short package name (e.g., "cuda_cccl")
# pname : String
pname
, # Long package name (e.g., "CXX Core Compute Libraries")
# description : String
description
, # platforms : List System
platforms
, # version : Version
version
, # releaseAttrs : ReleaseAttrs
releaseAttrs
, # releaseFeaturesAttrs : ReleaseFeaturesAttrs
releaseFeaturesAttrs
,
2022-04-15 01:41:22 +00:00
} :
let
2023-10-09 19:29:22 +00:00
# Useful imports
inherit ( lib . lists ) optionals ;
inherit ( lib . meta ) getExe ;
inherit ( lib . strings ) optionalString ;
2023-03-08 16:32:21 +00:00
in
2023-11-16 04:20:00 +00:00
backendStdenv . mkDerivation ( finalAttrs : {
2023-10-09 19:29:22 +00:00
# NOTE: Even though there's no actual buildPhase going on here, the derivations of the
# redistributables are sensitive to the compiler flags provided to stdenv. The patchelf package
# is sensitive to the compiler flags provided to stdenv, and we depend on it. As such, we are
# also sensitive to the compiler flags provided to stdenv.
inherit pname version ;
strictDeps = true ;
2022-04-15 01:41:22 +00:00
2023-10-09 19:29:22 +00:00
outputs = with releaseFeaturesAttrs ;
[ " o u t " ]
++ optionals hasBin [ " b i n " ]
++ optionals hasLib [ " l i b " ]
++ optionals hasStatic [ " s t a t i c " ]
++ optionals hasDev [ " d e v " ]
++ optionals hasDoc [ " d o c " ]
++ optionals hasSample [ " s a m p l e " ] ;
src = fetchurl {
url = " h t t p s : / / d e v e l o p e r . d o w n l o a d . n v i d i a . c o m / c o m p u t e / c u d a / r e d i s t / ${ releaseAttrs . relative_path } " ;
inherit ( releaseAttrs ) sha256 ;
2022-04-15 01:41:22 +00:00
} ;
2023-10-09 19:29:22 +00:00
# We do need some other phases, like configurePhase, so the multiple-output setup hook works.
dontBuild = true ;
2022-04-15 01:41:22 +00:00
nativeBuildInputs = [
autoPatchelfHook
# This hook will make sure libcuda can be found
# in typically /lib/opengl-driver by adding that
# directory to the rpath of all ELF binaries.
# Check e.g. with `patchelf --print-rpath path/to/my/binary
autoAddOpenGLRunpathHook
2023-08-04 22:07:22 +00:00
markForCudatoolkitRootHook
2022-04-15 01:41:22 +00:00
] ;
buildInputs = [
2023-04-12 12:48:02 +00:00
# autoPatchelfHook will search for a libstdc++ and we're giving it
# one that is compatible with the rest of nixpkgs, even when
# nvcc forces us to use an older gcc
2023-03-08 16:32:21 +00:00
# NB: We don't actually know if this is the right thing to do
2023-04-12 12:48:02 +00:00
stdenv . cc . cc . lib
2022-04-15 01:41:22 +00:00
] ;
2023-04-29 16:46:19 +00:00
# Picked up by autoPatchelf
# Needed e.g. for libnvrtc to locate (dlopen) libnvrtc-builtins
appendRunpaths = [
" $ O R I G I N "
] ;
2023-10-09 19:29:22 +00:00
installPhase = with releaseFeaturesAttrs ;
# Pre-install hook
''
runHook preInstall
''
# doc and dev have special output handling. Other outputs need to be moved to their own
# output.
# Note that moveToOutput operates on all outputs:
# https://github.com/NixOS/nixpkgs/blob/2920b6fc16a9ed5d51429e94238b28306ceda79e/pkgs/build-support/setup-hooks/multiple-outputs.sh#L105-L107
+ ''
mkdir - p " $ o u t "
rm LICENSE
mv * " $ o u t "
''
# Handle bin, which defaults to out
+ optionalString hasBin ''
moveToOutput " b i n " " $ b i n "
''
# Handle lib, which defaults to out
+ optionalString hasLib ''
moveToOutput " l i b " " $ l i b "
''
# Handle static libs, which isn't handled by the setup hook
+ optionalString hasStatic ''
moveToOutput " * * / * . a " " $ s t a t i c "
''
# Handle samples, which isn't handled by the setup hook
+ optionalString hasSample ''
moveToOutput " s a m p l e s " " $ s a m p l e "
''
# Post-install hook
+ ''
runHook postInstall
'' ;
2022-04-15 01:41:22 +00:00
2023-10-09 19:29:22 +00:00
# The out output leverages the same functionality which backs the `symlinkJoin` function in
# Nixpkgs:
# https://github.com/NixOS/nixpkgs/blob/d8b2a92df48f9b08d68b0132ce7adfbdbc1fbfac/pkgs/build-support/trivial-builders/default.nix#L510
#
# That should allow us to emulate "fat" default outputs without having to actually create them.
#
# It is important that this run after the autoPatchelfHook, otherwise the symlinks in out will reference libraries in lib, creating a circular dependency.
postPhases = [ " p o s t P a t c h e l f " ] ;
# For each output, create a symlink to it in the out output.
# NOTE: We must recreate the out output here, because the setup hook will have deleted it
# if it was empty.
# NOTE: Do not use optionalString based on whether `outputs` contains only `out` -- phases
# which are empty strings are skipped/unset and result in errors of the form "command not
# found: <customPhaseName>".
postPatchelf = ''
mkdir - p " $ o u t "
for output in $ outputs ; do
if [ " $ o u t p u t " = " o u t " ] ; then
continue
fi
$ { getExe lndir } " ' ' ${ ! output } " " $ o u t "
done
2022-04-15 01:41:22 +00:00
'' ;
2023-10-09 19:29:22 +00:00
# Make the CUDA-patched stdenv available
2023-03-08 16:32:21 +00:00
passthru . stdenv = backendStdenv ;
2023-10-09 19:29:22 +00:00
# Setting propagatedBuildInputs to false will prevent outputs known to the multiple-outputs
# from depending on `out` by default.
# https://github.com/NixOS/nixpkgs/blob/2920b6fc16a9ed5d51429e94238b28306ceda79e/pkgs/build-support/setup-hooks/multiple-outputs.sh#L196
# Indeed, we want to do the opposite -- fat "out" outputs that contain all the other outputs.
propagatedBuildOutputs = false ;
# By default, if the dev output exists it just uses that.
# However, because we disabled propagatedBuildOutputs, dev doesn't contain libraries or
# anything of the sort. To remedy this, we set outputSpecified to true, and use
# outputsToInstall, which tells Nix which outputs to use when the package name is used
# unqualified (that is, without an explicit output).
outputSpecified = true ;
2022-04-15 01:41:22 +00:00
meta = {
2023-11-16 04:20:00 +00:00
inherit platforms ;
description = " ${ description } . B y d o w n l o a d i n g a n d u s i n g t h e p a c k a g e s y o u a c c e p t t h e t e r m s a n d c o n d i t i o n s o f t h e ${ finalAttrs . meta . license . shortName } " ;
license = lib . licenses . nvidiaCudaRedist // {
url = " h t t p s : / / d e v e l o p e r . d o w n l o a d . n v i d i a . c o m / c o m p u t e / c u d a / r e d i s t / ${ releaseAttrs . license_path or " ${ pname } / L I C E N S E . t x t " } " ;
} ;
sourceProvenance = [ lib . sourceTypes . binaryNativeCode ] ;
2023-05-24 13:37:59 +00:00
maintainers = lib . teams . cuda . members ;
2023-10-09 19:29:22 +00:00
# Force the use of the default, fat output by default (even though `dev` exists, which
# causes Nix to prefer that output over the others if outputSpecified isn't set).
outputsToInstall = [ " o u t " ] ;
2022-04-15 01:41:22 +00:00
} ;
2023-11-16 04:20:00 +00:00
} )