web-dev-qa-db-ja.com

アンブレラフレームワーク

2番目のフレームワーク、いわゆる「傘フレームワーク」が挿入されたフレームワークを作成しました。テストアプリケーションにフレームワークを挿入すると(埋め込みバイナリとリンクされたフレームワークとライブラリの両方)アプリをビルドできない場合、次のエラーが発生します。

ld: framework not found 'embeddedInMyFramework' for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

その埋め込みフレームワーク(embeddedInMyFramework)を埋め込みバイナリとリンクされたフレームワークとライブラリにも追加し、正常に機能するよりもビルドしてみます。後で、そのフレームワークを埋め込みバイナリとリンクされたフレームワークとライブラリの両方から削除しても、問題なく機能します。誰かがこれで私を助けてくれますか?初めて組み込みバイナリにフレームワークを追加したときに何が起こるか、そしてそれを修正する方法はわかりません(組み込みバイナリに追加しなくてもなんとか機能するでしょうか)

13

機能するUmbrella Frameworkをセットアップすることができ、アプローチを書き留めました。

ステップ5で、リンカーエラーld: framework not found ..が削除されます


セットアップ:

  • Swiftアンブレラフレームワークを依存関係として持つ「クライアント」プロジェクトに基づく

  • アンブレラフレームワークの依存関係である動的フレームワーク(主にC++とObjC)


手順:

  1. Umbrellaフレームワークを依存(サブ)フレームワークにリンクし、ビルド時に製品にコピーされることを確認します。

Setting of Project -> Build Phases


2。依存(サブ)フレームワークの場所をUmbrella FrameworkプロジェクトのFramework Search Pathsに追加します。

Setting of Project -> Build Settings


3。 「クライアント」プロジェクトで、Umbrella Frameworkをリンクして埋め込むようにしてください

General Setting Client


4。 dyld: Library not loaded: @rpath/...エラーを回避するために、Umbrella Frameworkが(クライアント=)アプリバンドルにコピーされていることを確認してください。 (クライアント-)アプリは、通常...Build/Products/Debug-iphoneos/YOUR_CLIENT_APP.appの下に、FrameworksというフォルダーにUmbrella Frameworkが含まれているはずです。

Project Setting Embed Framework


5。 「クライアント」プロジェクトでは、Umbrella Frameworkへのパスを必ずFramework Search Pathsに追加してください。
ld: framework not found '[Framework_Name]' for architecture ...エラーが解決しない場合は、ここで(サブ)フレームワークへのパスを追加することもできます。

Project setting framework search path

18
ehrpaulhardt

HERE IS AN DEMO PROJECT:

アンブレラフレームワークデモ

この行の下のすべての答えは間違っています。手動でサブフレームワークを「アンブレラフレームワーク」にコピーするだけなので、

フレームワーク内にフレームワークを埋め込む(iOS 8以降)

iOS SDKでアンブレラフレームワークを作成する方法

別のフレームワーク内にフレームワークを追加する方法(傘フレームワーク)

アンブレラフレームワーク

「傘フレームワーク」はiOSではなくMac OSの概念であることを最初に知っておく必要があります。公式ドキュメントはこちらです。

https://developer.Apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/CreationGuidelines.html#//Apple_ref/doc/uid/20002254-BAJHGGGA

非推奨の「UmbrellaFramework」を作成する場合は、これらのプロセスを段階的に実行し、コンパイルおよびリンク期間中に詳細を知っておく必要があります。

  1. すべてのサブフレームワークMach-Oを静的ライブラリに変更します。これは、このターゲットを静的ライブラリ(.a)としてコンパイルすることを意味します
  2. ビルドフェーズ中にすべてのサブフレームワークを手動でUmbrellaFrameworkにコピーします(他の回答と同様)
  3. 「FakeBundleShellScript」をターゲットの「UmbrellaFramework」に追加すると、すべてのサブフレームワーク自体がリソースとしてバンドルされ、「UmbrellaFramework」に結合されます
  4. フレームワークロード機能を変更します。パスまたはURLを介してサブフレームワークリソースをロードする必要があります。これはバンドルになったため、この手順により、サブフレームワークとアンブレラの両方のすべてのコードを完全に制御できるはずです。

!!参考にできる「FakeBundleShellScript」の例です

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
BUNDLE_IN_ROOT="$APP_PATH/${FRAMEWORK_EXECUTABLE_NAME}.bundle"
if [[ -e "$FRAMEWORK_EXECUTABLE_PATH" ]]; then
  FRAMEWORK_MACH_O="$(otool -a "$FRAMEWORK_EXECUTABLE_PATH" | head -n 1)"
  FRAMEWORK_FAT_Arch="$(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")"
else
  FRAMEWORK_MACH_O="NO EXIST"
  FRAMEWORK_FAT_Arch="NO EXIST"
fi
echo "FRAMEWORK_EXECUTABLE_NAME is $FRAMEWORK_EXECUTABLE_NAME"
echo "FRAMEWORK_EXECUTABLE_PATH is $FRAMEWORK_EXECUTABLE_PATH"
echo "FRAMEWORK_MACH_O is $FRAMEWORK_MACH_O"
echo "FRAMEWORK_FAT_Arch is $FRAMEWORK_FAT_Arch"
echo "BUNDLE_IN_ROOT is $BUNDLE_IN_ROOT"
if [[ "$FRAMEWORK_MACH_O" =~ "Archive :" ]]; then
  echo "Rmove Static-Mach-O is $FRAMEWORK_EXECUTABLE_PATH"
  rm "$FRAMEWORK_EXECUTABLE_PATH"
  defaults write "$FRAMEWORK/Info.plist" CFBundlePackageType "BNDL"
  defaults delete "$FRAMEWORK/Info.plist" CFBundleExecutable
  if [[ -d "$BUNDLE_IN_ROOT" ]]; then
    rm -rf "$BUNDLE_IN_ROOT"
  fi
  mv -f "$FRAMEWORK" "$BUNDLE_IN_ROOT"
Elif [[ "$FRAMEWORK_FAT_Arch" =~ "Architectures in the fat file" ]]; then
  #statements
  EXTRACTED_ARCHS=()
  for Arch in $ARCHS
  do
    echo "Extracting $Arch from $FRAMEWORK_EXECUTABLE_NAME"
    lipo -extract "$Arch" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$Arch"
    EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$Arch")
  done
  echo "Merging extracted architectures: ${ARCHS}"
  lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
  rm "${EXTRACTED_ARCHS[@]}"
  echo "Replacing original executable with thinned version"
  rm "$FRAMEWORK_EXECUTABLE_PATH"
  mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
fi
done

http://alanli7991.github.io/2017/07/17/%E6%A8%A1%E5%9D%97%E5%8C%9617Framework%E4%B8%8EStaticFramework%E4%BC%AA %E8%A3%85バンドル/

私が言ったように、非推奨の「アンブレラフレームワーク」を作るためのキーポイントは!!!です! [サブフレームワークを静的としてコンパイルし、偽のバンドルを介してリソースを処理します]、忘れないでください!! Appleは常に傘フレームワークを作成しないでくださいと述べました

中国語がわかる方は、ブログから「傘フレーム」の作り方の詳細をブログで入手できます

Alan.li 2017年的文章

3
MinamiTouma

組み込みライブラリに追加すると、組み込みライブラリからライブラリを削除しても削除されない特定のビルド設定も設定されます。

おそらくFramework Search Paths以前に見つからなかったライブラリへのパスが含まれています。

どういうわけか組み込みライブラリを追加しないと機能しません。依存関係管理ツール(CocoaPodsやCarthageなど)を使用して、多かれ少なかれ作業を行うことができます。

2
shallowThought