web-dev-qa-db-ja.com

i386およびx86_64アーキテクチャ用のCocoaTouch Frameworkを構築する方法は?

Cocoa Touchフレームワーク(SwiftまたはObject-C)をビルドし、それを「Embedded Binaries」として別のプロジェクトに追加した後、ビルドしようとすると次のエラーメッセージが表示されます。

missing required architecture i386
...
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

さまざまな既存の回答と拡張された調査に続いて、私はすでにi386アーキテクチャに追加しましたビルド設定…

enter image description here

ただし、これは効果がないようです。使用して確認すると

lipo -info TesterFrameworkObjC

私は得るだけです

Architectures in the fat file: TesterFrameworkObjC are: armv7 arm64

…i386(およびx86_64)もここに表示されるべきではありませんか?何が足りないのですか?

(iOS8.2用のXcode6.2 +ビルドを使用しています)


いくつかの新しい洞察

このバージョンを使用すると ビルドスクリプト フレームワークのSwiftバージョン)に不足しているアーキテクチャをビルドできます。

enter image description here

ただし、このフレームワークをアプリに追加してビルドすると、エラーが発生します

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$__TtC20TesterFrameworkSwift18TestFrameworkSwift", referenced from:
  objc-class-ref in ViewController.o
ld: symbol(s) not found for architecture x86_64

シミュレーターの最終的なビルドフォルダーの構築を確認する

Build/Products/Debug-iphoneos/TesterFrameworkSwift.framework/

(示されているように)フレームワークの一部であったにもかかわらず、アーキテクチャーがまだ欠落していることがわかります。アプリをビルドするときに、フレームワークの適切なアーキテクチャビルドがすべて含まれていることを確認するにはどうすればよいですか?


更新

私へのすべてのエラーメッセージを見ると、問題は実際には間違った製品/アーキテクチャが構築されていることではないようですが、1ステップ後にリンカーそれらへの正しいパスを使用していません。これがどれほど正しいかわからない。

11
Bernd

これは私が持っていたのと同じ 問題 です。

これはXcodeのバグのようですが、ビルドスクリプトを追加することで回避できます。ライブラリをすべてのアーキテクチャでコンパイルし、lipoファットバイナリイメージにコンパイルするだけです。

また注意してください

シミュレーターの最終的なビルドフォルダーの構築を確認する

ビルド/製品/デバッグ-iphoneos/TesterFrameworkSwift.framework /

あなたはiphoneビルドフォルダでx86_64とi386イメージを探しています、それらはDebug-iphonesimulator/TesterFrameworkSwift.framework/にあるはずです

また、スクリプトに再帰の問題があります。修正しました。

 UNIVERSAL_OUTPUTFOLDER = $ {BUILD_DIR}/$ {CONFIGURATION}-ユニバーサル
 
 if ["true" == $ {ALREADYINVOKED:-false}] 
 then 
 echo "RECURSION:Detected、stopping" 
 else 
 exportALREADYINVOKED = "true" 
 
#ステップ1.デバイスとシミュレータのバージョンをビルドする
 xcodebuild -target "$ {PROJECT_NAME}" ONLY_ACTIVE_Arch = NO -configuration $ {CONFIGURATION} -sdk iphoneos BUILD_DIR = "$ {BUILD_DIR}" BUILD_ROOT = "$ {BUILD_ROOT}" clean build 
 xcodebuild -target "$ {PROJECT_NAME}" -configuration $ {CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_Arch = NO BUILD_DIR = "$ {BUILD_DIR}" BUILD_ROOT = "$ {BUILD_ROOT}"クリーンビルド
 
#ステップ2。フレームワーク構造(iphoneosビルドから)をユニバーサルフォルダー
 cp -R "$ {BUILD_DIR}/$ {CONFIGURATION} -iphoneos/$ {PROJECT_NAME} .framework" "$ {UNIVERSAL_OUTPUTFOLDER} /" [にコピーします。 ____。] 
#ステップ3. Swiftモジュール(iphonesimulatorビルドから)をコピーしたフレームワークディレクトリにコピーします
 cp -R "$ {BUILD_DIR}/$ {CONFIGURATION} -iphonesimulator/$ {PROJECT_NAME} .framework/Modules/$ {PROJECT_NAME} .swiftmodule /。 "" $ {UNIVERSAL_OUTPUTFOLDER}/$ {PROJECT_NAME} .framework/Modules/$ {PROJECT_NAME} .swiftmodule "
 
#ステップ4.lipoを使用してユニバーサルバイナリファイルを作成し、結合した実行可能ファイルをコピーしたフレームワークディレクトリに配置します
 lipo -create -output "$ {UNIVERSAL_OUTPUTFOLDER}/$ {PROJECT_NAME} .framework/$ {PROJECT_NAME} "" $ {BUILD_DIR}/$ {CONFIGURATION} -iphonesimulator/$ {PROJECT_NAME} .framework/$ {PROJECT_NAME} "" $ {BUILD_DIR}/$ {CONFIGURATION} -iphoneos/$ {PROJECT_NAME} .framework /${PROJECT_NAME}"

#ステップ5.フレームワークをプロジェクトのディレクトリにコピーするための便利なステップ
 cp -R "$ {UNIVERSAL_OUTPUTFOLDER}/$ {PROJECT_NAME} .framework "" $ {PROJECT_DIR} "
 
#ステップ6.Finderでプロジェクトのディレクトリを開くための便利なステップ
 open" $ {PROJECT_DIR} "
 
 fi 
 

6)"cmd + B"(ビルドプロジェクト)を押します

7)Finderで製品を開く

enter image description here

8)1つのディレクトリを上に移動すると( "cmd +↑")、"Release-universal"ディレクトリが表示されます。 enter image description here

"fat/universal"ライブラリがあります。準備ができています!

で確認できます

file test.dylib 
test.dylib: Mach-O universal binary with 4 architectures
test.dylib (for architecture i386): Mach-O dynamically linked shared library i386
test.dylib (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64
test.dylib (for architecture armv7):    Mach-O dynamically linked shared library arm
test.dylib (for architecture arm64):    Mach-O 64-bit dynamically linked shared library
35
l0gg3r

私は同じ問題に遭遇し、幸いにもそれを解決しました。

Xcodeでフレームワークを作成し、iPhone 5シミュレーターまたはiPhone 5より前のシミュレーター(iPhone4sやiPhone4など)でビルドすると、i386アーキテクチャのフレームワークが得られます。 iPhone 5sシミュレーターまたはiPhone 5s以降のsimulatroでビルドすると、x86_64アーキテクチャーのフレームワークが得られます。ただし、プロジェクトでフレームワークを使用していて、シミュレーターでアプリを実行する場合は、フレームワークにi386アーキテクチャとx86_64アーキテクチャの両方が含まれている必要があります。含まれていないと、リンカーエラーが発生します。したがって、lipo -createコマンドを使用して2つのフレームワークをマージする必要があります。この時点で、フレームワークを使用する準備ができています。

1
DaiPei

ビルド設定->に移動アクティブなアーキテクチャのみをビルドから[〜#〜] no [〜#〜]

フレームワークをiPhone5およびiPhone6以降のシミュレーターでビルドします。

ポストアクションに実行スクリプトを追加して、ユニバーサルフレームワークを生成します。

ターミナルに移動してcd(フレームワークのパス、またはフレームワークをドラッグアンドドロップ)と入力すると、フレームワークディレクトリに移動します。

タイプファイルYOUR_FRAMEWORK_NAMEフレームワークがサポートしているすべてのアーキテクチャを一覧表示します

フレームワークが4つのアーキテクチャi386、x86_64、armv7arm64すべてをサポートしていることがわかります。

1
Sundaresh Joshi