在 python 中加载 dylib 在 macOS Big Sur 上失败:`找不到符号:___addtf3`

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

我在 python3.7 在 Mac OS X Big Sur 11.1:

中加载自定义 mylib.dylib 时遇到问题
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

然而 完全相同的 mylib.dylib 正在成功加载 python 代码 Mac OS X 10.15 Catalina . 此外,当编译为可执行文件而不是共享库时,完全相同的 mylib 二进制文件在我的 Big Sur 11.1 上成功运行。

详细的分步说明:

  1. 我在 Mac OS X Big Sur 11.1:
  2. 上使用 bazel 在共享库中构建了一个 C++ 代码
bazel build :mylib.dylib

BUILD 文件是:

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

.bazelrc 文件为:

# 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. 然后我尝试加载到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()

它给了我:

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

this GitHub issue 中讨论了同一问题的可能解决方案,但对我来说,更改 DYLD_LIBRARY_PATH 不起作用。

  1. 我试图在 libquadmath.0.dylib 中将路径设置为 libgcc_ext.10.4.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

它可能会有所帮助,因为 Big Sur 11.1 上没有 /usr/lib/libSystem.B.dylib(所以我想这个文件没有被使用),但它给了我一个新的错误:

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. 我也是brew reinstall gcc,在这个动作之前实际问题中是/usr/local/libSystem.B.dylib而不是flat namespace

  2. 有一些相关问题:scipy, , scipy._fblas, gdal2。他们的解决方案没有帮助,因为通常,他们都是关于重新安装软件包,这里我有自己的软件包。

  3. 最后,我尝试在时设置CC=clang/g++/g++-10。不幸的是,它没有用。

如有任何建议和想法,我们将不胜感激。提前谢谢你

关注@n。 'pronouns'米。来自评论的建议,我尝试 link libgcc_s 而不是 libSystem:

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

它给了我另一个错误:来自 libopenblas 的 Symbol not found: ___emutls_get_address。我用谷歌搜索并找到了 this SO answer,然后:

brew link --overwrite gcc

然后我唯一做的就是使用与之前完全相同的规则用 bazel 重建 mylib.dylib 并且成功了!现在库加载 python 没有任何错误。非常感谢。