2010-11-22 12 views
13

La forma en que se desarrolla el proyecto de mi equipo, generamos una biblioteca de objetos compartidos para nuestra aplicación desde todos nuestros archivos de objetos .o. Mi tarea (espero que sea lo suficientemente específica pero también lo suficientemente general como para ser útil a los demás) es vincular solo los archivos de objeto que han cambiado desde la última vez que se creó el ejecutable. Por ejemplo, aquí está la línea de comando que utilizo para construir el .so:Enlace incremental usando gcc en linux. ¿Es posible?

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o -o libMySharedLibrary.so 

¡Qué funciona como se esperaba! :) Mi objetivo es poder vincular solo los archivos de objetos modificados de ahora en adelante, para acelerar el proceso de vinculación simultáneo. Un comando de ejemplo sería:

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o -o libMySharedLibrary.so 

Qué actualizaría libMySharedLibrary.so con los archivos de objetos nuevos, mientras que el mantenimiento de los archivos de objetos mayores en libMySharedLibrary.so también. En realidad, cuando genero libMySharedLibrary.so usando el comando anterior, el tamaño del archivo es mucho más pequeño que el de cuando se incluyen todos los archivos de objeto, así que casi puedo estar seguro de que el comando anterior no está haciendo lo que quiero.

través de mi investigación he encontrado que hay una opción de -i para el enlazador que es lo mismo que la opción -r, que parece simplemente combinar todos los archivos de objetos en un archivo objeto grande también. Lamentablemente, no parece que esto sea lo que quiero.

En resumen, me gustaría vincular solo los archivos de objetos modificados después del enlace inicial, lo que da como resultado un proceso de enlace más rápido para los enlaces futuros. ¿Hay alguna forma de hacer esto?

EDIT: Un ejemplo de lo que he tratado con -i/-r:

Comando de ejemplo: g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o -o AllMyObjects.o

he tenido que añadir la etiqueta -nostdlib para que deje de gritar a mí sobre la necesidad de ella, y se retira -shared porque los objetos compartidos no están permitidos con la etiqueta -r.

Este comando parece cerrar todos mis archivos .o en un gran archivo .o. Entonces, si pudiera actualizar ese archivo .o de aquí en adelante con solo los archivos .o cambiados, sería genial. Después de que AllMyObjects.o se creó inicialmente, probé este comando: g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o -o AllMyObjects.o, pero también crearía un archivo mucho más pequeño (tamaño de archivo) AllMyObjects.o, por lo que estoy asumiendo que no puede tener todos los archivos de objeto. Siento que esto es algo en lo que probablemente estoy cometiendo un pequeño error. Alguien tiene algún consejo? Gracias por adelantado.

+0

¿La fase de enlace realmente domina tus compilaciones incrementales? Si no, ¿para qué molestarse? – dmckee

+0

¿Puede mostrarnos qué ha intentado con '-i' /' -r'? Parece que * es * la opción que desea, aunque espero que se encuentre con conflictos de símbolos (considerando que no hay opción de 'reemplazar'). –

+0

La fase de enlace no es la parte más lenta de mis compilaciones. Sin embargo, esta es la tarea que el líder de mi equipo me ha dado. Ya somos buenos solo compilando lo que ha cambiado. Actualmente, compilamos solo lo que ha cambiado, mientras reenlazamos cada archivo de objeto cada vez. –

Respuesta

6

Parece que tiene razón en que -shared y -r no funcionan en conjunto. Yo era escéptico acerca de la versión antigua de GCC, pero incluso en Ubuntu 10.10 Veo la misma:

$ ld -shared -r 
/usr/bin/ld.bfd.real: -r and -shared may not be used together 

Por desgracia, eso significa que ha llegado a un callejón sin salida si necesita absolutamente objetos compartidos. El enlazador binutils simplemente no lo implementa.

Si las bibliotecas estáticas son una opción para usted, simplemente son archivos que se pueden manipular fácilmente con la utilidad ar.

De lo contrario, tendrá que mirar diferentes enlazadores o compiladores. Aunque no puedo garantizar que encuentres esta característica, parece exótico.

+0

Ok. Muchas gracias por sus respuestas rápidas. Definitivamente hablaré con el líder de mi equipo y veré si el uso de bibliotecas estáticas sería una opción. También en mi investigación, descubrí un enlazador alternativo llamado "oro" que fue desarrollado por Ian Lance Taylor en Google. Se agregó a los binutils en marzo de 2008. También puedo analizar esto. Esperaba que hubiera una manera de hacer esto usando el enlazador predeterminado, pero no parece que sea el caso. ¡Otra vez, gracias por tu ayuda! –

+3

Parece que tengo 'gold' instalado, pero' gold -shared -r' da el mismo resultado. –

+0

Haha, por supuesto, ese sería el caso. :) De nuevo, gracias por tu ayuda. –

3

Puede obtener el comportamiento que busca utilizando bibliotecas de archivo/estáticas, pero el enlace inicial aún tardará el mismo tiempo.

El uso de un archivo de almacenamiento:

# Initially create the archive 
ar r libmylib.a <all object files> 

# Create your shared object (re-use this line after libmylib.a is updated) 
g++ -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' libmylib.a -o libmylib.so  

# Update the archive file 
ar r libmylib.a updated1.o updated2.o 

Como ya he dicho, todavía tendrá la misma cantidad de tiempo para vincular la realidad .so como lo hacía antes.

Cuestiones relacionadas