@@ -111,6 +111,22 @@ def _find_nvjpeg_libs():
111111 return list (found )
112112
113113
114+ def _find_nvjpeg_license ():
115+ # Try to find EULA.txt, fallback to LICENSE
116+ dirs = []
117+ for lib in _find_nvjpeg_libs ():
118+ dirs .extend (lib .parents )
119+ for var in ("CUDA_HOME" , "CUDA_PATH" , "CUDAToolkit_ROOT" ):
120+ if v := os .environ .get (var ):
121+ dirs .append (Path (v ))
122+ for filename in ("EULA.txt" , "LICENSE" ):
123+ for d in dirs :
124+ candidate = d / filename
125+ if candidate .is_file ():
126+ return candidate
127+ return None
128+
129+
114130def repair_linux (wheels ):
115131 run ([sys .executable , "-m" , "pip" , "install" , "--upgrade" , "auditwheel" ])
116132 run (["auditwheel" , "--version" ])
@@ -274,7 +290,8 @@ def bundle_third_party_licenses():
274290 statically embeds dav1d and libyuv) as binaries inside the wheel. Their
275291 permissive licenses (IJG/BSD/zlib) require reproducing the copyright notice
276292 and license text in binary redistributions, so we ship them next to our own
277- LICENSE.
293+ LICENSE. CUDA wheels additionally bundle libnvjpeg, redistributed under the
294+ NVIDIA CUDA Toolkit EULA, which we ship as well.
278295 """
279296
280297 def _resolve_conda_licenses ():
@@ -349,9 +366,9 @@ def _resolve_avif_licenses():
349366 return {f .name : f for f in sorted (dirs [0 ].iterdir ()) if f .is_file ()}
350367
351368 run ([sys .executable , "-m" , "pip" , "install" , "-U" , "wheel" ])
352- licenses = {** _resolve_conda_licenses (), ** _resolve_avif_licenses ()}
369+ base_licenses = {** _resolve_conda_licenses (), ** _resolve_avif_licenses ()}
353370 print ("Third-party license files to bundle:" )
354- for name , src in sorted (licenses .items ()):
371+ for name , src in sorted (base_licenses .items ()):
355372 print (f" { name } <- { src } " )
356373
357374 scratch = Path ("dist_licenses" )
@@ -360,6 +377,16 @@ def _resolve_avif_licenses():
360377 scratch .mkdir (parents = True )
361378
362379 for wheel in sorted (DIST_DIR .glob ("*.whl" )):
380+ licenses = dict (base_licenses )
381+ if _is_cuda_wheel (wheel ):
382+ if (nvjpeg_license := _find_nvjpeg_license ()) is None :
383+ raise RuntimeError (
384+ f"{ wheel .name } bundles libnvjpeg but the NVIDIA CUDA EULA "
385+ "could not be located to ship alongside it."
386+ )
387+ licenses ["LICENSE.libnvjpeg-NVIDIA-CUDA-EULA.txt" ] = nvjpeg_license
388+ print (f" LICENSE.libnvjpeg-NVIDIA-CUDA-EULA.txt <- { nvjpeg_license } " )
389+
363390 unpack_dir = scratch / "unpack"
364391 if unpack_dir .is_dir ():
365392 shutil .rmtree (unpack_dir )
@@ -550,16 +577,20 @@ def _assert_linux_libjpeg_is_turbo(zf):
550577 "found at build time."
551578 )
552579
553- def _assert_third_party_licenses (zf ):
580+ def _assert_third_party_licenses (zf , is_cuda ):
554581 """Every bundled third-party lib must ship its license text under
555582 .dist-info/licenses/third_party/ (see bundle_third_party_licenses)."""
556583 license_files = [
557584 n
558585 for n in zf .namelist ()
559586 if "/licenses/third_party/" in n and not n .endswith ("/" )
560587 ]
561- # keyword each bundled lib's license file must be identifiable by.
562- for keyword in ("jpeg" , "png" , "zlib" , "webp" , "avif" , "dav1d" , "yuv" ):
588+ # keyword each bundled lib's license file must be identifiable by. CUDA
589+ # wheels also bundle libnvjpeg, whose NVIDIA CUDA EULA must ship too.
590+ keywords = ["jpeg" , "png" , "zlib" , "webp" , "avif" , "dav1d" , "yuv" ]
591+ if is_cuda :
592+ keywords .append ("nvjpeg" )
593+ for keyword in keywords :
563594 if not any (keyword in n .lower () for n in license_files ):
564595 raise RuntimeError (
565596 f"No third-party license file matching '{ keyword } ' found in "
@@ -569,7 +600,7 @@ def _assert_third_party_licenses(zf):
569600 for wheel in DIST_DIR .glob ("*.whl" ):
570601 print (f"Checking bundled libraries in { wheel .name } " )
571602 with zipfile .ZipFile (wheel ) as zf :
572- _assert_third_party_licenses (zf )
603+ _assert_third_party_licenses (zf , _is_cuda_wheel ( wheel ) )
573604 names = zf .namelist ()
574605 libs = sorted ({n .rsplit ("/" , 1 )[- 1 ] for n in names if _is_shared_lib (n )})
575606 if unexpected := [lib for lib in libs if not _is_allowed (lib )]:
0 commit comments