Ilya Zakharkin
Ilya Zakharkin

Reputation: 41

Loading dylib in python fails on macOS Big Sur: `Symbol not found: ___addtf3`

I have trouble when loading a custom mylib.dylib in python3.7 on Mac OS X Big Sur 11.1:

OSError                                   Traceback (most recent call last)
<ipython-input-7-21ad9f6d803b> in <module>
     12 try:
---> 13     mylib = ctypes.CDLL(mylib_path)
     14 except OSError:

~/opt/anaconda3/lib/python3.7/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error)
    363         if handle is None:
--> 364             self._handle = _dlopen(self._name, mode)
    365         else:

OSError: dlopen(mylib.dylib, 6): Symbol not found: ___addtf3
  Referenced from: /usr/local/opt/gcc/lib/gcc/10/libquadmath.0.dylib
  Expected in: flat namespace
 in /usr/local/opt/gcc/lib/gcc/10/libquadmath.0.dylib

However exactly the same mylib.dylib is loading successfully with exactly this python code on Mac OS X 10.15 Catalina. Moreover, exactly the same mylib binary runs successfully on my Big Sur 11.1 when compiled as an executable, not as a shared library.

Detailed step-by-step description:

  1. I build a C++ code in a shared library using bazel on Mac OS X Big Sur 11.1:
bazel build :mylib.dylib

BUILD file is:

cc_binary(
    name = "mylib.dylib",
    srcs = ["mylib.cc", "mylib.h", "mylib_external.cc", "mylib_external.h"],
    deps = [
        ...some dependencies...
    ],
    linkshared = 1,
)

.bazelrc file is:

# Basic build settings
build --jobs 128
build --define='absl=1'
build --enable_platform_specific_config

# macOS
build:macos --cxxopt=-std=c++17
build:macos --host_cxxopt=-std=c++17
build:macos --copt=-w

# Sets the default Apple platform to macOS.
build --apple_platform_type=macos

# Allow debugging with XCODE
build --apple_generate_dsym

build:darwin_x86_64 --apple_platform_type=macos
build:darwin_x86_64 --macos_minimum_os=10.12
build:darwin_x86_64 --cpu=darwin_x86_64
  1. Then I try to load it in python3.7:
import sys, platform
import ctypes, ctypes.util

mylib_path = ctypes.util.find_library("mylib")
if not mylib_path:
    print("Unable to find the specified library.")
    sys.exit()

try:
    mylib = ctypes.CDLL(mylib_path)
except OSError:
    print("Unable to load the specified library.")
    sys.exit()

And it gives me:

OSError                                   Traceback (most recent call last)
<ipython-input-7-21ad9f6d803b> in <module>
     12 try:
---> 13     mylib = ctypes.CDLL(mylib_path)
     14 except OSError:

~/opt/anaconda3/lib/python3.7/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error)
    363         if handle is None:
--> 364             self._handle = _dlopen(self._name, mode)
    365         else:

OSError: dlopen(mylib.dylib, 6): Symbol not found: ___addtf3
  Referenced from: /usr/local/opt/gcc/lib/gcc/10/libquadmath.0.dylib
  Expected in: flat namespace
 in /usr/local/opt/gcc/lib/gcc/10/libquadmath.0.dylib

A possible solution to the same problem was discussed in this GitHub issue, but for me, changing DYLD_LIBRARY_PATH does not work.

  1. I tried to set the path to libgcc_ext.10.4.dylib in libquadmath.0.dylib:
install_name_tool -change /usr/lib/libSystem.B.dylib /usr/local/opt/gcc/lib/gcc/10/libgcc_ext.10.4.dylib /usr/local/opt/gcc/lib/gcc/10/libquadmath.0.dylib

It might help because there is no /usr/lib/libSystem.B.dylib on Big Sur 11.1 (so this file is not used I suppose), but instead it gives me a new error:

OSError                                   Traceback (most recent call last)
<ipython-input-7-21ad9f6d803b> in <module>
     12 try:
---> 13     mylib = ctypes.CDLL(mylib_path)
     14 except OSError:

~/opt/anaconda3/lib/python3.7/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error)
    363         if handle is None:
--> 364             self._handle = _dlopen(self._name, mode)
    365         else:

OSError: dlopen(mylib.dylib, 6): Library not loaded: /usr/local/opt/gcc/lib/gcc/10/libgcc_ext.10.4.dylib
  Referenced from: /usr/local/opt/gcc/lib/gcc/10/libquadmath.0.dylib
  Reason: no suitable image found.  Did find:
    /usr/local/opt/gcc/lib/gcc/10/libgcc_ext.10.4.dylib: mach-o, but wrong filetype
    /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgcc_ext.10.4.dylib: mach-o, but wrong filetype
  1. I also tried to brew reinstall gcc, before this action there was /usr/local/libSystem.B.dylib instead of flat namespace in the actual issue.

  2. There are some related issues: scipy, scipy.special, scipy._fblas, gdal2. Their solutions do not help, because usually, they are about re-installing the packages, and here I have my own package.

  3. Eventually, I tried to set CC=clang/g++/g++-10 when building with bazel. Unfortunately, it did not work.

Any suggestions and thoughts would be highly appreciated. Thank you in advance 🙏

Upvotes: 3

Views: 2589

Answers (1)

Ilya Zakharkin
Ilya Zakharkin

Reputation: 41

Following @n. 'pronouns' m. advice from the comments, I tried to link libgcc_s instead of libSystem:

install_name_tool -change "/usr/lib/libSystem.B.dylib" "/usr/local/opt/gcc/lib/gcc/10/libgcc_s.1.dylib" mylib.dylib

It gave me another error: Symbol not found: ___emutls_get_address from libopenblas. I googled and found this SO answer, and did:

brew link --overwrite gcc

Then the only thing I did is rebuilt the mylib.dylib with bazel with exact the same rules as earlier and it worked! Now the library loads in python without any errors. Thank you so much.

Upvotes: 1

Related Questions