无法在Mac OS Lion上将mysqlclient.18.dylib加载到Python中

0 投票
1 回答
1567 浏览
提问于 2025-04-17 09:15

我想在Mac OS X Lion上让MySQL和系统自带的Python 2.7一起工作。

我知道网上有很多类似的问题,实际上我的情况和关于mysql-python安装问题(在mac os x lion上)的描述一模一样。不过,那里的解决方案似乎不适合我。

我的Mac是一台当前的MacBook Pro,运行的是64位内核:

% uname -a 
Darwin Leos-MacBook-Pro.local 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug  9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64

Lion系统自带的Python是一个“胖二进制文件”,也就是说它包含了多种架构的代码:

% file /usr/bin/python
/usr/bin/python: Mach-O universal binary with 2 architectures
/usr/bin/python (for architecture x86_64):  Mach-O 64-bit executable x86_64
/usr/bin/python (for architecture i386):    Mach-O executable i386

我使用了迁移助手,所以我的系统上有一个旧版的MySQL。我按照如何在Mac OS X上卸载MySQL的说明,删除了旧的MySQL安装。

我从MySQL网站的.dmg文件安装了64位的MySQL 5.5.19。和往常一样,这将客户端库放在了/usr/local/mysql/lib目录下。这个客户端库看起来正是我们需要的:

% file /usr/local/mysql/lib/libmysqlclient.18.dylib
/usr/local/mysql/lib/libmysqlclient.18.dylib: Mach-O 64-bit dynamically linked shared library x86_64

然而,这个共享库无法加载到Python中(我使用arch命令确保我在运行64位版本,结果无论有无这个命令都是一样的):

% arch -x86_64 python
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import cdll
>>> cdll.LoadLibrary("/usr/local/mysql/lib/libmysqlclient.18.dylib")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 431, in LoadLibrary
    return self._dlltype(name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 353, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(/usr/local/mysql/lib/libmysqlclient.18.dylib, 6): no suitable image found.      Did find:
    /usr/local/mysql/lib//libmysqlclient.18.dylib: mach-o, but wrong architecture
    /usr/local/mysql/lib/libmysqlclient.18.dylib: mach-o, but wrong architecture

我可以用很多其他方法重现这个问题,尤其是通过标准的import MySQLdb。我特别展示使用ctypes重现这个问题,是因为我想弄清楚问题出在mysql-python还是MySQL客户端库。从上面的情况来看,问题似乎出在客户端库。不过,我很困惑,为什么加载器会认为客户端库的架构不对。

为了检查是否是某个依赖库的问题,我查看了libmysqlclient.18.dylib的依赖关系:

% otool -L /usr/local/mysql/lib/libmysqlclient.18.dylib
/usr/local/mysql/lib/libmysqlclient.18.dylib:
libmysqlclient.18.dylib (compatibility version 18.0.0, current version 18.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.1)

当然,/usr/lib/libSystemB.dylib是一个胖二进制文件,这也是预期的结果:

% file /usr/lib/libSystem.B.dylib 
/usr/lib/libSystem.B.dylib: Mach-O universal binary with 2 architectures
/usr/lib/libSystem.B.dylib (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64
/usr/lib/libSystem.B.dylib (for architecture i386): Mach-O dynamically linked shared library i386

所以……Python是64位的,mysqlclient库也是64位的,所有依赖库也都是64位的……如果有人能猜到为什么加载器拒绝导入这个库,我将非常感激。

为了确保一切都是64位的,我还做了一些额外的检查:

% python -c 'import platform; print platform.platform()'
Darwin-11.2.0-x86_64-i386-64bit
% ls -l /usr/local/mysql
lrwxr-xr-x  1 root  wheel  27 Dec 10 16:52 /usr/local/mysql@ -> mysql-5.5.19-osx10.6-x86_64

在这个时候,由于我需要实际完成一些工作,我打算尝试切换到pymysql。这主要是为了与Django一起使用,Django有一个方便的方法可以在这个讨论串的底部找到文档说明。

附言:我了解macports,但在这个系统上无法使用它。

1 个回答

0

很可能你已经把苹果自带的Python默认设置成了32位模式,这可能是通过使用defaults命令或者设置VERSIONER_PYTHON_PREFER_32_BIT这个环境变量来实现的;具体可以查看man python了解更多信息。在OS X 10.6和10.7中,/usr/bin/python是一个苹果提供的包装程序,它决定了要运行哪个Python以及以什么模式运行。使用arch来执行/usr/bin/python并不会影响解释器的工作。比如:

$ unset VERSIONER_PYTHON_PREFER_32_BIT 
$ arch -x86_64 /usr/bin/python -c "import sys;print(sys.maxsize)"
9223372036854775807
$ export VERSIONER_PYTHON_PREFER_32_BIT=yes
$ arch -x86_64 /usr/bin/python -c "import sys;print(sys.maxsize)"
2147483647
#
# But avoiding the wrapper program ....
#
$ arch -x86_64 /usr/bin/python2.7 -c "import sys;print(sys.maxsize)"
9223372036854775807
$ arch -i386 /usr/bin/python2.7 -c "import sys;print(sys.maxsize)"
2147483647

撰写回答