@@ -150,10 +150,11 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
150
150
wheel_files : DefaultDict [str , List [Tuple [pathlib .Path , str ]]] = collections .defaultdict (list )
151
151
packages : Dict [str , str ] = {}
152
152
153
- for group in sources .values ():
153
+ for key , group in sources .items ():
154
154
for src , target in group .items ():
155
155
destination = pathlib .Path (target ['destination' ])
156
156
anchor = destination .parts [0 ]
157
+ dst = pathlib .Path (* destination .parts [1 :])
157
158
158
159
path = _INSTALLATION_PATH_MAP .get (anchor )
159
160
if path is None :
@@ -170,7 +171,28 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
170
171
f'{ this !r} and { that !r} , a "pure: false" argument may be missing in meson.build. '
171
172
f'It is recommended to set it in "import(\' python\' ).find_installation()"' )
172
173
173
- wheel_files [path ].append ((pathlib .Path (* destination .parts [1 :]), src ))
174
+ if key == 'install_subdirs' :
175
+ assert os .path .isdir (src )
176
+ exclude_files = {os .path .normpath (x ) for x in target .get ('exclude_files' , [])}
177
+ exclude_dirs = {os .path .normpath (x ) for x in target .get ('exclude_dirs' , [])}
178
+ for root , dirnames , filenames in os .walk (src ):
179
+ for name in dirnames .copy ():
180
+ dirsrc = os .path .join (root , name )
181
+ relpath = os .path .relpath (dirsrc , src )
182
+ if relpath in exclude_dirs :
183
+ dirnames .remove (name )
184
+ # sort to process directories determninistically
185
+ dirnames .sort ()
186
+ for name in sorted (filenames ):
187
+ filesrc = os .path .join (root , name )
188
+ relpath = os .path .relpath (filesrc , src )
189
+ if relpath in exclude_files :
190
+ continue
191
+ filedst = dst / relpath
192
+ wheel_files [path ].append ((filedst , filesrc ))
193
+ else :
194
+ wheel_files [path ].append ((dst , src ))
195
+
174
196
return wheel_files
175
197
176
198
@@ -416,7 +438,7 @@ def _is_native(self, file: Union[str, pathlib.Path]) -> bool:
416
438
return True
417
439
return False
418
440
419
- def _install_path ( # noqa: C901
441
+ def _install_path (
420
442
self ,
421
443
wheel_file : mesonpy ._wheelfile .WheelFile ,
422
444
origin : Path ,
@@ -430,51 +452,39 @@ def _install_path( # noqa: C901
430
452
"""
431
453
location = destination .as_posix ()
432
454
433
- # fix file
434
- if os .path .isdir (origin ):
435
- for root , dirnames , filenames in os .walk (str (origin )):
436
- # Sort the directory names so that `os.walk` will walk them in a
437
- # defined order on the next iteration.
438
- dirnames .sort ()
439
- for name in sorted (filenames ):
440
- path = os .path .normpath (os .path .join (root , name ))
441
- if os .path .isfile (path ):
442
- arcname = os .path .join (destination , os .path .relpath (path , origin ).replace (os .path .sep , '/' ))
443
- wheel_file .write (path , arcname )
444
- else :
445
- if self ._has_internal_libs :
446
- if platform .system () == 'Linux' or platform .system () == 'Darwin' :
447
- # add .mesonpy.libs to the RPATH of ELF files
448
- if self ._is_native (os .fspath (origin )):
449
- # copy ELF to our working directory to avoid Meson having to regenerate the file
450
- new_origin = self ._libs_build_dir / pathlib .Path (origin ).relative_to (self ._build_dir )
451
- os .makedirs (new_origin .parent , exist_ok = True )
452
- shutil .copy2 (origin , new_origin )
453
- origin = new_origin
454
- # add our in-wheel libs folder to the RPATH
455
- if platform .system () == 'Linux' :
456
- elf = mesonpy ._elf .ELF (origin )
457
- libdir_path = \
458
- f'$ORIGIN/{ os .path .relpath (f".{ self ._project .name } .mesonpy.libs" , destination .parent )} '
459
- if libdir_path not in elf .rpath :
460
- elf .rpath = [* elf .rpath , libdir_path ]
461
- elif platform .system () == 'Darwin' :
462
- dylib = mesonpy ._dylib .Dylib (origin )
463
- libdir_path = \
464
- f'@loader_path/{ os .path .relpath (f".{ self ._project .name } .mesonpy.libs" , destination .parent )} '
465
- if libdir_path not in dylib .rpath :
466
- dylib .rpath = [* dylib .rpath , libdir_path ]
467
- else :
468
- # Internal libraries are currently unsupported on this platform
469
- raise NotImplementedError ("Bundling libraries in wheel is not supported on platform '{}'"
470
- .format (platform .system ()))
471
-
472
- try :
473
- wheel_file .write (origin , location )
474
- except FileNotFoundError :
475
- # work around for Meson bug, see https://github.com/mesonbuild/meson/pull/11655
476
- if not os .fspath (origin ).endswith ('.pdb' ):
477
- raise
455
+ if self ._has_internal_libs :
456
+ if platform .system () == 'Linux' or platform .system () == 'Darwin' :
457
+ # add .mesonpy.libs to the RPATH of ELF files
458
+ if self ._is_native (os .fspath (origin )):
459
+ # copy ELF to our working directory to avoid Meson having to regenerate the file
460
+ new_origin = self ._libs_build_dir / pathlib .Path (origin ).relative_to (self ._build_dir )
461
+ os .makedirs (new_origin .parent , exist_ok = True )
462
+ shutil .copy2 (origin , new_origin )
463
+ origin = new_origin
464
+ # add our in-wheel libs folder to the RPATH
465
+ if platform .system () == 'Linux' :
466
+ elf = mesonpy ._elf .ELF (origin )
467
+ libdir_path = \
468
+ f'$ORIGIN/{ os .path .relpath (f".{ self ._project .name } .mesonpy.libs" , destination .parent )} '
469
+ if libdir_path not in elf .rpath :
470
+ elf .rpath = [* elf .rpath , libdir_path ]
471
+ elif platform .system () == 'Darwin' :
472
+ dylib = mesonpy ._dylib .Dylib (origin )
473
+ libdir_path = \
474
+ f'@loader_path/{ os .path .relpath (f".{ self ._project .name } .mesonpy.libs" , destination .parent )} '
475
+ if libdir_path not in dylib .rpath :
476
+ dylib .rpath = [* dylib .rpath , libdir_path ]
477
+ else :
478
+ # Internal libraries are currently unsupported on this platform
479
+ raise NotImplementedError ("Bundling libraries in wheel is not supported on platform '{}'"
480
+ .format (platform .system ()))
481
+
482
+ try :
483
+ wheel_file .write (origin , location )
484
+ except FileNotFoundError :
485
+ # work around for Meson bug, see https://github.com/mesonbuild/meson/pull/11655
486
+ if not os .fspath (origin ).endswith ('.pdb' ):
487
+ raise
478
488
479
489
def _wheel_write_metadata (self , whl : mesonpy ._wheelfile .WheelFile ) -> None :
480
490
# add metadata
0 commit comments