77import glob
88import sys
99import argparse
10+ import shutil
1011
1112SCRIPT_DIR = os .path .dirname (__file__ )
1213ROOT_DIR = os .path .abspath (os .getcwd ())
1920from wheel_builder_utils import push_dir , push_env
2021from windows_build_common import DEFAULT_PY_ENVS , venv_paths
2122
23+ def install_and_import (package ):
24+ """
25+ Install package with pip and import in current script.
26+ """
27+ import importlib
28+ try :
29+ importlib .import_module (package )
30+ except ImportError :
31+ import pip
32+ pip .main (['install' , package ])
33+ finally :
34+ globals ()[package ] = importlib .import_module (package )
35+
2236def build_wheels (py_envs = DEFAULT_PY_ENVS , cleanup = True , cmake_options = []):
2337 for py_env in py_envs :
2438 python_executable , \
@@ -64,6 +78,34 @@ def build_wheels(py_envs=DEFAULT_PY_ENVS, cleanup=True, cmake_options=[]):
6478 if cleanup :
6579 check_call ([python_executable , "setup.py" , "clean" ])
6680
81+ def rename_wheel_init (py_env , filepath ):
82+ """
83+ Rename module __init__ file in wheel.
84+ This is required to prevent modules to override ITK's __init__ file on install.
85+ If the module ships its own __init__ file, it is automatically renamed to
86+ __init_{module_name}__ by this function. The renamed __init__ file will be executed
87+ by ITK's __init__ file when loading ITK.
88+ """
89+ python_executable , python_include_dir , python_library , pip , ninja_executable , path = venv_paths (py_env )
90+
91+ # Get module info
92+ install_and_import ("pkginfo" )
93+ w = pkginfo .Wheel (filepath )
94+ module_name = w .name .split ("itk-" )[- 1 ]
95+ module_version = w .version
96+
97+ dist_dir = os .path .dirname (filepath )
98+ wheel_dir = os .path .join (dist_dir , "itk_" + module_name + "-" + module_version )
99+ init_dir = os .path .join (wheel_dir , "itk" )
100+ init_file = os .path .join (init_dir , "__init__.py" )
101+
102+ # Unpack wheel and rename __init__ file if it exists.
103+ check_call ([python_executable , "-m" , "wheel" , "unpack" , filepath , "-d" , dist_dir ])
104+ if os .path .isfile (init_file ):
105+ shutil .move (init_file , os .path .join (init_dir , "__init_" + module_name + "__.py" ))
106+ # Pack wheel and clean wheel folder
107+ check_call ([python_executable , "-m" , "wheel" , "pack" , wheel_dir , "-d" , dist_dir ])
108+ shutil .rmtree (wheel_dir )
67109
68110def fixup_wheel (py_envs , filepath , lib_paths :str = '' ):
69111 lib_paths = ';' .join (["C:/P/IPP/oneTBB-prefix/bin" ,lib_paths .strip ()]).strip (';' )
@@ -76,6 +118,10 @@ def fixup_wheel(py_envs, filepath, lib_paths:str=''):
76118 lib_paths , "--ignore-in-wheel" , "-w" ,
77119 os .path .join (ROOT_DIR , "dist" ), filepath ])
78120
121+ # The delve_wheel patch loading shared libraries is added to the module
122+ # __init__ file. Rename this file here to prevent conflicts on installation.
123+ # The renamed __init__ file will be executed when loading ITK.
124+ rename_wheel_init (py_env , filepath )
79125
80126def fixup_wheels (py_envs , lib_paths :str = '' ):
81127 # shared library fix-up
0 commit comments