Mac 10.6 通用二进制 scipy: 找不到 cephes/specfun "_aswfa_" 符号

6 投票
2 回答
1923 浏览
提问于 2025-04-15 18:36

我在我的64位MacPro1,1上,编译成i386/x86_64通用二进制文件后,无法让scipy在32位模式下运行。

我的Python环境

这个回答的帮助下,我构建了一个32/64位的intel通用二进制Python 2.6.4,打算用arch命令在不同架构之间切换。(我用lipo成功制作了一些我想要的库的通用二进制文件。)这一切都正常。我然后按照hyperjeff的文章中的说明安装了scipy,只是使用了更新版的numpy(1.4.0),并跳过了在安装scipy时暂时移动numpy的那部分。

现在,除了scipy之外,其他一切似乎都能正常工作,我确实可以使用arch -i386 pythonarch -x86_64 python在32位和64位模式之间切换。

错误信息

在32位模式下,scipy报错:

$ arch -x86_64 python -c "import scipy.interpolate; print 'success'"
success
$ arch -i386 python -c "import scipy.interpolate; print 'success'"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/interpolate/__init__.py", line 7, in <module>
    from interpolate import *
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/interpolate/interpolate.py", line 13, in <module>
    import scipy.special as spec
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/__init__.py", line 8, in <module>
    from basic import *
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/basic.py", line 8, in <module>
    from _cephes import *
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/_cephes.so, 2): Symbol not found: _aswfa_
  Referenced from: /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/_cephes.so
  Expected in: flat namespace
 in /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/_cephes.so

尝试找出问题

看起来scipy.interpolate导入了一个叫_cephes的东西,它在寻找一个叫_aswfa_的符号,但在32位模式下找不到。浏览scipy的源代码,我在specfun.f中找到了一个ASWFA子程序。唯一一个名字相似的scipy产品文件是specfun.so,但这两个文件(specfun.so和_cephes.so)似乎都是通用二进制文件:

$ cd /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/
$ file _cephes.so specfun.so 
_cephes.so: Mach-O universal binary with 2 architectures
_cephes.so (for architecture i386): Mach-O bundle i386
_cephes.so (for architecture x86_64): Mach-O 64-bit bundle x86_64
specfun.so: Mach-O universal binary with 2 architectures
specfun.so (for architecture i386): Mach-O bundle i386
specfun.so (for architecture x86_64): Mach-O 64-bit bundle x86_64

唉,我卡住了。我可能会尝试但还没想出办法的事情包括手动编译specfun.so。

我想scipy并不是在所有32位机器上都坏掉了,所以我猜是我安装的方式出了问题,但我搞不清楚是什么问题。

考虑到我的环境比较特殊,我并不指望能得到完整的答案,但如果有人能给我一些线索,让我朝正确的方向走,那将非常感谢。

(编辑) 更多细节以回答问题:

我使用的是gfortran(来自GCC 4.2.1的GNU Fortran,Apple Inc.构建5646)。

Python 2.6.4的安装大致是这样的:

cd /tmp
curl -O http://www.python.org/ftp/python/2.6.4/Python-2.6.4.tar.bz2
tar xf Python-2.6.4.tar.bz2
cd Python-2.6.4
# Now replace buggy pythonw.c file with one that supports the "arch" command:
curl http://bugs.python.org/file14949/pythonw.c | sed s/2.7/2.6/ > Mac/Tools/pythonw.c    
./configure --enable-framework=/Library/Frameworks --enable-universalsdk=/ --with-universal-archs=intel
make -j4
sudo make frameworkinstall

Scipy 0.7.1的安装过程基本上如这里所述,但简单来说就是运行sudo python setup.py install

如果你用nm查看_cephes库,确实可以看到在i386架构下这个符号是未定义的,正如David Cournapeau所建议的那样:

$ nm -arch x86_64 /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/_cephes.so | grep _aswfa_
00000000000d4950 T _aswfa_
000000000011e4b0 d _oblate_aswfa_data
000000000011e510 d _oblate_aswfa_nocv_data
(snip)
$ nm -arch i386 /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/special/_cephes.so | grep _aswfa_
         U _aswfa_
0002e96c d _oblate_aswfa_data
0002e99c d _oblate_aswfa_nocv_data
(snip)

不过,我还无法解释它的缺失。

2 个回答

1

你是怎么安装scipy的?用的是哪个版本的python,还有哪个fortran编译器?

你可能还想确认一下缺失的符号确实在这两个架构中都有(我不太记得那个函数具体在哪里,但你可以通过结合使用nm和otool这两个工具自己很容易找到)。

3

你有没有试过用macports编译的scipy?

sudo port install scipy +universal

(当然,你还得确保其他相关的东西,比如pythonpy26-numpy也是用相同的选项编译的)

我得到的是:

$ arch -x86_64 /opt/local/bin/python -c "import scipy.interpolate; print 'success'"
success

$ arch -i386 /opt/local/bin/python -c "import scipy.interpolate; print 'success'"
success

你可以利用macports维护者用来编译的设置和知识,来进行你自己的编译。

撰写回答