Pregunta

Mi proyecto consiste en un par de bibliotecas estáticas, que están vinculadas en un paso final. Ahora tengo el problema, que el El orden de enlace de la biblioteca es importante (De lo contrario, obtengo un error de enlazador de símbolos indefinido). A veces me encuentro con el problema, que tengo que volver a sesgar las bibliotecas vinculadas (-lcommon -lsetup -lcontrol, etc.). En este momento es una estúpida prueba y error: volver a escrestar, compilar, verificar el error, volver a clasificar, compilar, etc.

Así que escribí un pequeño programa para mostrarme las dependencias interbibliotecas y me genera el orden de las bibliotecas para vincular. Se lee en los símbolos definidos ('t', 'b', etc.) y indefinidos ('u') de Nuevo Méjico y elimina el símbolos débiles ('W', 'W', 'V' y 'V') de la 'Lista de símbolos indefinidos'. Ahora determina para cada símbolo indefinido la biblioteca que la resuelve.

Pero mi programa me muestra dependencias circulares ... ¿Cuál es mi error?

Si realmente existen, no podría vincular en absoluto ... así que ¿Qué extrañé al analizar la salida de NM?? ¿O analizar la salida de NM no es la forma, para obtener estas dependencias?

libcommon.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
libhardware.a:
00000484 T _ZN15HardwareUnit23GetHardwareSerialNumberEv
libsecurityaccess.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
---
libhardware.a:
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
libsecurityaccess.a:
00004020 T _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
¿Fue útil?

Solución

Otra opción para vincular bibliotecas con dependencias circulares es utilizar una opción de enlazador especial para eso. Hombre ld:

   -( archives -)
   --start-group archives --end-group
       The archives should be a list of archive files.  They may be either
       explicit file names, or -l options.

       The specified archives are searched repeatedly until no new
       undefined references are created.  Normally, an archive is searched
       only once in the order that it is specified on the command line.
       If a symbol in that archive is needed to resolve an undefined
       symbol referred to by an object in an archive that appears later on
       the command line, the linker would not be able to resolve that
       reference.  By grouping the archives, they all be searched
       repeatedly until all possible references are resolved.

       Using this option has a significant performance cost.  It is best
       to use it only when there are unavoidable circular references
       between two or more archives.

Sin embargo, siempre es más limpio eliminar las dependencias circulares.

Otros consejos

Si realmente tiene una cadena de dependencia circular de bibliotecas estáticas (y esto no está claro de su pasta; solo muestra una dependencia no circular), hay dos opciones:

  1. Retire la dependencia circular de alguna manera; Por ejemplo, puede asegurarse de que LibCommon no haga referencia a símbolos en LibpThardware.
  2. Extraiga los archivos .o individuales de la biblioteca .a y enléalos directamente. Entonces el pedido de enlace ya no importa.

En el caso de 2., es posible que le resulte útil usar un enlace parcial en lugar de crear bibliotecas estáticas. En los sistemas que utilizan Bintools GNU, esto se puede hacer invocando algo como:

ld -r -o libfoo.o foo.o bar.o

El efecto de esto es combinar foo.o y bar.o en un solo archivo .o. El orden no importa. Luego puede simplemente hacer referencia a Libfoo.o como un archivo de objeto normal en su paso final de enlace.

Tenga en cuenta que hacer esto puede interferir con la capacidad del enlazador para descartar porciones no referenciadas de la biblioteca estática (Normalmente esto se hace a nivel de archivos .o dentro del .a, creo). Si está utilizando todas o la mayoría de estas bibliotecas, esto probablemente no sea un problema. Sin embargo, si la memoria del código es un problema, es posible que desee investigar Descartar automáticamente el código no utilizado en el nivel de función. Si haces esto, pasa --gc-sections y -s Solo en el final ¡Enlace en la etapa (y evite hacerlo si necesita depurar!). Además, la vinculación estática con las bibliotecas del sistema no parece ser necesaria con el CCG moderno.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top