我试图在MacOSX 10.6上构建一个Python扩展,并将其链接到几个框架(仅i386)。我用distutils和Extension对象创建了一个setup.py文件。
为了链接到我的框架,我的LDFLAGSenv var应该如下所示:
LDFLAGS = -lc -arch i386 -framework fwk1 -framework fwk2
由于在扩展模块文档中没有找到任何“framework”关键字,因此我改用了extra_link_args关键字。
Extension('test',
define_macros = [('MAJOR_VERSION', '1'), ,('MINOR_VERSION', '0')],
include_dirs = ['/usr/local/include', 'include/', 'include/vitale'],
extra_link_args = ['-arch i386',
'-framework fwk1',
'-framework fwk2'],
sources = "testmodule.cpp",
language = 'c++' )
一切都在编译和链接。如果我从额外的链接参数中删除-framework行,我的链接器将按预期失败。下面是python setup.py生成的最后两行:
/usr/bin/g++-4.2 -arch x86_64 -arch i386 -isysroot /
-L/opt/local/lib -arch x86_64 -arch i386 -bundle
-undefined dynamic_lookup build/temp.macosx-10.6-intel-2.6/testmodule.o
-o build/lib.macosx-10.6-intel-2.6/test.so
-arch i386 -framework fwk1 -framework fwk2
不幸的是,我刚刚制作的.所以找不到这个框架提供的几个符号。我试着用otool检查链接的框架。他们都没出现。
$ otool -L test.so
test.so:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.1)
有一个测试二进制文件的otool run输出,它是用g++和ldd生成的,使用的LDFLAGS在我文章的顶部描述。在这个例子中,-框架确实有效。
$ otool -L vitaosx
vitaosx:
/Library/Frameworks/fwk1.framework/Versions/A/fwk1 (compatibility version 1.0.0, current version 1.0.0)
/Library/Frameworks/fwk2.framework/Versions/A/fwk2 (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.1)
此问题是否可以链接到链接步骤上的“-未定义的动态查找”标志?在Google上找到的几行文档让我有点困惑。
干杯
虽然尘埃落定很久之后,我自己也有同样的问题,但我在周围摸索了一下,发现:
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/sysconfig.py
我从另一个角度来讨论这个问题——10.6版本的distutils正在尝试构建C扩展,但由于10.6版本的SDK中没有PPC部分,因此我对此表示不满。
然而
工作起来很有魅力。
我不确定我是否理解你在做什么和你想要的结果,但也许这会有帮助。由于C扩展模块通常在Python解释器的执行上下文中运行,因此必须构建与解释器兼容的扩展模块。在OS X上,Python和distutils在确保C扩展模块使用与Python解释器本身最初构建时相同的SDK(
-sysroot
)、MACOSX_DEPLOYMENT_TARGET
值和-arch
值时会遇到一些麻烦。因此,如果您在10.6上使用Apple提供的Python,distutils将提供-arch i386 -arch ppc -arch x86_64
,这是用它构建的三个arch。如果使用当前的python.org OS X安装程序(在10.6、10.5或10.4上),它将使用:从您提供的代码片段来看,我猜您使用的是安装了通用Python的MacPorts,默认情况下,它是使用
-arch x86_64 -arch i386 -isysroot /
构建扩展模块的。一般来说,要使一切正常工作,您需要确保:
中至少有一个
arch
在口译员中很常见 扩展模块和所有外部 框架和/或共享库 它们链接到解释器在那个(或其中一个)公共体系结构中执行。
在OSX10.6上,最后一步并不那么简单,这取决于您使用的是哪种Python。例如,Apple提供的Python2.6修改了强制32位执行(有关详细信息,请参见Apple的
man python
):如果您构建自己的32/64位通用Python,那么2.6.5中有一些修正,允许在运行时进行选择。不幸的是,MacPorts构建Python的方法绕过了这些修复,因此似乎没有任何简单的方法强制MacPorts python2.6在10.6上运行32位/64位通用构建,使其以32位模式运行。由于复杂的原因,即使您使用
/usr/bin/arch -i386
,它也总是喜欢64位(如果可用)。因此,取决于你想做什么,你可以通过以下任一方法来解决这个问题(如果我理解正确的话):
-arch x86_64
/usr/bin/python
)或Python.org 2.6.5以32位模式重新安装MacPorts python(未测试!)以下内容:
这与未定义的动态查找无关,而是与distutils有关。它将额外的链接标志附加到它为python构建选择的链接标志。相反,它应该放在前面,因为-framework列表必须在命令行上使用它们的对象之前(AFAIK这是因为gcc如何收集用于链接的符号)。我个人使用的一个快速修复方法是
或者你需要的任何框架。LDFLAGS前面是distutils own flags。请注意,您的包将不能
pip install
。正确的修复只能来自distutils-imho,它们应该支持frameworks
,就像它们支持libraries
。或者,也可以添加
在你的setup.py中。然后,您的包应该能够
pip install
。相关问题 更多 >
编程相关推荐