ejecutar - gcc linux
Error de enlace al compilar el funcionamiento atómico de gcc en modo de 32 bits (2)
Tengo el siguiente programa:
~/test> cat test.cc
int main()
{
int i = 3;
int j = __sync_add_and_fetch(&i, 1);
return 0;
}
Estoy compilando este programa usando GCC 4.2.2 en Linux que se ejecuta en una máquina Intel de varias CPU de 64 bits:
~/test> uname --all
Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux
Cuando compilo el programa en modo de 64 bits, compila y vincula bien:
~/test> /share/tools/gcc-4.2.2/bin/g++ test.cc
~/test>
Cuando lo compilo en modo de 32 bits, aparece el siguiente error:
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccEVHGkB.o(.text+0x27): In function `main'':
: undefined reference to `__sync_add_and_fetch_4''
collect2: ld returned 1 exit status
~/test>
Aunque en realidad nunca ejecutaré en un procesador de 32 bits, sí necesito un ejecutable de 32 bits para poder enlazar con algunas bibliotecas de 32 bits.
Mis 2 preguntas son:
¿Por qué obtengo un error de enlace cuando compilo en modo de 32 bits?
¿Hay alguna forma de hacer que el programa compile y enlace, mientras se puede enlazar con una biblioteca de 32 bits?
Desde la página de GCC en Builtins atómicos :
No todas las operaciones son compatibles con todos los procesadores de destino. Si una operación en particular no puede implementarse en el procesador de destino, se generará una advertencia y se generará una llamada a una función externa. La función externa tendrá el mismo nombre que la función incorporada, con un sufijo adicional `_n ''donde n es el tamaño del tipo de datos.
A juzgar por la salida del compilador, que se refiere a __sync_add_and_fetch_4
, esto es lo que está sucediendo. Por alguna razón, GCC no está generando la función externa correctamente.
Es probable que solo obtenga un error en el modo de 32 bits: al compilar para el modo de 64 bits, compila más de cerca para su procesador. Al compilar para 32 bits, bien puede estar utilizando un arco genérico (i386, por ejemplo) que no admite de forma nativa esas características. Intente especificar una arquitectura específica para su familia de chips (Xeon, Core 2, etc.) a través de -mcpu y vea si eso funciona.
De lo contrario, deberá averiguar por qué GCC no incluye la función apropiada que debería estar generando.
La respuesta de Dan Udey fue cercana, lo suficientemente cerca como para permitirme encontrar la solución real.
De acuerdo con la página man "-mcpu" es un sinónimo en desuso para "-mtune" y solo significa "optimizar para una CPU en particular (pero aún se ejecuta en CPU más antiguas, aunque menos óptima)". Intenté esto, y no resolvió el problema.
Sin embargo, "-march =" significa "generar código para una CPU en particular (y no se ejecuta en CPU más antiguas)". Cuando probé esto, resolvió el problema: la especificación de una CPU de i486 o superior eliminó el error de enlace.
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main'':
: undefined reference to `__sync_add_and_fetch_4''
collect2: ld returned 1 exit status
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main'':
: undefined reference to `__sync_add_and_fetch_4''
collect2: ld returned 1 exit status
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc