ios xcode frameworks embedded-binary

¿Cuándo debemos usar "binarios incrustados" en lugar de "Marcos vinculados" en Xcode?



frameworks embedded-binary (3)

Hay una buena pregunta sobre la diferencia entre esas dos opciones como se describe en Enlace binario con bibliotecas VS Embed Frameworks .

Parece que tenemos opciones para usarlos a ambos, solo me pregunto qué caso deberíamos usar mejor los binarios incrustados, o en lugar del marco vinculado.

¿Algún ejemplo sólido para abordar esto más claro? Gracias


En breve,

  • bibliotecas del sistema, vincularlas;
  • Bibliotecas de terceros, incrustarlas.

¿por qué?

  • si intenta incrustar bibliotecas del sistema, no las encontrará en la lista emergente;
  • si vincula bibliotecas de terceros, probablemente obtendrá un bloqueo.

Es parte de la gestión de Dependency [Acerca de]

Tenga en cuenta que Xcode 11 contiene solo la sección Frameworks, Libraries, and Embedded Content en General pestaña General

Enlace binario

Build Phases -> Link Binary With Libraries es un espejo de General -> Linked Frameworks and Libraries .

Biblioteca estática y marco

Si agrega una Static Library or Static Framework a esta sección, aparecerá en el grupo Frameworks y se agregará una referencia a su proyecto. Luego será utilizado por Static Linker . Static Linker en tiempo de compilación incluirá / copiará todo el código de la biblioteca en el archivo de objeto ejecutable.

Static Library

  • Si no agrega una static library a esta sección, recibirá un error de enlazador [ld: símbolo (s) no encontrado (s)] . También el Static linker funciona en pareja con Build Settings -> Library Search Paths biblioteca [biblioteca no encontrada]

Framework

Debería funcionar con Build Settings -> Framework Search Paths [No existe tal módulo]

  • Si no agrega un static framework a esta sección, obtendrá un error de compilación [No existe tal módulo] .
  • Puede omitir esta sección para dynamic framework .

Incrustar binario

Biblioteca estática y marco estático

Incrustar no tendría ningún sentido para una Static Library y un Static Framework porque los símbolos de ellos se compilan en el ejecutable. Xcode no le permitirá colocar una static library en la sección Incrustar.

Marco Dinámico

Build Phases -> Embed Frameworks es un espejo de General -> Embedded Binaries . La incrustación en realidad agrega una copia del marco en su paquete de aplicaciones. Como resultado, cuando se agrega / elimina un marco a la sección Embed , se agregará / eliminará automáticamente a la sección Linked . Por defecto, la carpeta del paquete es Frameworks pero puede cambiarla usando el campo Destination . Además, puede especificar un Subpath .

Dynamic linker :dyld en carga o tiempo de ejecución intentará encontrar el marco incrustado usando @rpath [Acerca de] Si no se encuentra, se producirá el error [dyld: Biblioteca no cargada]

[Cuando usa Enlace e Incrustar]

[Vocabulario]

La fuente está aquí .


La pregunta que ha vinculado hace referencia a la funcionalidad "Vincular binario con bibliotecas", que es algo diferente de un binario incrustado.

"Enlace binario con bibliotecas" significa lo que esperaría con respecto al enlace: independientemente de si el binario es una biblioteca estática, una biblioteca dinámica o un marco, estará vinculado a su código de objeto en el momento del enlace después de la compilación.

Cuando piensa en la vinculación con una biblioteca estática, lo que sucede es bastante claro: el vinculador copia el código de la biblioteca (por ejemplo, libFoo.a ) en su binario de salida. Su archivo de salida aumenta de tamaño pero no necesita resolver ninguna dependencia externa en tiempo de ejecución. Todo lo que su programa necesita para ejecutarse (con respecto a la biblioteca estática) está presente después de su creación.

Con una biblioteca dinámica (.dylib, o marco proporcionado por el sistema), la expectativa es que la biblioteca con la que se está vinculando estará presente en algún lugar de la ruta del cargador de la biblioteca dinámica del sistema cuando ejecute su programa. De esta manera no tiene la sobrecarga de copiar todas las bibliotecas externas de terceros en su binario, y todos los diferentes programas en una computadora que también se vinculan a esa biblioteca podrán encontrarla, lo que ahorra un mínimo espacio en disco, pero también potencialmente espacio de memoria, dependiendo de cómo y dónde el sistema almacena en caché las bibliotecas.

Un marco es muy parecido a una biblioteca dinámica, pero puede contener recursos en su estructura de directorios (imágenes, audio, otros marcos, etc.). En este caso, una simple biblioteca estática o un archivo .dylib no lo cortará, por lo que es posible que deba vincular a un marco solo para que pueda encontrar lo que necesita para ejecutarse correctamente.

Cuando se vincula a un marco de terceros (por ejemplo, algo que descargó de github y creó usted mismo), es posible que no esté presente en el sistema en el que desea ejecutar. En este caso, no solo vincularía al marco, sino que también lo incrustaría dentro de su paquete de aplicaciones utilizando la fase "Copiar marcos". Cuando se ejecuta su programa, el runtime-linker (también conocido como el resolutor) buscará dentro de su paquete además de la ruta del cargador del sistema, encontrará el marco incrustado y lo vinculará para que su aplicación tenga el código que necesita para ejecutarse.

Finalmente, lo que es propiamente un "binario incrustado" es un ejecutable que ambos incrustan en su paquete de aplicaciones a través de una Fase de Copiar Archivos, y que usted mismo ejecuta, quizás con una llamada a popen() o similar. El programa puede llamar al binario incrustado, pero no está vinculado con él. Es una entidad totalmente externa (como los programas en el directorio /bin ).

En la práctica, para bibliotecas y marcos proporcionados por el sistema, se vinculará con ellos y eso es todo lo que necesita hacer.

Si necesita vincular una biblioteca que creó que no necesita recursos integrados (es decir, no requiere que exista un marco), puede simplemente vincular con una biblioteca estática. Si encuentra que tiene varios módulos en su programa que desean usar el mismo código de biblioteca, entonces convertirlo en un marco o biblioteca dinámica y vincularlo puede ahorrar espacio y puede ser conveniente (particularmente si el uso de memoria es una preocupación).

Finalmente, los marcos pueden incluir no solo recursos, sino también archivos de encabezado y / o licencia. El uso de un marco para transmitir estos archivos es en realidad un mecanismo de distribución conveniente, por lo que a menudo es posible que desee incorporar un marco solo para que estas cosas puedan etiquetarse junto con su binario (es decir, los requisitos de licencia pueden hacer que esto sea obligatorio).

--- EDITAR ---

Adam Johns publicó la siguiente pregunta como comentario:

Esta es una respuesta genial. Sin embargo, hay algo en lo que todavía estoy un poco confundido. ¿Qué significa ejecutar el binario usted mismo? ¿Te refieres a simplemente usar el código del marco incrustado? Sé que mencionaste popen (), pero ¿estás diciendo que mi aplicación está llamando popen ()? Realmente no sé lo que eso significa.

Estoy diciendo que un binario incrustado es solo otro archivo de recursos en su paquete, como un archivo de audio o imagen, aunque el archivo es en cambio una herramienta de línea de comandos ejecutable. La función popen() ( man popen desde su terminal para leer más sobre él) le permite ejecutar programas arbitrarios desde otro programa en ejecución. La función system() es otra forma. Hay otros, y daré un ejemplo histórico aquí que puede hacer que el uso de un binario incrustado sea un poco más claro:

Como probablemente ya sepa, cuando inicia una aplicación en Mac OS X, se inicia con una identificación de usuario del usuario actual. En las instalaciones más comunes, ese es el usuario administrador predeterminado de usuario en el escritorio, al que se le asigna la identificación de usuario 501 .

En los sistemas operativos basados ​​en Unix, solo el usuario root (ID de usuario 0 ) tiene acceso completo a todo el sistema de archivos. A veces sucede que un programa instalador lanzado por el usuario de Desktop necesita instalar archivos en un directorio privilegiado (controladores, por ejemplo). En este caso, el programa de aplicación necesita escalar sus privilegios al usuario root para que pueda escribir en estos directorios restringidos.

Para facilitar esto en los sistemas operativos a través de OS X 10.7, Apple proporcionó en su API de servicios de autorización la función AuthorizationExecuteWithPrivileges() (ahora está en desuso, pero sigue siendo un ejemplo útil).

AuthorizationExecuteWithPrivileges() tomó como argumento una ruta a una herramienta de línea de comandos para ejecutarla como root . La herramienta de línea de comando era un script de shell ejecutable o un binario compilado que escribiste para ejecutar tu lógica de instalación. Esta herramienta se instaló dentro de su paquete de aplicaciones al igual que cualquier otro archivo de recursos.

Cuando se le llama, el sistema operativo muestra un diálogo de autorización que solicita la contraseña del usuario (¡ya lo ha visto antes!) Y cuando se ingresa, ejecuta el programa como root en nombre de su aplicación. Este proceso es similar a solo ejecutar un programa con popen() usted mismo, aunque popen() solo no le brinda el beneficio de la escalada de privilegios.