2010-04-09 21 views
9

Por una razón quiero desempaquetar una lib estática (libx.a) en archivos de objetos individuales (ao bo co) y especificar estos archivos de objetos (ao bo co) en la entrada del enlazador lista en lugar de libx.a, con otras opciones de enlazador que permanecen iguales.enlace con biblioteca estática vs archivos de objeto individuales

Sin embargo, he notado que el cambio anterior ha producido una gran diferencia en el ejecutable de salida. Básicamente, el método (a.o b.o c.o) dará como resultado un mayor tamaño de salida.

¿Cuál es la diferencia entre los dos métodos (libx.a y archivos de objetos individuales)? ¿Y hay alguna manera de evitarlo?

El binutil GNU (a favor y ar ld) versión que estoy usando es 2.16.1

Gracias.

+0

¿Qué es lo que intentas lograr dividiendo los archivos individuales del objeto? –

+0

La razón original fue que, quería especificar la sección de salida para una lib estática en el script del enlazador. Y por alguna razón, la sintaxis del archivo (libx.a: *. O (.text)) no funciona, probablemente debido a la versión binutil desactualizada en mi cadena de herramientas. Como no podía actualizar la cadena de herramientas, tuve que descomprimir la biblioteca y usar los archivos del objeto explícitamente. Y así es como me encontré con este problema. – user313031

Respuesta

10

Ld elimina las partes no utilizadas de los archivos .lib vinculados (como las variables con vinculación global). Esta optimización no puede tener lugar cuando los archivos objeto se pasan directamente, ya que el enlazador no puede determinar si algún elemento no referenciado de un archivo .o lo necesita alguna parte desconocida más tarde (por ejemplo, porque sería visible externamente por la lista de exportación del módulo) o puede ser eliminado por completo. Cuando se instala una .lib en el proceso de enlace, el vinculador sabe con certeza que puede eliminar elementos innecesarios.

+0

No dudo que lo que diga es cierto, pero debe ser una peculiaridad de ld específicamente. Por lo que puedo ver, siempre y cuando esté en el último paso del enlace, ld debería ser capaz de hacer todo el mismo borrado de código muerto con archivos .o como lo hace con un archivo .a. –

+0

La diferencia entre los archivos .lib y .o es que ld trata los archivos .o sin referencia en archivos .lib como descartables, mientras que cada archivo .o se incluye en el resultado. Esto se debe a que existen símbolos especiales (por ejemplo, constructores de C++) que se agrupan en secciones especiales por ld (incluso cuando no están referenciados) para realizar funciones especiales. También existe un interruptor (--whole-archive) para instanciar cada archivo .o sin referencia de los archivos .lib, pero no sé si hay un cambio para eliminar los archivos .o innecesarios. – Rudi

+0

Gracias a todos. Es bueno saber eso. Pero, ¿eso significa que si siempre enlace archivos de objetos individuales en una lib estática antes de vincular el ejecutable final, es más probable que obtenga un resultado más pequeño (si hubo código/datos sin referencia)? Y si eso es cierto, puede ser una técnica útil (aunque suena contra intuitivo). Y vuelva a mi problema original (no se puede especificar el apartado de salida para las librerías estáticas en el script del enlazador), ¿hay alguna manera de solucionarlo? Gracias. – user313031

Cuestiones relacionadas