module - example - cmake link library
¿Diferencia entre módulos y bibliotecas compartidas? (3)
Creo que la distinción que se está haciendo es que las bibliotecas compartidas son especificadas por el desarrollador en tiempo de compilación y deben estar presentes para que la aplicación se ejecute, aunque sus métodos se cargan en tiempo de ejecución. Un módulo, es decir, un complemento, agrega soporte adicional en tiempo de ejecución, pero no es necesario. Sí, puede dlopen () una biblioteca compartida, pero en ese caso no se habría especificado como una parte requerida del programa y las funciones como un módulo.
El título lo cubre principalmente, ¿cuál es la diferencia entre un módulo y una biblioteca compartida? Acabo de encontrar esta distinción en el comando add_library
de CMake, donde dicen:
Las bibliotecas COMPARTIDAS están vinculadas dinámicamente y cargadas en tiempo de ejecución. Las bibliotecas MODULE son complementos que no están vinculados a otros destinos pero que pueden cargarse dinámicamente en tiempo de ejecución utilizando la funcionalidad similar a dlopen.
Pero puedo cargar un objeto compartido usando dlopen (), ¿no puedo?
La diferencia es que puede vincularse a una biblioteca COMPARTIDA con el vinculador, pero no puede vincularlo a un MÓDULO con el vinculador. En algunas plataformas.
Entonces ... para ser completamente multiplataforma y trabajar en todas partes, CMake funciona, nunca debes hacer esto:
# This is a big NO-NO:
add_library(mylib MODULE ${srcs})
target_link_libraries(myexe mylib)
Para ser justos, en Windows, ambos son solo archivos DLL, por lo que este código podría funcionar. Pero cuando lo lleva a una plataforma donde es imposible enlazar con el MÓDULO, encontrará un error.
Línea inferior: si necesita enlazar a la biblioteca, use COMPARTIDO. Si tiene la garantía de que la biblioteca solo se cargará dinámicamente, entonces es seguro usar un MÓDULO. (Y quizás incluso es preferible ayudar a detectar si alguien intenta vincularlo ...)
Otra diferencia está en cómo se ..._OUTPUT_DIRECTORY
y ..._OUTPUT_NAME
:
Las bibliotecas de módulos siempre se tratan como destinos de biblioteca. Para plataformas que no son DLL, las bibliotecas compartidas se tratan como destinos de biblioteca. Para las plataformas DLL, la parte DLL de una biblioteca compartida se trata como un destino de tiempo de ejecución y la biblioteca de importación correspondiente se trata como un destino de archivo. Todos los sistemas basados en Windows, incluido Cygwin, son plataformas DLL.
Por ejemplo, esto significa que si compilas una biblioteca SHARED
en Windows, LIBRARY_OUTPUT_DIRECTORY
se ignorará, porque en su lugar está buscando ARCHIVE_OUTPUT_DIRECTORY
y RUNTIME_OUTPUT_DIRECTORY