2011-02-07 8 views
16

que tienen una aplicación C++ que he heredado, que consiste en:¿Puedo obtener un informe de TODAS las bibliotecas vinculadas al compilar mi ejecutable de C++ (gcc)? (Incluyendo enlazado estáticamente)

  • Mi principal de aplicaciones
  • Varias bibliotecas específicas de la aplicación (libapp1, libapp2, etc ...)
  • Varias bibliotecas "de terceros" (la mayoría de las "terceras partes son solo otros equipos de la empresa") vinculadas desde la aplicación principal, desde las bibliotecas libappX específicas de la aplicación y desde otras bibliotecas de terceros: por ej. libext1, libext2, etc ...

En otras palabras, mi código es el siguiente:

// main.C 
#include <app1/a1l1.H> 
#include <app2/a2l1.H> 
#include <ext1/e1l1.H> 

// app1/a1l1.H 
#include <app1/a1l2.H> 
#include <ext2/e2l1.H> 

// app2/a2l1.H 
#include <ext2/e2l2.H> 

// ext1/e1l1.H 
#include <ext3/e3l1.H> 

// ext3/e3l1.H 
#include <ext4/e4l1.H> 

preguntas:

1) ¿Cómo puedo saber qué bibliotecas se han relacionado en el ejecutable final? Esto debe incluir enlazados estáticamente los

En otras palabras, quiero una respuesta de "app1, app2, ext1, ext2, ext3, ext4"

Idealmente, la respuesta estaría disponible desde el propio ejecutable (Tengo una versión de depuración construida en caso de que lo haga más posible). Si eso es imposible, me gustaría saber si hay una herramienta simple de análisis de código (es decir, algo dentro de gcc) para proporcionar ese análisis.

Tenga en cuenta que los archivos de objeto para bibliotecas externas ya están construidos, así que mirando los registros de compilación para ver lo que estaba vinculado, me preocupa que "ext4" no aparezca en el registro ya que no lo haremos construyendo una biblioteca "ext3" que ya está preconstruida.

NOTA: ejecutar "nmake" con DEPS establecido en yes para reconstruir todo NO es una opción. Pero SI TENGO acceso al código fuente completo para bibliotecas externas.

2) Una pregunta ligeramente separada y menos importante, ¿cómo puedo decir una lista de todos los incluir archivos utilizados en todo el árbol fuente que estoy construyendo. Nuevamente, idealmente frm ya ejecutado ejecutable, que tengo una versión de depuración de.

=================

ACTUALIZACIÓN: Solo para aclarar, nuestras bibliotecas están vinculadas de forma estática, por lo ldd (Lista Synamic Dependencias) no funciona.

Además, la respuesta puede ser para Solaris o Linux, no importa.

He intentado utilizar nm pero eso no enumera las bibliotecas

+0

¿Qué plataforma estás usando? – Tom

+0

@Tom, ya sea Solaris o Linux. No me importa si la respuesta es genérica para ambos o solo funciona en uno. – DVK

+0

Sugeriría ldd para su primera pregunta – Tom

Respuesta

21

tuve un problema similar y solución encontrada: añadir -Wl, - opción detallada cuando se enlaza. Se cambiará enlazador de modo detallado:

gcc -o test main.o -ltest -L. -Wl,--verbose 

Aquí es una salida de ejemplo:

GNU ld (GNU Binutils) 2.23.52.20130604 
    Supported emulations: 
    i386pep 
    i386pe 
using internal linker script: 
================================================== 
/* Default linker script, for normal executables */ 
[many lines here] 
================================================== 
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o succeeded 
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o 
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o succeeded 
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o 
attempt to open main.o succeeded 
main.o 
attempt to open ./libtest.dll.a failed 
attempt to open ./test.dll.a failed 
attempt to open ./libtest.a succeeded 
(./libtest.a)test.o 
[more lines here] 
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o succeeded 
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o 

Actualización: También puede utilizar -Wl, - opción de rastreo en lugar de -Wl, - verbosa . También le dará una lista de bibliotecas, pero es menos detallado.

Actualización 2: -Wl, - trace no muestra las bibliotecas incluidas indirectamente. Ejemplo: se vincula con libA, y libA se vinculó con libB. Si desea ver que también se necesita libB, debe usar -WL, - verbose.

+1

Como nota para los seguidores, los archivos ".o" listas 'ld' para una biblioteca (es decir, los que figuran a continuación) dice 'intento de abrir libXX succeeded') no serán" todos "los archivos .o en una biblioteca, solo los que necesita para satisfacer las dependencias en ese punto. El resto, en esencia, se descarta, aunque esté presente en el archivo .a. ref: http://stackoverflow.com/q/14091669/32453 – rogerdpack

9

Para dependencias directas;

ldd <app> 

Indirecto/Todas las dependencias;

ldd -r <app> 
+0

Disculpe por no aclarar esto antes, las bibliotecas están vinculadas estáticamente. 'ldd' no lista esos. – DVK

+0

Encontré la respuesta que estaba buscando con tu respuesta, ¡gracias! – jredd

1

Intente utilizar ldd + tu nombre de fichero, esto mostrará las librerías.

+1

Disculpe por no haber aclarado esto antes, las bibliotecas están vinculadas estáticamente. 'ldd' no lista esos. – DVK

4

Por lo que sé, no se conserva mucha información sobre las bibliotecas estáticas al vincular (ya que el vinculador simplemente ve esa biblioteca como una colección de objetos * .o de todos modos).

Si encuentra el comando make que vincula el ejecutable final y agrega un indicador -v, g++ le mostrará exactamente cómo llama al comando ld. Esto debería incluir todas las bibliotecas estáticas necesarias, incluidas las bibliotecas utilizadas por otras bibliotecas, o de lo contrario el paso de enlace fallaría. Pero también podría incluir bibliotecas adicionales que no se usan realmente.

Otra cosa posiblemente útil es que, al menos en Linux, los objetos y ejecutables generalmente almacenan los nombres de los archivos de código fuente desde los que se crearon. (Nombre del archivo solamente, hay un camino.) Trate

objdump -t executable | grep '*ABS*' 
+0

objdump parece producir resultados muy similares a 'nm' y no producen realmente listas de bibliotecas. ¿Puedo pasar "-v" a través de un interruptor de línea de comando para nmake? Thx – DVK

+0

@DVK: AT & T nmake? Microsoft nmake? En cualquier caso, probablemente no.Desea encontrar el último comando 'g ++' que hizo o llamaría el proceso make, luego agregue -v a eso. – aschepler

+0

gotcha. Creo que ya lo hace de forma predeterminada ya que creo que veo una lista de todos los archivos .a en la línea de comandos g ++ – DVK

0

Primero responderé a su segunda pregunta. Simplemente puede usar el indicador -H o -M para ver todos los encabezados (incluido el sistema) procesados ​​en la compilación. gcc -H main.c debería hacer el truco. Al ver las cabeceras están incluidos en realidad le permitirá estar en el camino correcto para encontrar qué bibliotecas estáticas estaban vinculados en.

Usted podría utilizar objdump en su objeto final (o readelf en su binario final) para obtener los nombres de todos los funciones allí. Tendría que ir a buscar las bibliotecas desde donde se extrajeron las funciones, pero eso es un poco engorroso. Definitivamente tendrías que hacer un guión para minimizar el dolor.

Alguien mencionó usar gcc <stuff> -Wl,-verbose que simplemente pasa el indicador -verbose al enlazador. Esa es una forma perfecta de obtener una lista de bibliotecas compartidas (archivos .so), pero dijo que las suyas son estáticas, por lo que ese no es el camino a seguir en este caso.

¡Buena suerte!

Cuestiones relacionadas