1{
2 stdenv,
3 lib,
4 addDriverRunpath,
5 fetchFromGitHub,
6 pkg-config,
7 elfutils,
8 libcap,
9 libseccomp,
10 rpcsvc-proto,
11 libtirpc,
12 makeWrapper,
13 removeReferencesTo,
14 replaceVars,
15 applyPatches,
16 nvidia-modprobe,
17 go,
18}:
19let
20 modprobeVersion = "550.54.14";
21 patchedModprobe = applyPatches {
22 src = nvidia-modprobe.src.override {
23 version = modprobeVersion;
24 hash = "sha256-iBRMkvOXacs/llTtvc/ZC5i/q9gc8lMuUHxMbu8A+Kg=";
25 };
26 patches = [
27 (replaceVars ./modprobe.patch {
28 inherit modprobeVersion;
29 })
30 ];
31 };
32in
33stdenv.mkDerivation (finalAttrs: {
34 pname = "libnvidia-container";
35 version = "1.17.8";
36
37 src = fetchFromGitHub {
38 owner = "NVIDIA";
39 repo = "libnvidia-container";
40 tag = "v${finalAttrs.version}";
41 hash = "sha256-OzjcYxnWjzgmrjERyPN3Ch3EQj4t1J5/TbATluoDESg=";
42 };
43
44 patches = [
45 # Locations of nvidia driver libraries are not resolved via ldconfig which
46 # doesn't get used on NixOS.
47 (replaceVars ./0001-ldcache-don-t-use-ldcache.patch {
48 inherit (addDriverRunpath) driverLink;
49 })
50
51 # Use both PATH and the legacy nvidia-docker paths (NixOS artifacts)
52 # for binary lookups.
53 # TODO: Remove the legacy compatibility once nvidia-docker is removed
54 # from NixOS.
55 (replaceVars ./0002-nvc-nvidia-docker-compatible-binary-lookups.patch {
56 inherit (addDriverRunpath) driverLink;
57 })
58
59 # fix bogus struct declaration
60 ./0003-nvc-fix-struct-declaration.patch
61 ];
62
63 postPatch = ''
64 sed -i \
65 -e 's/^REVISION ?=.*/REVISION = ${finalAttrs.src.tag}/' \
66 -e 's/^COMPILER :=.*/COMPILER = $(CC)/' \
67 mk/common.mk
68
69 sed -i \
70 -e 's/^GIT_TAG ?=.*/GIT_TAG = ${finalAttrs.version}/' \
71 -e 's/^GIT_COMMIT ?=.*/GIT_COMMIT = ${finalAttrs.src.tag}/' \
72 versions.mk
73
74 mkdir -p deps/src/nvidia-modprobe-${modprobeVersion}
75 cp -r ${patchedModprobe}/* deps/src/nvidia-modprobe-${modprobeVersion}
76 chmod -R u+w deps/src
77 pushd deps/src
78
79 touch nvidia-modprobe-${modprobeVersion}/.download_stamp
80 popd
81
82 # 1. replace DESTDIR=$(DEPS_DIR) with empty strings to prevent copying
83 # things into deps/src/nix/store
84 # 2. similarly, remove any paths prefixed with DEPS_DIR
85 # 3. prevent building static libraries because we don't build static
86 # libtirpc (for now)
87 # 4. prevent installation of static libraries because of step 3
88 # 5. prevent installation of libnvidia-container-go.so twice
89 # 6. Replace pkg-config and objcopy with target platform's one
90 # 7. Stub ldconfig
91 #
92 sed -i Makefile \
93 -e 's#DESTDIR=\$(DEPS_DIR)#DESTDIR=""#g' \
94 -e 's#\$(DEPS_DIR)\$#\$#g' \
95 -e 's#all: shared static tools#all: shared tools#g' \
96 -e '/$(INSTALL) -m 644 $(LIB_STATIC) $(DESTDIR)$(libdir)/d' \
97 -e '/$(INSTALL) -m 755 $(libdir)\/$(LIBGO_SHARED) $(DESTDIR)$(libdir)/d' \
98 -e "s,pkg-config,$PKG_CONFIG,g"
99 substituteInPlace mk/common.mk \
100 --replace-fail objcopy '$(OBJCOPY)' \
101 --replace-fail ldconfig true
102 '';
103
104 # Recreate library symlinks which ldconfig would have created
105 postFixup = ''
106 for lib in libnvidia-container libnvidia-container-go; do
107 rm -f "$out/lib/$lib.so"
108 ln -s "$out/lib/$lib.so.${finalAttrs.version}" "$out/lib/$lib.so.1"
109 ln -s "$out/lib/$lib.so.1" "$out/lib/$lib.so"
110 done
111 '';
112
113 enableParallelBuilding = true;
114
115 preBuild = ''
116 HOME="$(mktemp -d)"
117 '';
118
119 env = {
120 NIX_CFLAGS_COMPILE = toString [ "-I${lib.getInclude libtirpc}/include/tirpc" ];
121 CGO_ENABLED = "1"; # Needed for cross-compilation
122 GOFLAGS = "-trimpath"; # Don't include paths to Go stdlib to resulting binary
123 inherit (go) GOARCH GOOS;
124 };
125 NIX_LDFLAGS = [
126 "-L${lib.getLib libtirpc}/lib"
127 "-ltirpc"
128 ];
129
130 nativeBuildInputs = [
131 pkg-config
132 go
133 rpcsvc-proto
134 makeWrapper
135 removeReferencesTo
136 ];
137
138 buildInputs = [
139 elfutils
140 libcap
141 libseccomp
142 libtirpc
143 ];
144
145 makeFlags = [
146 "WITH_LIBELF=yes"
147 "prefix=$(out)"
148 # we can't use the WITH_TIRPC=yes flag that exists in the Makefile for the
149 # same reason we patch out the static library use of libtirpc so we set the
150 # define in CFLAGS
151 "CFLAGS=-DWITH_TIRPC"
152 ];
153
154 postInstall =
155 let
156 inherit (addDriverRunpath) driverLink;
157 libraryPath = lib.makeLibraryPath [
158 "$out"
159 driverLink
160 "${driverLink}-32"
161 ];
162 in
163 ''
164 remove-references-to -t "${go}" $out/lib/libnvidia-container-go.so.${finalAttrs.version}
165 wrapProgram $out/bin/nvidia-container-cli --prefix LD_LIBRARY_PATH : ${libraryPath}
166 '';
167 disallowedReferences = [ go ];
168
169 meta = {
170 homepage = "https://github.com/NVIDIA/libnvidia-container";
171 description = "NVIDIA container runtime library";
172 license = lib.licenses.asl20;
173 platforms = lib.platforms.linux;
174 mainProgram = "nvidia-container-cli";
175 maintainers = with lib.maintainers; [
176 cpcloud
177 msanft
178 katexochen
179 ];
180 };
181})