Mac OS X上与Python解释器链接的C库问题

3 投票
1 回答
924 浏览
提问于 2025-04-17 00:48

我正在尝试使用一个可以在Python中使用的C库。这个库在Mac OS X(10.6.0,i386)上用GCC编译得很好(版本:i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659))。

但是,当我在Python中尝试导入这个模块时,出现了错误:

$ python
Enthought Python Distribution -- www.enthought.com
Version: 7.0-2 (64-bit)

Python 2.7.1 |EPD 7.0-2 (64-bit)| (r271:86832, Dec  3 2010, 15:56:20) 
[GCC 4.0.1 (Apple Inc. build 5488)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>> import mymodule
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/__init__.py", line 2, in <module>
    from mymodule import *
ImportError: dlopen(/Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/mymodule.so, 2): Symbol not found: _b_char
  Referenced from: /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/mymodule.so
  Expected in: flat namespace
 in /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/mymodule.so

为了回答Ned的问题,这是我得到的输出:

$ file $(python -c 'import sys;print(sys.executable)') 
/Library/Frameworks/EPD64.framework/Versions/Current/bin/python: Mach-O 64-bit executable x86_64
$ python -c 'import sys;print(sys.maxsize > 2**32)' ;
True
$ cd /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule
$ file mymodule.so 
mymodule.so: Mach-O 64-bit bundle x86_64
$ otool -L mymodule.so
mymodule.so:
    /usr/local/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
$ file /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib: Mach-O universal binary with 3 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
/usr/lib/libSystem.B.dylib (for architecture ppc7400):  Mach-O dynamically linked shared library ppc
$ file /usr/local/lib/libgcc_s.1.dylib
/usr/local/lib/libgcc_s.1.dylib: Mach-O universal binary with 4 architectures
/usr/local/lib/libgcc_s.1.dylib (for architecture i386):    Mach-O dynamically linked shared library i386
/usr/local/lib/libgcc_s.1.dylib (for architecture x86_64):  Mach-O 64-bit dynamically linked shared library x86_64
/usr/local/lib/libgcc_s.1.dylib (for architecture ppc): Mach-O dynamically linked shared library ppc
/usr/local/lib/libgcc_s.1.dylib (for architecture ppc64):   Mach-O 64-bit dynamically linked shared library ppc64

看起来有一个常见的架构,但我不确定otool -L所引用的库是否也是这样——那些似乎有多个版本。

我还注意到,当我制作这个包并编译它,然后再制作Python模块时,模块的“build”目录(也就是和setup.py文件在同一层级的目录)里有这些Mac OS X 10.5的文件:

$ cd build/
$ ls
lib.macosx-10.5-x86_64-2.7  temp.macosx-10.5-x86_64-2.7

然而,我使用的是Mac OS X 10.6。请问,使用distutils编译Python包时,是什么决定使用哪个版本的?我担心这可能是导致问题的原因。

你觉得这可能是什么原因呢?谢谢。

1 个回答

1

要准确了解问题是什么,可能需要更多的信息,但看起来你正在使用的是64位版本的Python(来自EPD)。你构建的库也是64位的吗?你可以通过以下方式来确认:

file $(python -c 'import sys;print(sys.executable)')  # see archs that Python was built with
python -c 'import sys;print(sys.maxsize > 2**32)' ; # see if running as 64-bit (false if 32-bit)
cd /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule
file mymodule.so       # see what architectures the C extension module is built with
otool -L mymodule.so   # see what libraries are referenced by the C extension module
file /path/to/lib1     # see what archs the referenced lib module(s) are built with

所有这些都需要有一个共同的架构。

更新:根据你提供的额外信息,最可疑的地方是库引用的/usr/local/lib/libgcc_s.1.dylib。这似乎表明你在/usr/local目录下安装了本地的gcc或其他编译器。你确定没有混用编译器吗?试着清理一下构建目录,然后在构建模块之前明确设置export CC=/usr/bin/gcc-4.0。或者把那个其他的编译器移出/usr/local。 (10.5这个版本应该不是问题。这只是说明EPD Python发行版是为了在10.5及更高版本的系统上运行而构建的。)

撰写回答