# itk 5.3rc4.post3: Failure to load libtbb library (observed on macOS 10.13)

**URL:** https://discourse.itk.org/t/itk-5-3rc4-post3-failure-to-load-libtbb-library-observed-on-macos-10-13/5405
**Category:** Engineering
**Tags:** itk-releases, python
**Created:** [October 11, 2022, 2:31am UTC](https://discourse.itk.org/t/itk-5-3rc4-post3-failure-to-load-libtbb-library-observed-on-macos-10-13/5405 "2022-10-11T02:31:56Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![jcfr](https://discourse.itk.org/user_avatar/discourse.itk.org/jcfr/32/2526_2.png) [@jcfr](https://discourse.itk.org/u/jcfr)
#### Post date: [October 11, 2022, 2:31am UTC](https://discourse.itk.org/t/itk-5-3rc4-post3-failure-to-load-libtbb-library-observed-on-macos-10-13/5405/1 "2022-10-11T02:31:56Z")

</div>

To follow up on [ITK 5.3 Release Candidate 4 available for testing](https://discourse.itk.org/t/itk-5-3-release-candidate-4-available-for-testing/5290), I may have identified few issues found with [itk 5.3rc4.post3](https://pypi.org/project/itk/5.3rc4.post3/#files) 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](https://github.com/Slicer/Slicer/pull/6564), it was reproduced in the regular python interpreter available in the Slicer distribution.

The system used was the following:

```bash
$ 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:

```bash
$ 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](https://stackoverflow.com/questions/17143373/determine-minimum-osx-version-a-binary-was-compiled-for#comment121691803_17143373) 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:

```auto
$ 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`:

```auto
$ 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:

```auto
$ 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](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/99857101d1433e61011648a2663a01fa1bf967b1/CMakeLists.txt#L109-L110)) 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](https://github.com/oneapi-src/oneTBB/blob/v2021.3.0/CMakeLists.txt#L32-L39)), the corresponding options should be passed when building oneTBB in [ITKPythonPackage/CMakeLists.txt](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/99857101d1433e61011648a2663a01fa1bf967b1/CMakeLists.txt#L108-L125)

```auto
-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](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/99857101d1433e61011648a2663a01fa1bf967b1/scripts/macpython-build-wheels.sh#L87-L96).

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [October 17, 2022, 7:10pm UTC](https://discourse.itk.org/t/itk-5-3rc4-post3-failure-to-load-libtbb-library-observed-on-macos-10-13/5405/2 "2022-10-17T19:10:07Z")

</div>

@jcfr thanks for the investigation and digging into this issue.

I am surprise that the [package tests](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/c264f7f789879e21819eab794607ea491adf0d8e/scripts/macpython-build-wheels.sh#L217-L229) were still passing.

> [@jcfr](#):
>
> ### Suggested path forward
> 
> Since the version of TBB currently built by `ITKPythonPackage` is `v2021.3.0.tar.gz` (See [here](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/99857101d1433e61011648a2663a01fa1bf967b1/CMakeLists.txt#L109-L110)) 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](https://github.com/oneapi-src/oneTBB/blob/v2021.3.0/CMakeLists.txt#L32-L39)), the corresponding options should be passed when building oneTBB in [ITKPythonPackage/CMakeLists.txt](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/99857101d1433e61011648a2663a01fa1bf967b1/CMakeLists.txt#L108-L125)
> 
> ```auto
> -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](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/99857101d1433e61011648a2663a01fa1bf967b1/scripts/macpython-build-wheels.sh#L87-L96).

👍 could you please create a PR so you get credit for this fix?

---

<div class="post-metadata">

### Author: ![jcfr](https://discourse.itk.org/user_avatar/discourse.itk.org/jcfr/32/2526_2.png) [@jcfr](https://discourse.itk.org/u/jcfr)
#### Post date: [November 2, 2022, 9:05pm UTC](https://discourse.itk.org/t/itk-5-3rc4-post3-failure-to-load-libtbb-library-observed-on-macos-10-13/5405/3 "2022-11-02T21:05:27Z")

</div>

### Pull request

> create a PR

Here is a pull request to ensure the TBB library have the expected deployment target.  
See [https://github.com/InsightSoftwareConsortium/ITKPythonPackage/pull/216](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/pull/216).

Once this is being tested, we will be able to also assess if additional option need to be passed to ensure the `library id ` is not hardcoded to `/DLC/itk/.dylibs/libtbb.12.3.dylib`

### `_ITKCommonPython.so` vs `libtbb.12.3.dylib`

For comparison, here is the output associated with a compiled module (e.g `_ITKCommonPython.so`) having its deployment target set:

```bash
$ otool -l ./itk/_ITKCommonPython.so | grep -E -A4 '(LC_VERSION_MIN_MACOSX|LC_BUILD_VERSION)' | grep -B1 sdk
  version 10.9
      sdk 12.1

```

… and the one that fail to be loaded:

```auto
$ otool -l libtbb.12.3.dylib | grep -E -A4 '(LC_VERSION_MIN_MACOSX|LC_BUILD_VERSION)' | grep -B1 sdk
  platform macos
       sdk 12.1

```

### Package Tests

> I am surprise that the package tests were still passing.

I am wondering if the build script where ran in the background and the logic checking for error was skipped.

That said, I also confirmed that executing `import itk; image = itk.Image[itk.UC, 2].New()` using a regular python interpreter also lead to the error.

Here is what I get on `factory-south-macos` build machine (running macOS `10.13.6`):

```bash
TEST_VENV=/tmp/itk-wheels-test-env
/Library/Frameworks/Python.framework/Versions/3.7//bin/python3.7 -m venv $TEST_VENV

$TEST_VENV/bin/python -m pip install \
  itk==5.3rc4.post3 --pre

$TEST_VENV/bin/python -c "import itk; image = itk.Image[itk.UC, 2].New()"
[...]
ImportError: dlopen(/private/tmp/itk-wheels-test-env/lib/python3.7/site-packages/itk/_ITKCommonPython.so, 2): Library not loaded: @loader_path/.dylibs/libtbb.12.3.dylib
  Referenced from: /private/tmp/itk-wheels-test-env/lib/python3.7/site-packages/itk/_ITKCommonPython.so
  Reason: no suitable image found. Did find:
	/private/tmp/itk-wheels-test-env/lib/python3.7/site-packages/itk/.dylibs/libtbb.12.3.dylib: cannot load 'libtbb.12.3.dylib' (load command 0x80000034 is unknown)
	/private/tmp/itk-wheels-test-env/lib/python3.7/site-packages/itk/.dylibs/libtbb.12.3.dylib: cannot load 'libtbb.12.3.dylib' (load command 0x80000034 is unknown)

```

---

<div class="post-metadata">

### Author: ![jcfr](https://discourse.itk.org/user_avatar/discourse.itk.org/jcfr/32/2526_2.png) [@jcfr](https://discourse.itk.org/u/jcfr)
#### Post date: [November 14, 2022, 1:55pm UTC](https://discourse.itk.org/t/itk-5-3rc4-post3-failure-to-load-libtbb-library-observed-on-macos-10-13/5405/4 "2022-11-14T13:55:47Z")

</div>

To follow up, thanks to the help of @Tom_Birdsong, @dzenanz and @matt.mccormick, this has been fixed in pull request [ITKPythonPackage#216](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/pull/216).
