Skip to content

Commit bff7c53

Browse files
authored
Merge pull request #169 from tbirdso/expose-library-paths
ENH: Add cross platform options for wheel repair with shared libraries
2 parents 1bdb236 + 4f0dfd2 commit bff7c53

7 files changed

+60
-12
lines changed

scripts/dockcross-manylinux-build-module-wheels.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
# For example,
88
#
99
# scripts/dockcross-manylinux-build-module-wheels.sh cp39
10+
#
11+
# Shared libraries can be included in the wheel by exporting them to LD_LIBRARY_PATH before
12+
# running this script.
13+
#
14+
# For example,
15+
#
16+
# export LD_LIBRARY_PATH="/path/to/OpenCL.so:/path/to/OpenCL.so.1.2"
17+
# scripts/dockcross-manylinux-build-module-wheels.sh cp39
18+
#
1019

1120
# Generate dockcross scripts
1221
docker run --rm dockcross/manylinux2014-x64:20210823-d7b98b4 > /tmp/dockcross-manylinux-x64
@@ -19,6 +28,13 @@ chmod 777 $(pwd)/tools
1928
# Build wheels
2029
mkdir -p dist
2130
DOCKER_ARGS="-v $(pwd)/dist:/work/dist/ -v $script_dir/..:/ITKPythonPackage -v $(pwd)/tools:/tools"
31+
# Mount any shared libraries
32+
if [[ -n ${LD_LIBRARY_PATH} ]]; then
33+
for libpath in ${LD_LIBRARY_PATH//:/ }; do
34+
DOCKER_ARGS+=" -v ${libpath}:/usr/lib64/$(basename -- ${libpath})"
35+
done
36+
fi
37+
2238
/tmp/dockcross-manylinux-x64 \
2339
-a "$DOCKER_ARGS" \
2440
"/ITKPythonPackage/scripts/internal/manylinux-build-module-wheels.sh" "$@"

scripts/internal/manylinux-build-module-wheels.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/usr/bin/env bash
22

3+
# Run this script inside a dockcross container to build Python wheels for an ITK module
4+
35
# -----------------------------------------------------------------------
46
# These variables are set in common script:
57
#
@@ -10,8 +12,9 @@ script_dir=$(cd $(dirname $0) || exit 1; pwd)
1012
source "${script_dir}/manylinux-build-common.sh"
1113
# -----------------------------------------------------------------------
1214

13-
# So auditwheel can find the libs
14-
export LD_LIBRARY_PATH=/work/oneTBB-prefix/lib64
15+
# Set up library paths in container so that shared libraries can be added to wheels
16+
sudo ldconfig
17+
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/work/oneTBB-prefix/lib64:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64
1518

1619
# Compile wheels re-using standalone project and archive cache
1720
for PYBIN in "${PYBINARIES[@]}"; do

scripts/internal/manylinux-build-wheels.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ pushd /work/ITK-source > /dev/null 2>&1
2020
popd > /dev/null 2>&1
2121
tbb_dir=/work/oneTBB-prefix/lib64/cmake/TBB
2222
# So auditwheel can find the libs
23-
export LD_LIBRARY_PATH=/work/oneTBB-prefix/lib64
23+
sudo ldconfig
24+
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/work/oneTBB-prefix/lib64:/usr/lib:/usr/lib64
2425

2526
SINGLE_WHEEL=0
2627

scripts/macpython-build-module-wheels.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ ${Python3_EXECUTABLE} -m pip install --no-cache delocate
2626
DELOCATE_LISTDEPS=${VENV}/bin/delocate-listdeps
2727
DELOCATE_WHEEL=${VENV}/bin/delocate-wheel
2828
# So delocate can find the libs
29-
export DYLD_LIBRARY_PATH=${script_dir}/../oneTBB-prefix/lib
29+
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${script_dir}/../oneTBB-prefix/lib
3030

3131
# Compile wheels re-using standalone project and archive cache
3232
for VENV in "${VENVS[@]}"; do
@@ -66,7 +66,7 @@ for VENV in "${VENVS[@]}"; do
6666
-DPython3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
6767
-DPython3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
6868
|| exit 1
69-
${Python3_EXECUTABLE} setup.py clean
69+
# ${Python3_EXECUTABLE} setup.py clean # Permission denied
7070
done
7171

7272
for wheel in $PWD/dist/*.whl; do

scripts/macpython-build-wheels.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ DELOCATE_PATCH=${VENV}/bin/delocate-patch
4444
# Build standalone project and populate archive cache
4545
tbb_dir=$PWD/oneTBB-prefix/lib/cmake/TBB
4646
# So delocate can find the libs
47-
export DYLD_LIBRARY_PATH=$PWD/oneTBB-prefix/lib
47+
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:$PWD/oneTBB-prefix/lib
4848
mkdir -p ITK-source
4949
pushd ITK-source > /dev/null 2>&1
5050
${CMAKE_EXECUTABLE} -DITKPythonPackage_BUILD_PYTHON:PATH=0 \

scripts/windows_build_module_wheels.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from subprocess import check_call
22
import os
3+
import glob
34
import sys
45
import argparse
56

67
SCRIPT_DIR = os.path.dirname(__file__)
78
ROOT_DIR = os.path.abspath(os.getcwd())
89

9-
1010
print("SCRIPT_DIR: %s" % SCRIPT_DIR)
1111
print("ROOT_DIR: %s" % ROOT_DIR)
1212

@@ -33,6 +33,7 @@ def build_wheels(py_envs=DEFAULT_PY_ENVS, cleanup=True, cmake_options=[]):
3333
check_call([pip, "install", "cmake"])
3434
check_call([pip, "install", "scikit_build"])
3535
check_call([pip, "install", "ninja"])
36+
check_call([pip, "install", "delvewheel"])
3637

3738
build_type = "Release"
3839
source_path = ROOT_DIR
@@ -59,12 +60,33 @@ def build_wheels(py_envs=DEFAULT_PY_ENVS, cleanup=True, cmake_options=[]):
5960
if cleanup:
6061
check_call([python_executable, "setup.py", "clean"])
6162

63+
64+
def fixup_wheel(py_envs, filepath, lib_paths:str=''):
65+
lib_paths = lib_paths.strip() if lib_paths.isspace() else lib_paths.strip() + ";"
66+
lib_paths += "C:/P/IPP/oneTBB-prefix/bin"
67+
print(f'Library paths for fixup: {lib_paths}')
68+
69+
py_env = py_envs[0]
70+
71+
delve_wheel = os.path.join(ROOT_DIR, "venv-" + py_env, "Scripts", "delvewheel.exe")
72+
check_call([delve_wheel, "repair", "--no-mangle-all", "--add-path",
73+
lib_paths, "--ignore-in-wheel", "-w",
74+
os.path.join(ROOT_DIR, "dist"), filepath])
75+
76+
77+
def fixup_wheels(py_envs, lib_paths:str=''):
78+
# shared library fix-up
79+
for wheel in glob.glob(os.path.join(ROOT_DIR, "dist", "*.whl")):
80+
fixup_wheel(py_envs, wheel, ';'.join(lib_paths))
81+
6282
if __name__ == '__main__':
6383
parser = argparse.ArgumentParser(description='Driver script to build ITK Python module wheels.')
6484
parser.add_argument('--py-envs', nargs='+', default=DEFAULT_PY_ENVS,
6585
help='Target Python environment versions, e.g. "37-x64".')
6686
parser.add_argument('--no-cleanup', dest='cleanup', action='store_false', help='Do not clean up temporary build files.')
87+
parser.add_argument('--lib-paths', nargs=1, default='', help='Add semicolon-delimited library directories for delvewheel to include in the module wheel')
6788
parser.add_argument('cmake_options', nargs='*', help='Extra options to pass to CMake, e.g. -DBUILD_SHARED_LIBS:BOOL=OFF')
6889
args = parser.parse_args()
6990

7091
build_wheels(cleanup=args.cleanup, py_envs=args.py_envs, cmake_options=args.cmake_options)
92+
fixup_wheels(args.py_envs, ';'.join(args.lib_paths))

scripts/windows_build_wheels.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,21 +219,26 @@ def build_wheel(python_version, single_wheel=False,
219219
shutil.rmtree(
220220
os.path.join(build_path, "Wrapping", "Generators", "CastXML"))
221221

222-
def fixup_wheel(py_envs, filepath):
222+
def fixup_wheel(py_envs, filepath, lib_paths:str=''):
223+
lib_paths = lib_paths.strip() if lib_paths.isspace() else lib_paths.strip() + ";"
224+
lib_paths += "C:/P/IPP/oneTBB-prefix/bin"
225+
print(f'Library paths for fixup: {lib_paths}')
226+
223227
py_env = py_envs[0]
228+
224229
delve_wheel = os.path.join(ROOT_DIR, "venv-" + py_env, "Scripts", "delvewheel.exe")
225230
check_call([delve_wheel, "repair", "--no-mangle-all", "--add-path",
226-
"C:/P/IPP/oneTBB-prefix/bin", "--ignore-in-wheel", "-w",
231+
lib_paths, "--ignore-in-wheel", "-w",
227232
os.path.join(ROOT_DIR, "dist"), filepath])
228233

229234

230-
def fixup_wheels(single_wheel, py_envs):
235+
def fixup_wheels(single_wheel, py_envs, lib_paths:str=''):
231236
# TBB library fix-up
232237
tbb_wheel = "itk_core"
233238
if single_wheel:
234239
tbb_wheel = "itk"
235240
for wheel in glob.glob(os.path.join(ROOT_DIR, "dist", tbb_wheel + "*.whl")):
236-
fixup_wheel(py_envs, wheel)
241+
fixup_wheel(py_envs, wheel, lib_paths)
237242

238243

239244
def test_wheels(python_env):
@@ -299,13 +304,14 @@ def main(wheel_names=None):
299304
parser.add_argument('--py-envs', nargs='+', default=DEFAULT_PY_ENVS,
300305
help='Target Python environment versions, e.g. "37-x64".')
301306
parser.add_argument('--no-cleanup', dest='cleanup', action='store_false', help='Do not clean up temporary build files.')
307+
parser.add_argument('--lib-paths', nargs=1, default='', help='Add semicolon-delimited library directories for delvewheel to include in the module wheel')
302308
parser.add_argument('cmake_options', nargs='*', help='Extra options to pass to CMake, e.g. -DBUILD_SHARED_LIBS:BOOL=OFF')
303309
args = parser.parse_args()
304310

305311
build_wheels(single_wheel=args.single_wheel, cleanup=args.cleanup,
306312
py_envs=args.py_envs, wheel_names=wheel_names,
307313
cmake_options=args.cmake_options)
308-
fixup_wheels(args.single_wheel, args.py_envs)
314+
fixup_wheels(args.single_wheel, args.py_envs, ';'.join(args.lib_paths))
309315
for py_env in args.py_envs:
310316
test_wheels(py_env)
311317

0 commit comments

Comments
 (0)