Il y a une bonne question sur la différence entre ces deux options, comme décrit dans Lien binaire avec les bibliothèques VS Embed Frameworks .
On dirait que nous avons des options pour les utiliser tous les deux, demandez-vous simplement dans quel cas nous devrions mieux utiliser les binaires intégrés, ou plutôt que le cadre lié?
Y a-t-il des exemples solides pour résoudre ce problème plus clairement? Merci
ios
xcode
frameworks
embedded-binary
Forrest
la source
la source
Réponses:
La question que vous avez liée fait référence à la fonctionnalité "Lier le binaire avec les bibliothèques", qui est quelque peu différente d'un binaire incorporé.
"Lier le binaire avec les bibliothèques" signifie ce à quoi vous vous attendez en ce qui concerne le lien: indépendamment du fait que le binaire soit une bibliothèque statique, une bibliothèque dynamique ou un framework, il sera lié à votre code objet au moment du lien après la compilation.
Quand vous pensez à la liaison avec une bibliothèque statique, ce qui se passe est assez clair: l'éditeur de liens copie le code de la bibliothèque (par exemple
libFoo.a
) dans votre binaire de sortie. Votre fichier de sortie augmente en taille mais n'a pas besoin de résoudre les dépendances externes au moment de l'exécution. Tout ce dont votre programme a besoin pour s'exécuter (par rapport à la bibliothèque statique) est présent après sa construction.Avec une bibliothèque dynamique (.dylib ou framework fourni par le système), on s'attend à ce que la bibliothèque que vous liez soit présente quelque part dans le chemin du chargeur de bibliothèque dynamique du système lorsque vous exécutez votre programme. De cette façon, vous n'avez pas la charge de copier toutes les bibliothèques externes tierces dans votre binaire, et tous les différents programmes sur un ordinateur qui sont également liés à cette bibliothèque pourront la trouver, ce qui économise un minimum d'espace disque, mais aussi potentiellement de l'espace mémoire, selon comment et où le système met en cache les bibliothèques.
Un framework ressemble beaucoup à une bibliothèque dynamique, mais peut contenir des ressources dans sa structure de répertoires (images, audio, autres frameworks, etc.). Dans ce cas, une simple bibliothèque statique ou un fichier .dylib ne le coupera pas, vous devrez peut-être créer un lien vers un framework juste pour qu'il puisse trouver ce dont il a besoin pour fonctionner correctement.
Lorsque vous créez un lien vers un framework tiers (dites quelque chose que vous avez téléchargé depuis github et que vous avez créé vous-même), il se peut qu'il ne soit pas présent sur le système sur lequel vous avez l'intention de fonctionner. Dans ce cas, vous ne feriez pas seulement un lien vers le framework, mais vous l'intégreriez également dans votre bundle d'applications en utilisant la phase "Copier les Frameworks". Lorsque votre programme s'exécute, l'éditeur de liens d'exécution (alias le résolveur) cherchera à l'intérieur de votre bundle en plus du chemin du chargeur système, trouvera le cadre intégré et le liera afin que votre application ait le code dont elle a besoin pour s'exécuter.
Enfin, ce qui est proprement un "binaire incorporé" est un exécutable que vous intégrez à la fois dans votre bundle d'application via une phase de copie de fichiers et que vous exécutez vous-même, peut-être avec un appel à
popen()
ou similaire. Le binaire intégré peut être appelé par votre programme, mais il n'y est pas lié. C'est une entité entièrement externe (comme les programmes du/bin
répertoire).En pratique, pour les bibliothèques et les frameworks fournis par le système, vous établissez un lien avec eux et c'est tout ce que vous avez à faire.
Si vous avez besoin de lier une bibliothèque que vous avez construite qui n'a pas besoin de ressources intégrées (c'est-à-dire ne nécessite pas de framework pour exister), alors vous pouvez simplement créer un lien avec une bibliothèque statique. Si vous trouvez que vous avez plusieurs modules dans votre programme qui souhaitent utiliser le même code de bibliothèque, le convertir en un framework ou une bibliothèque dynamique et établir une liaison avec cela peut économiser de l'espace et peut être pratique (en particulier si l'utilisation de la mémoire est un problème).
Enfin, les frameworks peuvent inclure non seulement des ressources, mais aussi des fichiers d'en-tête et / ou de licence. Utiliser un framework pour véhiculer ces fichiers est en fait un mécanisme de distribution pratique si souvent vous voudrez peut-être incorporer un framework juste pour que ces éléments puissent être associés à votre binaire (c'est-à-dire que les exigences de licence peuvent rendre cela obligatoire).
--- ÉDITER ---
Adam Johns a posté la question suivante en commentaire:
Je dis qu'un binaire intégré n'est qu'un autre fichier de ressources dans votre bundle, comme un fichier audio ou une image, bien que le fichier soit plutôt un outil de ligne de commande exécutable. La
popen()
fonction (man popen
depuis votre terminal pour en savoir plus) vous permet d'exécuter des programmes arbitraires à partir d'un autre programme en cours d'exécution. Lasystem()
fonction est une autre manière. Il y en a d'autres, et je vais donner ici un exemple historique qui peut rendre la compréhension de l'utilisation d'un binaire intégré un peu plus claire:Comme vous le savez probablement, lorsque vous lancez une application sur Mac OS X, elle est lancée avec un identifiant d'utilisateur de l'utilisateur actuel. Dans les installations les plus courantes, il s'agit de l'utilisateur par défaut sur le bureau
admin
, auquel un identifiant d'utilisateur est attribué501
.Sur les systèmes d'exploitation Unix, seul l'
root
utilisateur (ID utilisateur0
) a un accès complet à l'ensemble du système de fichiers. Il arrive parfois qu'un programme d'installation lancé par l'utilisateur Desktop ait besoin d'installer des fichiers dans un répertoire privilégié (pilotes par exemple). Dans ce cas, le programme d'application doit élever ses privilèges à l'root
utilisateur afin qu'il puisse écrire dans ces répertoires restreints.Pour faciliter cela dans les systèmes d'exploitation via OS X 10.7, Apple a fourni dans son API Authorization Services la fonction AuthorizationExecuteWithPrivileges () (c'est maintenant obsolète, mais c'est toujours un exemple utile).
AuthorizationExecuteWithPrivileges()
a pris comme argument un chemin vers un outil de ligne de commande pour exécuter en tant queroot
. L'outil de ligne de commande était un script shell exécutable ou un binaire compilé que vous aviez écrit pour exécuter votre logique d'installation. Cet outil a été installé dans votre ensemble d'applications comme n'importe quel autre fichier de ressources.Lorsqu'il est appelé, le système d'exploitation affiche une boîte de dialogue d'autorisation demandant le mot de passe de l'utilisateur (vous l'avez déjà vu!) Et une fois entré, il exécute le programme au nom
root
de votre application. Ce processus est similaire à la simple exécution d'un programme avecpopen()
vous-même, bien quepopen()
seul ne vous donne pas l'avantage d'une élévation de privilèges.la source
link
, mais vous avez raison de dire que vous devez également l'intégrer via une phase de copie de fichiers (sinon comment l'utiliseriez-vous?). Le but de l'utilisation d'un framework tiers ou d'un binaire intégré est d'exécuter le code fourni par l'entité. Avec un binaire intégré, aucune liaison n'est impliquée. Au moment de l'exécution, vous construisez un chemin vers le binaire, puis vous l'exécutez manuellement. Avec un framework, l'éditeur de liens au moment de la compilation le liera lorsque vous construirez votre application, puis (s'il s'agit d'un framework tiers) vous l'incorporerez via une phase de copie de fichiers, et enfin l'éditeur de liens d'exécution le liera à nouveau lorsque vous exécutez votre application. .En bref,
Pourquoi?
la source
Cela fait partie de la
Dependency
gestion [À propos]Veuillez noter que
Xcode 11
ne contient que laFrameworks, Libraries, and Embedded Content
section dans l'General
ongletLien binaire
Build Phases -> Link Binary With Libraries
est un miroir deGeneral -> Linked Frameworks and Libraries
.Bibliothèque statique et cadre
Si vous ajoutez un
Static Library or Static Framework
à cette section, il apparaîtra dans leFrameworks
groupe [À propos] (Project Navigator -> <workspace/project> -> Frameworks
) et une référence sera ajoutée à votre projet pour cela. Ensuite, il sera utilisé parStatic Linker
.Static Linker
au moment de la compilation inclura / copiera tout le code de la bibliothèque dans le fichier objet exécutable.Static linker
fonctionne en paire avecBuild Settings -> <Library/Framework> Search Paths
Static Library
Build Settings -> Library Search Paths
[bibliothèque introuvable] Si vous n'ajoutez pas de astatic library
à cette section, vous obtiendrez une erreur de l'éditeur de liens [ld: symbole (s) non trouvé]Static Framework
Build Settings -> Framework Search Paths
. Si vous n'ajoutez pas de astatic framework
à cette section, vous obtiendrez une erreur de compilation [No such module]Incorporer le binaire
Bibliothèque statique et cadre statique
L'intégration n'aurait aucun sens pour a
Static Library
etStatic Framework
parce que leurs symboles sont compilés dans l'exécutable binaire. Xcode ne vous permettra pas de déposer unstatic library
sous la section Intégrer.Cadre dynamique
Build Phases -> Embed Frameworks
est un miroir deGeneral -> Embedded Binaries
. L'intégration ajoute en fait une copie du framework dans votre bundle d'applications. En conséquence, lorsqu'un cadre est ajouté / supprimé à laEmbed
section, il sera automatiquement ajouté / supprimé à laLinked
section. Par défaut, le dossier du bundle estFrameworks
mais vous pouvez le modifier à l'aide deDestination
field. De plus, vous pouvez spécifier un fichierSubpath
.Dynamic linker :dyld
au chargement ou à l'exécution essaiera de trouver le framework intégré à l' aide de@rpath
[About] S'il n'est pas trouvé, l'erreur se produira [dyld: Bibliothèque non chargée][Lorsque vous utilisez Link and Embed]
[Vocabulaire]
la source