To follow up on ITK 5.3 Release Candidate 4 available for testing, I may have identified few issues found with itk 5.3rc4.post3 specific to macOS that are related to the bundling of libtbb.12.3.dylib
.
Context
While the issue was discovered while testing the use of itk wheels in the context of Slicer PR-6564, it was reproduced in the regular python interpreter available in the Slicer distribution.
The system used was the following:
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G14033
How to reproduce ?
After installing the wheels on macOS 10.13.6 and attempting to trigger the loading of _ITKCommonPython.so
simply using print(itk.Image)
, the following error is reported:
$ PYTHONPATH=$itk_wheels_install_prefix/lib/python3.9/site-packages/:$itk_wheels_install_prefix/lib/python3.9/site-packages/itk \
$slicer_build_dir/python-install/bin/PythonSlicer -c "import itk; print(itk.Image)"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/support/lazy.py", line 138, in __getattribute__
base.itk_load_swig_module(module, namespace)
File "/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/support/base.py", line 96, in itk_load_swig_module
itk_load_swig_module(dep, namespace)
File "/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/support/base.py", line 132, in itk_load_swig_module
l_module = loader.load(swig_module_name)
File "/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/support/base.py", line 291, in load
l_spec.loader.exec_module(l_module) # pytype: disable=attribute-error
File "<frozen importlib._bootstrap_external>", line 850, in exec_module
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/support/../ITKPyBasePython.py", line 69, in <module>
from itk.pyBasePython import *
File "/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/pyBasePython.py", line 15, in <module>
from . import _ITKCommonPython
ImportError: dlopen(/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/_ITKCommonPython.so, 2): Library not loaded: @loader_path/.dylibs/libtbb.12.3.dylib
Referenced from: /tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/_ITKCommonPython.so
Reason: no suitable image found. Did find:
/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/.dylibs/libtbb.12.3.dylib: cannot load 'libtbb.12.3.dylib' (load command 0x80000034 is unknown)
/private/tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/.dylibs/libtbb.12.3.dylib: cannot load 'libtbb.12.3.dylib' (load command 0x80000034 is unknown)
Inspecting the libtbb.12.3.dylib
library shipped within the wheels prefix with -cp39-cp39-macosx_10_9_x86_64
, it looks like the library was not built to target maOS 10.9:
$ cd /tmp/itk-wheels-installed/lib/python3.9/site-packages/itk/.dylibs/
$ otool -l libtbb.12.3.dylib | grep -E -A4 '(LC_VERSION_MIN_MACOSX|LC_BUILD_VERSION)' | grep -B1 sdk
platform macos
sdk 12.1
Additionally, it seems the library id is incorrect, instead of the hardcoded path /DLC/itk/.dylibs/libtbb.12.3.dylib
, it should be libtbb.12.3.dylib
:
$ otool -L libtbb.12.3.dylib
libtbb.12.3.dylib:
/DLC/itk/.dylibs/libtbb.12.3.dylib (compatibility version 12.0.0, current version 12.3.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1200.3.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
… and attempting to change it is also failing:
$ install_name_tool -id libtbb.12.3.dylib ./libtbb.12.3.dylib
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool: object: ./libtbb.12.3.dylib malformed object (unknown load command 5)
Suggested path forward
Since the version of TBB currently built by ITKPythonPackage
is v2021.3.0.tar.gz
(See here) and the logic related to the minimum deployment target is setting the variables CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG
and CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG
(see here), the corresponding options should be passed when building oneTBB in ITKPythonPackage/CMakeLists.txt
-DCMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG:STRING="-mmacosx-version-min=${osx_deployment_target}"
-DCMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG:STRING="-mmacosx-version-min=${osx_deployment_target}"
where osx_deployment_target
is set based on the logic already implemented in ITKPythonPackage/scripts/macpython-build-wheels.sh.