建立一个python模块,并联系对MacOSX框架
-
24-09-2019 - |
题
我在试图建立一个Python延MacOSX10.6和链接,它针对若干框架(i386)。我做了一个setup.py 文件时,使用distutils来完成和扩展的对象。
我以链接针对我的框架,我的 LDFLAGS env var应该是这样的:
LDFLAGS = -lc -arch i386 -framework fwk1 -framework fwk2
因为我没有找到任'框架'关键字在扩展模块的文件,我用的 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++' )
一切都是汇编和联罚款。如果我删除该框架线从extra_link_args,我的接头的失败,正如所预期的。这里是最后的两条线产生的蟒蛇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上运行的一个试验二,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)
可能这个问题被联系到的"-不确定dynamic_lookup"标志的连接步骤?我有点困惑的几行文件,我现在谷歌。
干杯,
解决方案
这有什么好做的不确定dynamic_lookup但所有的distutils。它追加extra_link_flags到它自己选择的蟒蛇建筑的链接标志。相反,它应该在前面加上它,因为-framework上市必须来使用他们在CMDLINE对象之前(据我所知,这是由于GCC如何云集符号连接)。速战速决,我个人的使用与建设
LDFLAGS="-framework Carbon" python setup.py build_ext --inplace
或任何框架的需要。 LDFLAGS被前置到distutils的自己的标志。请注意,你的包将不会pip install
able。一个适当的修复程序只能来自的distutils - IMHO它们应该支持frameworks
像它们支持libraries
可替换地,还可以添加
import os
os.environ['LDFLAGS'] = '-framework Carbon'
在您的setup.py。然后,您的包应该是pip install
able。
其他提示
虽然尘埃落定不久,有我自己的周围挖一点点,发现这个同样的问题:
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/sysconfig.py
if 'ARCHFLAGS' in os.environ:
archflags = os.environ['ARCHFLAGS']
else:
archflags = '-arch i386 -arch ppc -arch x86_64'
_config_vars['ARCHFLAGS'] = archflags
if archflags.strip() != '':
_config_vars['CFLAGS'] = _config_vars['CFLAGS'] + ' ' + archflags
_config_vars['LDFLAGS'] = _config_vars['LDFLAGS'] + ' ' + archflags
我在问题来从不同的角度 - 在10.6的distutils试图构建C扩展和抱怨,因为有在10.6 SDK没有PPC部分
然而,
export ARCHFLAGS="-arch i386 -arch x86_64"
python setup.py build
工作就像一个魅力。
我不确定我明白你正在尝试做的和你所希望的结果,但也许这会有帮助。因为C扩展的模块正常运行的内的执行方面的蟒蛇译员,扩展模式都必须建立兼容的翻译。在OS X、蟒蛇及distutils来完成转到一些麻烦,以确保C扩展的模块建造的同样的SDK(-sysroot
), MACOSX_DEPLOYMENT_TARGET
值,和 -arch
值为蟒蛇口译员本身最初建成。所以,如果您使用的是苹果公司提供的蟒蛇在10.6,distutils来完成将供应 -arch i386 -arch ppc -arch x86_64
, ,第三歙县,它是建立。如果你使用一个电流python.org OS X安装程序(在10.6,10.5,或10.4),它将使用:
gcc-4.0 -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk
从该段提供的,我猜你用的是一个MacPorts安装的普遍蟒蛇,并通过默认,它是建立和使用 -arch x86_64 -arch i386 -isysroot /
建设扩展的模块。
一般来说,让一切工作,你需要确保:
至少有一个
arch
在 普遍的解释,所有C 扩展的模块,和所有外部 框架和/或共用图书馆 他们链接到该解释正在执行中,(或者)公共建筑(s)。
在OS X10.6,最后一步骤是不容易的,因为它应该根据其蟒蛇你都可使用。例如苹果公司提供的Python2.6已经修改力的32位的执行(参看苹果的 man python
对于细节):
export VERSIONER_PYTHON_PREFER_32_BIT=yes
如果你建立自己的32-/64-位的普遍蟒蛇,有修复在2.6.5允许选择在运行时间。不幸的是,这种方式MacPorts建立Python绕过这些修复使似乎没有任何简单的办法强迫一个MacPorts python2.6 32-/64-位的普遍性建立在10.6运行中的32位的模式。对于复杂的原因,它总是会更喜欢64位,如果有的话,甚至如果你使用 /usr/bin/arch -i386
.
所以,根据什么你们试图要做的,你可能能够解决的问题(如果我的理解是否正确)通过:
- 重建的框架,包括
-arch x86_64
- 使用的苹果公司提供的蟒蛇(
/usr/bin/python
)在模式中的32位或python.org 2.6.5 重新安装的MacPorts蟒的32位的唯一模式(未经测试的!):
sudo port selfupdate sudo port clean python26 sudo port install python26 +universal universal_archs=i386
看来,我的框架编译为PPC和i386而不是x86_64的:
$ file /Library/Frameworks/fwk1.framework/Versions/A/fwk1
/Library/Frameworks/fwk1.framework/Versions/A/fwk1: Mach-O universal binary with 2 architectures
/Library/Frameworks/fwk1.framework/Versions/A/fwk1 (for architecture ppc): Mach-O dynamically linked shared library ppc
/Library/Frameworks/fwk1.framework/Versions/A/fwk1 (for architecture i386): Mach-O dynamically linked shared library i386
从我的连接线除去-arch x86_64的标志。我的图书馆连接对我的框架:
$ otool -L test.so
test.so:
/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)
如果有人知道如何为动力可在编译和链接时使用Python的的distutils使用的-arch ......请分享您的建议。
我只是碰到了这个自己。我不得不绕行distutils的,因为他们似乎硬编码-undefined dynamic_lookup。这里是生成文件我使用效仿的distutils:
CC = gcc
CFLAGS = -pipe -std=c99 -fno-strict-aliasing -fno-common -dynamic -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Werror -pedantic -Wall -Wstrict-prototypes -Wshorten-64-to-32 -g -Os -arch i386 -arch x86_64 -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
LD = gcc
LDFLAGS = -Wl,-F. -bundle -Wl,-F. -arch i386 -arch x86_64 -framework CoreFoundation -framework CoreMIDI -framework Python
project = <extension_name>
library = $(project).so
modules = <module_names>
sources = $(foreach module,$(modules),$(module).c)
objects = $(sources:.c=.o)
all: $(library)
$(library): $(objects)
$(LD) $(LDFLAGS) $(objects) -o $@
%.o: %.c Makefile
$(CC) $(CFLAGS) $< -c -o $@
install: $(library)
cp $(library) /Library/Python/2.7/site-packages
clean:
rm -f $(library) $(objects) *~
我敢肯定有办法让distutils的停止发射该-undefined的说法,但上述工作对我来说在10.7