2010-10-05 8 views
19

Al vincular una biblioteca estática con un archivo ejecutable, los símbolos sin referencia se descartan normalmente. En mi caso, algunos objetos no utilizados se utilizan para registrar sus clases respectivas en una fábrica y si los objetos se descartan, este registro falla.¿Cuál es el equivalente de Microsoft Visual Studio a la opción ld de GCC? --whole-archive

En Unix, donde utilizamos gcc, puedo pasar la bandera --whole-archive al linker ld (ver extracto de la documentación ld a continuación), que hace que ld no descarte ningún objeto. ¿Hay algo como esto para Visual C++?

--whole-archivo

        Para cada archivo mencionado en la línea de comandos después de la opción
        `--whole-archivo', incluyen todos los archivos objeto en el archivo
        en el enlace, en lugar de buscar en el archivo el requerido
        archivos de objeto. Esto se utiliza normalmente para convertir un archivo de almacenamiento en
        una biblioteca compartida, obligando a todos los objetos que se incluirán en el
        resultante biblioteca compartida. Esta opción puede usarse más de una vez.

+0

Gracias por la explicación de '--whole-archive', sólo estaba buscando cuál es el escenario para usarlo. – Deqing

Respuesta

7

Que yo sepa, no existe una opción única que lo garantice de manera confiable. Existen combinaciones de opciones de optimización que (silenciosamente) desactivan esto, así que de ninguna manera ... /INCLUDE funciona, pero para eso necesita extraer y codificar el nombre del símbolo. Tiene dos opciones: (1) asegurarse de que todos los registradores estén incluidos (incluidos) en la unidad de traducción que contiene main y haga cumplir su uso. (2) Renuncia a este 'modismo' y utiliza el registro explícito.

Precaución: esta respuesta tiene ahora casi 7 años y las afirmaciones sobre la disponibilidad de opciones en la cadena de herramientas MSVC++ están desactualizadas. Sin embargo, todavía recomiendo no confiar en el patrón del registrador y mirar las alternativas. Por favor, siéntase libre de votar por esta recomendación, pero creo que es un poco injusto votar abajo porque la opción se agregó al enlazador de Microsoft mientras tanto.

+0

Gracias. Seguí la ruta para crear un pequeño programa que extrae todos los nombres de símbolos de la lib estática y los incluye en el programa principal. – fschmitt

+1

Al parecer, esto se canceló silenciosamente dos veces después de casi dos años. ¿Podrías dejar una línea sobre el motivo? –

+0

@fschmitt ¿alguna vez encontró una mejor solución a este problema? –

7

Creo que el equivalente más cercano sería /OPT:NOREF.

+1

Parece que no tiene ningún efecto, esp. considerando que está implícito en las compilaciones de depuración. –

+0

Eso debería, pero no funciona para nada, y no solo para mí. Muy desafortunado. –

4

Uso /INCLUDE: para forzar la inclusión de símbolos no utilizados.

0

Utilicé otro enfoque: en lugar de compilar todo en un .lib y luego vincular ese .lib al ejecutable, enlace el ejecutable directamente con los archivos .obj.

En CMake, esto se puede hacer de esta manera:

add_library(common OBJECT ${common_sources}) 
add_executable(executable1 "main1.cc" $<TARGET_OBJECTS:common> 
add_executable(executable2 "main2.cc" $<TARGET_OBJECTS:common> 

Cambios en cualquiera de los archivos en ${common_sources}) única recompila sus objetos equivalentes y vuelve a vincular los archivos ejecutables, que proporciona los mismos beneficios que si se enlazó las cosas a través intermedia .lib. Al mismo tiempo, todos los constructores estáticos permanecen en su lugar, lo que resuelve el problema.

Tenga en cuenta que esto solo es útil si vincula cosas estáticamente.

Este enfoque se probó con gcc 5.2.0, 5.2.0 MinGW-W64 y MSVC 15.

0

En la página de propiedades de la mirada ejecutable en propiedades comunes/Referencias/set uso de la biblioteca de dependencia Las entradas que a la verdadera . Eso es más o menos el equivalente en MS de - todo el archivo en pocas palabras.

Editar: Sin embargo, la biblioteca en cuestión debe ser parte de la solución.

+0

¿Puedes dar eso como opciones de línea de comando? –

+0

No, agrega todos los archivos obj al comando del enlazador en lugar de los archivos lib. –

16

La versión de Visual C++ en Visual Studio 2015 Actualización 2 incluye una nueva bandera para link.exe llamada /WHOLEARCHIVE, que tiene una funcionalidad equivalente a la opción --whole-archive a ld. De acuerdo con the flag documentation:

La opción /WHOLEARCHIVE obliga al enlazador para incluir todos los archivos objeto desde una biblioteca estática especificada, o si no hay ninguna biblioteca es especificado, de todas las bibliotecas estáticas especificadas para el comando LINK.

+0

Guau, esto es enorme. Gracias por la info. – fschmitt

3

Se puede utilizar con CMake como:

add_executable(hello ${SOURCE_FILES}) 
target_link_libraries(hello libA libB libC)  # Not need /wholearchive libC 
set_target_properties(hello PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:libA /WHOLEARCHIVE:libB") 

Nota: /WHOLEARCHIVE sólo disponible Visual Studio 2015 Actualizar 2+

Cuestiones relacionadas