15

MacOSX 10.6でPython拡張機能を構築し、それをいくつかのフレームワーク(i386のみ)に対してリンクしようとしています。distutilsとExtensionオブジェクトを使用してsetup.pyファイルを作成しました。

フレームワークに対してリンクするように注文すると、LDFLAGSenvvarは次のようになります。

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++' )

すべてが正常にコンパイルおよびリンクされています。extra_link_argsから-framework行を削除すると、期待どおりにリンカーが失敗します。これがpythonsetup.pyビルドによって生成された最後の2行です:

/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

残念ながら、私が作成した.soは、このフレームワークによって提供されるいくつかのシンボルを見つけることができません。リンクされたフレームワークを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)

私の投稿の上部に記載されているLDFLAGSを使用してg++とlddで作成されたテストバイナリで実行されたotoolの出力があります。この例では、-frameworkは機能しました。

$ 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)

この問題は、リンク手順の「-undefineddynamic_lookup」フラグにリンクできますか?Googleで見つけた数行のドキュメントに少し混乱しています。

乾杯、

4

5 に答える 5

11

これは、未定義の dynamic_lookup とは関係ありませんが、すべて distutils と関係があります。Python ビルド用に選択したリンク フラグに extra_link_flags を追加します。-framework リストは、コマンドラインでそれらを使用するオブジェクトの前に来る必要があるため、代わりにそれを追加する必要があります(これは、gcc がリンク用のシンボルを収集する方法によるものです)。私が個人的に使用している簡単な修正は、で構築することです

    LDFLAGS="-framework Carbon" python setup.py build_ext --inplace

または必要なフレームワーク。LDFLAGS は、distutils 自身のフラグの先頭に追加されます。あなたのパッケージはできないことに注意してくださいpip install。適切な修正は、distutils からのみ行うことができます。サポートするframeworksようにサポートする必要がありlibrariesます。

または、追加することもできます

import os
os.environ['LDFLAGS'] = '-framework Carbon'

あなたのsetup.pyで。あなたのパッケージはそれからpip installできるはずです。

于 2012-01-03T21:46:56.343 に答える
4

ほこりが落ち着いてからずっと経ちましたが、同じ質問を自分で持ち、少し掘り下げてこれを見つけました:

/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 SDK には PPC 部分がないため、10.6 distutils は C 拡張機能を構築しようとしています。

でも、

 export ARCHFLAGS="-arch i386 -arch x86_64"
 python setup.py build

魅力のように働きました。

于 2011-05-26T06:40:30.390 に答える
3

あなたが何をしようとしているのか、そしてあなたが望む結果を理解しているかどうかはわかりませんが、おそらくこれが役立つでしょう. C 拡張モジュールは通常、Python インタープリターの実行コンテキスト内で実行されるため、拡張モジュールはインタープリターと互換性があるようにビルドする必要があります。OS X では、Python と distutils は、C 拡張モジュールが、Python インタープリター自体が最初にビルドされたときと同じ SDK ( -sysroot)、MACOSX_DEPLOYMENT_TARGET値、および値でビルドされるようにするために、いくつかの問題を抱えています。-archしたがって、Apple 提供の Python を 10.6 で使用している場合、distutils-arch i386 -arch ppc -arch x86_64はビルドに使用された 3 つのアーキテクチャを提供します。現在の python.org OS X インストーラー (10.6、10.5、または 10.4) を使用する場合は、以下が使用されます。

gcc-4.0 -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk

あなたが提供したスニペットから、MacPorts にインストールされたユニバーサル Python を使用していると推測されます。デフォルトでは、-arch x86_64 -arch i386 -isysroot /拡張モジュールの構築に使用されています。

一般に、すべてを機能させるには、次のことを確認する必要があります。

  1. インタープリター、すべての C 拡張モジュール、およびそれらがリンクするすべての外部フレームワークおよび/または共有ライブラリーに少なくとも 1 つarchの共通点がある

  2. インタプリタはその (またはそれらの 1 つ) 共通アーキテクチャで実行されています。

OS X 10.6 では、使用している Python によっては、最後のステップがそれほど簡単ではありません。たとえば、Apple 提供の Python 2.6 には、32 ビット実行を強制するための変更があります (詳細については、Apple のman pythonものを参照してください)。

export VERSIONER_PYTHON_PREFER_32_BIT=yes

独自の 32/64 ビット ユニバーサル Python をビルドする場合、実行時に選択できるように 2.6.5 に修正があります。残念ながら、MacPorts が Python をビルドする方法はこれらの修正をバイパスするため、MacPorts python2.6 32/64 ビット ユニバーサル ビルドを 10.6 で強制的に 32 ビット モードで実行する簡単な方法はないようです。複雑な理由により、使用可能な場合でも、常に 64 ビットが優先されます/usr/bin/arch -i386

したがって、何をしようとしているのかによっては、次のいずれかで問題を回避できる場合があります (私が正しく理解している場合)。

  1. フレームワークを再構築して含める-arch x86_64
  2. Apple 提供の Python ( /usr/bin/python) を 32 ビット モードで使用するか、python.org 2.6.5 を使用します。
  3. MacPorts python を 32 ビットのみのモードで再インストールします (未テスト!):

    sudo port selfupdate
    sudo port clean python26
    sudo port install python26 +universal universal_archs=i386
    
于 2010-04-06T22:54:35.887 に答える
1

私のフレームワークは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

リンク行から-archx86_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)

コンパイル時に-archを強制的に使用し、Pythonのdistutilsとリンクする方法を誰かが知っている場合は、アドバイスを共有してください。

于 2010-04-06T12:47:20.137 に答える