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:
C'est une excellente réponse. Il y a cependant quelque chose sur lequel je suis encore un peu confus. Que signifie exécuter le binaire vous-même? Voulez-vous dire simplement utiliser le code du framework intégré? Je sais que vous avez mentionné popen (), mais vous dites que mon application appelle popen ()? Je ne sais pas vraiment ce que ça veut dire.
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. La system()
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 utilisateur 0
) 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 que root
. 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 avec popen()
vous-même, bien que popen()
seul ne vous donne pas l'avantage d'une élévation de privilèges.