web-dev-qa-db-fra.com

Cadre parapluie

J'ai créé un framework dans lequel est inséré le second framework, appelé "framework parapluie". Lorsque j'insère le framework dans l'application de test (les fichiers binaires et les frameworks et bibliothèques liés ne peuvent pas être générés), j'obtiens le message d'erreur suivant:

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

Ensuite, ajoutez ce framework (embeddedInMyFramework) également dans les binaires incorporés et les frameworks et bibliothèques liés et essayez de construire que fonctionne correctement. Plus tard, supprimez ce cadre des fichiers binaires incorporés et des cadres et bibliothèques liés et fonctionne toujours bien. Quelqu'un peut-il m'aider avec ceci, ne sachant pas ce qui se passe lorsque j'ajoute une structure aux fichiers binaires incorporés pour la première fois et comment résoudre ce problème (pourrait-il fonctionner d'une manière ou d'une autre sans rien ajouter aux fichiers binaires incorporés)?

8
BGBoy

J'ai été en mesure de mettre en place un cadre de travail parapluie fonctionnel et d'écrire mon approche. 

L'étape 5 devrait supprimer votre éditeur de liens ld: framework not found .. 


Installer:

  • Un projet "client" basé sur Swift qui utilise le framework Umbrella comme dépendance

  • Un framework dynamique (principalement C++ et ObjC) qui est une dépendance du framework Umbrella


Pas:

  1. Liez le cadre parapluie à son (sous-) cadre dépendant et assurez-vous qu'il est copié dans le produit lors de la construction.

Setting of Project -> Build Phases


2. Ajoutez l'emplacement du (sous-) cadre dépendant au Framework Search Paths du projet de cadre-parapluie.

 Setting of Project -> Build Settings


3. Dans le projet "client", assurez-vous de lier et d'intégrer le framework Umbrella.

 General Setting Client


4. Assurez-vous que la structure Umbrella est copiée dans le groupe d'applications (client-) pour éviter les erreurs dyld: Library not loaded: @rpath/.... L’application (client), généralement placée sous ...Build/Products/Debug-iphoneos/YOUR_CLIENT_APP.app, devrait désormais contenir votre structure Umbrella dans un dossier appelé Frameworks

 Project Setting Embed Framework


5. Dans le projet "client" Assurez-vous d'ajouter le chemin d'accès à Umbrella Framework à Framework Search Paths.
Si l'erreur ld: framework not found '[Framework_Name]' for architecture ... persiste, vous pouvez également ajouter le chemin d'accès au (sous-) Framework ici.

 Project setting framework search path

14
ehrpaulhardt

L'ajout aux bibliothèques incorporées définit également certains paramètres de construction, qui ne sont pas supprimés lors de la suppression de la bibliothèque des bibliothèques incorporées.

Le plus probablement, Framework Search Paths contient le chemin de la bibliothèque précédemment manquante.

Cela ne fonctionnera pas sans ajouter en quelque sorte la bibliothèque intégrée. Vous voudrez peut-être utiliser un outil de gestion des dépendances (comme CocoaPods ou Carthage) pour effectuer plus ou moins le travail à votre place.

2
shallowThought

ICI IS UN PROJET DE DEMO:  

Démo du framework Umbrella

Toutes les réponses sous cette ligne sont fausses, car elles font juste ce qui copie manuellement les sous-cadres dans "cadre général"

Intégration d'un framework dans un framework (iOS 8+)

Comment créer un framework parapluie dans iOS SDK?

Comment ajouter un framework dans un autre framework (Cadre Umbrella)

Cadre parapluie

La première chose à savoir est que le "parapluie" est une conception sous Mac OS et non sous iOS, le document officiel est ici

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

si vous voulez créer un "UmbrellaFramework" non recommandé, vous devez effectuer ces opérations étape par étape et connaître les détails lors de la compilation et des périodes de liens.

  1. Changer tous les sous-frameworks Mach-O en bibliothèque statique, cela signifie compiler cette cible en tant que bibliothèque statique (.a)
  2. Copiez manuellement tous les sous-cadres dans UmbrellaFramework pendant la phase de construction (comme le faisaient les autres réponses)
  3. Ajoutez "FakeBundleShellScript" à la cible "UmbrellaFramework", il fait en sorte que tous les sous-cadres se chargent de ressources comme un paquet permettant de rejoindre "UmbrellaFramework".
  4. Changez la fonction de chargement du framework, vous devez charger les ressources du sous-framework via chemin ou url, car il est devenu un paquet, cette étape signifie que vous devez avoir le contrôle suprême de tous les codes des sous-frameworks et des parapluies.

!! Voici un exemple de "FakeBundleShellScript" vous pouvez vous référer

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% 85Bundle/

Comme tout ce que j'ai dit, le point clé pour faire un "UmbrellaFramework" non recommandé est !!! [Compilez les sous-cadres en tant que statiques, traitez les ressources via un faux paquet], N'OUBLIEZ PAS !! Apple a toujours dit NE PAS CRÉER UN Cadre-parapluie

si vous comprenez le chinois, vous pouvez obtenir plus de détails pour créer un "cadre de parapluie" sur mon blog

Alan.li 2017 的 文章

2
MinamiTouma