2010-11-11 7 views
10

Además de usar -nostdlib y vincular crt1.o -lc -lgcc, ¿hay alguna manera fácil de evitar que gcc vincule crtbegin[S].o y crtend[S].o? Estos archivos no son tan grandes, pero estoy jugando con pequeños binarios y me gustaría eliminar el inútil código de soporte C++ que no es necesario para los programas C. (Presumiblemente, gcc los vincula incluso para programas C en caso de que esté utilizando una biblioteca C++ con variables de objetos globales. Les ahorraré a todos la diatriba sobre cómo debería generar llamadas de inicialización seguras y únicas en todos los lugares donde se hace referencia al objeto global en C++ módulos en lugar de inicializar objetos globales antes de main ...)¿Hay alguna manera fácil de hacer que gcc omit crtbegin.o/crtend.o?

No me opondría a hackear el archivo gcc specs para hacer la vinculación de los archivos de soporte C++ condicional en tal y tal, pero estoy no estoy seguro de cómo haría eso. Tal vez ya hay una buena manera?

+0

Creo que también son necesarios para las funciones '__attribute__ ((constructor))' (y 'destructor'). (y estoy lejos de ser un experto en C++, pero me dijeron que para cumplir con el estándar, los constructores globales tienen que suceder antes de que se llame a 'main()') – caf

+0

@caf: Tenía la impresión de que el C++ estándar especifica que los constructores son llamados en un tiempo no especificado entre la invocación del programa y la primera vez que se utiliza (y por supuesto en un orden no especificado, aparte de los casos donde un objeto hace referencia a otro y así invoca la "primera vez que se usa") . ¿Tiene una referencia a lo contrario? –

+0

Probablemente una "enseñanza de chupar huevos", pero ¿ha intentado usar 'gcc' para compilar e ir directo a su enlazador de sistemas (probablemente' ld') para el paso del enlace real para que tenga un mayor control sobre el enlace? –

Respuesta

6
gcc -wrapper sh,-c,'z= ; for i ; do [ "$z" ] || set -- ; z=1 ; 
    case "$i" in *crtbegin*.o|*crtend*.o) ;; *) set -- "[email protected]" "$i" ;; esac ; 
    done ; exec "$0" "[email protected]"' 
+1

¿alguien puede explicar lo que está sucediendo en el guión anterior? –

+0

@ 4aRkKn1gh7: la opción '-wrapper' hace que gcc invoque los comandos externos que ejecuta a través de un programa contenedora. El programa contenedor es un script de shell que elimina cualquier argumento que coincida con '* crtbegin * .o' o' * crtend * .o' antes de invocar el comando solicitado. Se acaba de escribir en línea en la línea de comandos en lugar de guardar la secuencia de comandos en un archivo. –

3

Creo que necesita la opción -nostartfiles. Eso es lo que necesito para las cosas integradas de todos modos.

+1

Es un buen comienzo (sin juego de palabras), pero también omite 'crt1.o' que contiene el punto de entrada' _start'. –

+0

@R ..: estoy seguro de que podría configurar ENTRYPOINT en el script del enlazador. – leppie

+0

Sí, sé que podría hacerlo así, pero eso es mucho peor que encontrar el camino a 'crt1.o' y usar la línea de comando' gcc' para vincular. Básicamente, estaba buscando lo más parecido a una forma portátil de hacer que gcc no vincule cosas innecesarias, y las respuestas parecen ser que no hay ninguna. –

Cuestiones relacionadas