visual una studio sirve referencia que puedo programa para libreria estatica dinamica crear clases biblioteca archivo agregar linker cmake static-libraries visual-studio-2008-sp1

linker - una - que es un archivo dll y para que sirve



Vinculación de archivos DLL de Windows desde bibliotecas estáticas utilizando CMake sin crear nombres de símbolos no resueltos a mano (1)

La situación

Estoy usando Visual Studio 2008 SP1 (Professional Edition, tanto para versiones de 32 bits como de 64 bits). Estoy buscando una solución a lo que creo que es una " limitation " muy inútil en Visual Studio.

Me parece bastante sorprendente que el enlazador y el compilador de Visual Studio no lo hagan correctamente en el momento de la creación del archivo DLL, para escanear automáticamente todas las bibliotecas estáticas especificadas para todos los símbolos exportados de la misma manera que se indica en Creación de una biblioteca de importación y archivo de exportación y en una Comentario de StackOverflow . __declspec(dllexport) que no es suficiente simplemente aplicar los __declspec(dllexport) y __declspec(dllimport) a las declaraciones de clase, función y datos en los archivos que comprenden las bibliotecas estáticas.

El enlazador no escanea todas las bibliotecas estáticas en busca de símbolos exportados, por lo que no los introducirá en el archivo DLL (los símbolos deben ser referenciados por archivos .obj en la línea de comandos del enlace DLL o por otros medios que se muestran a continuación) . Sin referencias explícitas a cada símbolo exportado, aún se puede crear el archivo DLL, pero no se crea su archivo de biblioteca de importación asociado.

De lo que puedo reunir, Microsoft recomienda usar LIB.EXE para crear el archivo DEF , pero desafortunadamente, la página LIB.EXE aplica una restricción:

Tenga en cuenta que si crea su biblioteca de importación en un paso preliminar, antes de crear su .dll , debe pasar el mismo conjunto de archivos de objetos al crear el archivo .dll , como pasó al crear la biblioteca de importación.

Esa es una restricción desafortunada dado que también estoy usando CMake en mi nuevo entorno de compilación. CMake oculta los detalles de lo que realmente se pasa al vinculador (y considero que eso es algo bueno en el 99% del tiempo), pero en este caso necesito acceder a parte de esa información en el momento de la ejecución de CMake, no después, utilizando guiones hechos a mano u otras skulduggery .

Las preguntas:

¿Cómo hago para forzar al enlazador de DLL a resolver todos los símbolos exportados en todas las bibliotecas estáticas que comprenden el archivo DLL, que no generarán fragilidad y tareas adicionales de mantenimiento de la lógica de compilación? Piense en términos de automatización completa aquí, y tenga en cuenta que tengo que hacer esto varias veces para múltiples DLL diferentes.

Mis preguntas son:

  1. ¿Cómo obtengo el conjunto de archivos de objetos y bibliotecas estáticas utilizadas en la línea de comandos final del enlace DLL utilizando solo la sintaxis CMake?

  2. ¿El orden de los archivos enumerados en la línea LIB.EXE (el que se utiliza para generar el archivo DEF ) tiene que coincidir exactamente con el orden utilizado en la línea de enlace DLL?

  3. ¿Hay otras dificultades que pueda encontrar con el uso del enfoque LIB.EXE para generar el archivo DEF ?

  4. ¿Hay una mejor manera de hacerlo que no requiera llamar a una utilidad separada, como LIB.EXE, antes de llamar al enlace final? Me preocupa la sobrecarga de compilación adicional más allá del enlace en sí mismo para que LIB.EXE vuelva a escanear todas las bibliotecas estáticas a pesar de que las escribió en ejecuciones separadas.

Las No-Respuestas:

Las siguientes son soluciones que no puedo considerar en este momento:

  1. Especifique manualmente los símbolos no referenciados en cualquier lugar que no sea en los archivos .h o .cpp originales, ya que hacerlo se romperá cada vez que un desarrollador olvide actualizar el archivo que enumera el nombre del símbolo (muy posiblemente con nombre). Y se romperá con los errores de enlace no fáciles de usar sobre los símbolos no resueltos, lo que será costoso para los desarrolladores depurar. Esta no respuesta incluye los siguientes enfoques:

    1. .obj explícitamente los archivos .obj a la línea de comandos del enlace DLL, (las variantes de esto incluyen agregar archivos .obj "falsos" que tienen referencias ficticias a los símbolos de otro modo no referenciados pero exportados (y tenga en cuenta que esto es lo que mi entorno de compilación anterior hace hoy, y apesta)), y

    2. Elaboración DEF archivos DEF para incluir los símbolos no referenciados pero exportados, y,

    3. Opciones de línea de comandos del vinculador que hacen referencia específica a los símbolos de símbolos sin referencia pero exportados.

  2. Deja de usar bibliotecas estáticas por completo. No puedo hacer eso en el corto plazo, ya que es un cambio estructural del entorno de construcción anterior del que me estoy alejando. Es muy probable que tome esta ruta en el futuro, una vez que todos los restos del entorno de compilación anterior estén en la "papelera de reciclaje", pero ese no es mi enfoque aquí.

Material de referencia:


Solo estoy respondiendo para aclarar que tu sensación de no usar bibliotecas estáticas es correcta.

DLRdave dijo que ya en los comentarios, su sistema de compilación está siendo abusado por los archivos LIB. Un archivo LIB es muy parecido a una biblioteca real, solo sale con lo que pide, no todo en la biblioteca.

Si hay un vacío en el conjunto de herramientas de Visual Studio 2008, es que no admite la vinculación parcial. La entrada en un enlace parcial es un conjunto de archivos OBJ y la salida es un solo archivo OBJ que contiene todo el código y los datos de los archivos OBJ de entrada.

La diferencia entre un archivo / biblioteca y un enlace parcial se describe para g ++ en la respuesta a esta pregunta: ¿ g ++ enlace parcial en lugar de archivos? , donde el enlazador GNU ( ld ) soporta enlaces parciales.

En cuanto a la posible mitigación a corto plazo, personalmente, habría tratado de usar scripts para generar dinámicamente el archivo DEF en el momento de la compilación utilizando LIB /List o DUMPBIN /ARCHIVEMEMBERS para obtener los archivos obj y LIB /DEF para generar el archivo DEF a partir de ese lista. O, como supongo que se está utilizando _declspec(dllexport ), también podría haber utilizado DUMPBIN /DIRECTIVES , buscar /EXPORT y DUMPBIN /DIRECTIVES el archivo DEF usted mismo.