IOSアプリの動的なフレームワークを作成しようとしています。 Xcode(6)の新しいバージョンのおかげで、新しいプロジェクトを作成するときにCocoa Touch Frameworkを選択でき、集約ターゲットを追加したり、スクリプトを実行したりする必要がなくなりました。フレームワークを構築するときに問題はありません。しかし、iOSアプリ内で使用しようとすると、アーキテクチャの問題が発生します。
ld: warning: ignoring file /Library/Frameworks/MyFramework.framework/MyFramework, file was built for x86_64 which is not the architecture being linked (arm64): /Library/Frameworks/MyFramework.framework/MyFramework
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_MyFrameworkWebService", referenced from:
objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ld: warning: ignoring file /Library/Frameworks/MyFramework.framework/MyFramework, file was built for x86_64 which is not the architecture being linked (armv7): /Library/Frameworks/MyFramework.framework/MyFramework
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_MyFrameworkWebService", referenced from:
objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
さて、フレームワークのプロジェクトとターゲットの設定を変更しようとしました(Architectures&Build valid architecture only&Valid architectures)。 iOSアプリプロジェクトでも同じことをしましたが、何も機能しません。理解できなかったことがあると思います。
たとえば、コマンドライン「xcrun lipo -info MyFramework」でi386(iOSシミュレーター)のみをチェックするためのフレームワークをビルドすると、次の問題が発生します。
ld:警告:ファイル/Library/Frameworks/MyFramework.framework/MyFrameworkを無視します。ファイルはx86_64用にビルドされましたが、リンクされているアーキテクチャではありません(i386)...
シミュレータを含むすべてのiOSアーキテクチャで動作するフレームワークを手伝ってくれる人がいれば。
申し訳ありませんが、このトピックを長い間公開してきました...一部の皆さんは私の質問に正しく答えています。この質問を書いたとき、完全な(脂肪とも呼ばれる)フレームワーク(すぐに使用できる)に2つのスライスがあったことに気づきませんでした。 1つはiOSデバイス用で、もう1つはシミュレーター用です。 lipoコマンドを使用して2つのスライスを融合するスクリプトを作成し、自動的に完全なフレームワークを得たことを発見したとき。
すべての応答に基づいて、 raywenderlich.comの投稿 および Gist によって作成された Chris Conway 私が思いついたのは this です。
次の手順を実行して、シミュレータとデバイスの両方のすべてのアーキテクチャを含むCocoa Touchフレームワーク(SwiftおよびObjective-Cファイルを含む)を構築できました。
それが役に立てば幸い :)
UPDATE:手順3のパスが間違っていたGistのエラーを修正しました。 徳久 !!
[〜#〜] update [〜#〜]Xcode 7および8で、[ファイル]> [新規]> [ターゲット...]をクリックし、[その他]を選択します。集約ターゲットを選択するグループ
フレームワークプロジェクトとアプリプロジェクトを含むワークスペースを作成するには、次の手順を試してください。
ワークスペース:
フレームワークプロジェクト:
アプリプロジェクト:
上記の例は、simulatorで実行されるアプリのビルド方法を示していることに注意してください。 シミュレータとデバイスの両方で実行されるユニバーサルスタティックライブラリを作成する必要がある場合、一般的な手順は次のとおりです。
それについての良い参考文献がウェブ上にあります。たとえば、 here 。
フレームワークのユニバーサルバイナリを作成します。フレームワークの派生データディレクトリに移動してから/ Build/Products、次のコマンドでProductsディレクトリ:
lipo -create -output "framework-test-01-universal" "Debug-iphonesimulator/framework-test-01.framework/framework-test-01" "Debug-iphoneos/framework-test-01.framework/framework-test-01"
framework-test-01が私のフレームワークプロジェクト名であることに注意してください。
セットする ONLY_ACTIVE_Arch=NO
の中に Build Settings
プロジェクトで。
フレームワークのコンソールProducts
フォルダーで開く(フレームワークフォルダーを開いてcd ..
そこから)
実行このスクリプトProducts
フォルダーから。このフォルダーにファットフレームワークを作成します。 (または、以下で説明するように4。5。で手動で実行します)
framework_name="${$(basename $(find ./Debug-iphoneos -type d -name '*.framework' -maxdepth 1))%.*}" && \
cp -R Debug-iphoneos/$framework_name.framework ./$framework_name.framework && \
lipo -create -output "$framework_name.framework/$framework_name" "Debug-iphonesimulator/$framework_name.framework/$framework_name" "Debug-iphoneos/$framework_name.framework/$framework_name"
または:
このスクリプトでlipoを使用してこれら2つのフレームワークを結合します(YourFrameworkName
をフレームワーク名に置き換えます)
lipo -create -output "YourFrameworkName" "Debug-iphonesimulator/YourFrameworkName.framework/YourFrameworkName" "Debug-iphoneos/YourFrameworkName.framework/YourFrameworkName"
既存のフレームワークの新しいバイナリに置き換えます:
cp -R Debug-iphoneos/YourFrameworkName.framework ./YourFrameworkName.framework
mv YourFrameworkName ./YourFrameworkName.framework/YourFrameworkName
./YourFrameworkName.framework
-すぐに使えるファットバイナリです!プロジェクトにインポートできます!プロジェクトでは、xcworkspace
- es:にはありません
this Gist を使用することもできますが、ワークスペースのプロジェクトでは機能しないようです。
私がやった方法はvladofに似ていますが、うまくいけばもう少し簡単です。フレームワークをアプリプロジェクトのサブプロジェクトにしました。
フレームワークプロジェクト
アプリプロジェクト
Obj-Cアプリの場合
Swift app
このようにすると、アプリはフレームワークに依存するため、フレームワーククラスを変更する場合、フレームワークを個別にビルドするためにターゲットを変更する必要はありません。最初にフレームワークをコンパイルし、次にアプリをコンパイルします。
シミュレータのすべてのアーキテクチャをサポートするために、誰かのスクリプトを少し変更しました。
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions
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}" ONLY_ACTIVE_Arch=NO -configuration ${CONFIGURATION} -sdk iphonesimulator VALID_ARCHS="x86_64 i386" BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 2. Copy the framework structure to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory
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}"
# Step 4. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 5. Delete temporary build directory in the project's directory
rm -rf "${PROJECT_DIR}/build"
# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
上記のリンクが以前にあったので私がした古いビデオはもう利用できません。
最後に、私はそれが私のために働くようになりました!そして、大きな黄色いフレームで申し訳ありませんが、私はそれをより良くフォーマットする方法がわかりません。
解決策はClaudio Romandiから来ましたが、リンクされたスクリプトには小さな問題があります。 50の評判が必要なため、彼の投稿にコメントすることはできません。そのため、完全なソリューションを得るために彼の投稿をコピーする以外に選択肢はほとんどありません。
次のコードを入れてください:
#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions 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}" clean build
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory 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}"
# Step 5. Convenience step to copy the framework to the project's directory cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Convenience step to open the project's directory in Finder open "${PROJECT_DIR}"
スキーム選択ドロップダウンで集計を選択します
問題は、シミュレータのディレクトリが存在しないディレクトリを指しており、2つの場所で「フレームワーク」を「$ {PROJECT_NAME}」に変更することでした:)
Skywinder here によって提供されるリポスクリプトの回答に何かを追加したかった。手順を実行しましたが、フレームワークをシミュレータで実行できず、デバイスのみでした。それを修正するには:
-私はフレームワークのdebug-iphonesimulatorバージョンに入り、Modules/[FrameworkName] .swiftmoduleでi386およびX86ファイルをすべてコピーしました。
-次に、新しく作成されたフレームワークのファットバージョンに移動し、同じフォルダーに移動しました。 i386ファイルとX86ファイルを貼り付け(ARMファイルが既にそこにある)するために)、その後、太ったフレームワークをプロジェクトに追加しました。
出来上がり、彼女はシミュレーターと実際のデバイスで働いています!これはXcode 10/Swift 4.2 btw
Swiftベースのフレームワークにより適切であるvladofによって共有されるアプローチの周りのいくつかの追加ポイント
この質問はしばらく前(Xcode 6)に投稿されましたが、最近Xcode 10で同じ問題に遭遇しました。
問題は、構築されたフレームワークが十分なアーキテクチャをサポートしていないことです。
アーキテクチャの略がわからない場合、iPhoneデバイスごとにアーキテクチャが異なるため、完全なリストを次に示します。
そのため、シミュレータでフレームワークを使用している場合、フレームワークはi386またはx86_64をサポートする必要があります。 iPhone 6でアプリを実行している場合、フレームワークはarm64アーキテクチャをサポートする必要があります。
したがって、ほとんどの場合、フレームワークは前述のすべてのアーキテクチャをサポートする必要があります。
次に、問題の解決方法に戻ります。デバイスとシミュレータの両方のフレームワークを構築する必要があります。
デバイス用のビルド方法:
シミュレータ用のビルド方法:
デバイスとシミュレータの両方のビルド方法:
デバイス用のフレームワークを作成したら、シミュレーター用のフレームワークとデバイス用のフレームワークを「リポ」コマンドで組み合わせる必要があります。シミュレーターのフレームワークの名前を[MyFrameworkProject] _sim.frameworkに変更し、両方のフレームワークを同じフォルダーにコピーします。ターミナルで以下のコマンドを実行します(フォルダー内にいることを確認してください):
lipo -create -output [MyFrameworkProject].framework/[MyFrameworkProject] [MyFrameworkProject].framework/MyFrameworkProject [MyFrameworkProject]_sim.framework/MyFrameworkProject
[MyFrameworkProject] .frameworkは、シミュレーターとデバイスの両方をサポートする最終製品です。