2010-03-13 26 views
11

Recientemente, tuve problemas para intentar compilar una biblioteca de código abierto en mi Mac que dependía de otra biblioteca y obtuve algunos errores sobre las arquitecturas de bibliotecas incompatibles. ¿Alguien puede explicar el concepto detrás de la compilación de un programa C para una arquitectura específica? He visto el indicador del compilador -arch anteriormente y he visto valores que se le han pasado, como ppc, i386 y x86_64, que asumo se asignan al "idioma" de la CPU, pero mi entendimiento se detiene allí. Si un programa utiliza una arquitectura particular, ¿todas las bibliotecas que carga deben estar en la misma arquitectura? ¿Cómo puedo saber en qué arquitectura se está ejecutando un programa/proceso determinado?Compilación de un programa C con una arquitectura específica

Respuesta

13

¿Alguien puede explicar el concepto detrás de la compilación de un programa C para una arquitectura específica?

Sí. La idea es traducir C a una secuencia de instrucciones nativas de la máquina, que tienen el programa codificado en forma binaria. El significado de "arquitectura" aquí es "arquitectura de conjunto de instrucciones", que es cómo se codifican las instrucciones en binario. Por ejemplo, cada arquitectura tiene su propia forma de codificación para una instrucción que agrega dos enteros.

El motivo para compilar las instrucciones de la máquina es que funcionan muy, muy rápido.

Si un programa utiliza una arquitectura particular, ¿todas las bibliotecas que carga deben estar en la misma arquitectura también?

Sí. (Existen excepciones pero son raras.)

¿Cómo puedo saber en qué arquitectura se está ejecutando un programa/proceso determinado?

Si un proceso se está ejecutando en su hardware, se está ejecutando en la arquitectura nativa que en Unix se puede descubrir mediante la ejecución del comando uname -m, aunque para el lector humano la salida de uname -a puede ser más informativo.

Si usted tiene un binario ejecutable o una biblioteca compartida (.so), se puede descubrir su arquitectura con el comando file:

% file /lib/libm-2.10.2.so 
/lib/libm-2.10.2.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped 
% file /bin/ls 
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped 

Se puede ver que estos binarios se han compilado para los muy viejos Arquitectura 80386, a pesar de que mi hardware es un i686 más moderno. El i686 (Pentium Pro) es compatible con 80386 y ejecuta 80386 binarios, así como binarios nativos. Para hacer posible esta compatibilidad hacia atrás, Intel se enfrentó a un gran problema y costo —, pero prácticamente arrinconaron el mercado en CPUs de escritorio, ¡así que valió la pena!

1

Para construir una arquitectura diferente de la nativa de su CPU, necesitará un compilador cruzado, lo que significa que el código generado no puede ejecutarse de forma nativa en la máquina en la que está sentado. GCC puede hacer esto bien. Para saber en qué arquitectura está construido un programa para verificar el comando de archivo. En los sistemas basados ​​en Linux, al menos, un programa x86 de 32 bits requerirá libs x86 de 32 bits. Supongo que es lo mismo para la mayoría de los sistemas operativos.

3

Una cosa que puede ser confusa aquí es que la plataforma Mac tiene lo que llaman universal binary, que en realidad son dos binarios en un archivo, uno para Intel y otro para la arquitectura ppc. Su computadora decidirá automáticamente cuál ejecutar. Puede (a veces) ejecutar un binario para otra arquitectura en un modo de emulación, y algunas arquitecturas son superconjuntos de otras (es decir, el código i386 generalmente se ejecutará en un i486, i586, i686, etc.) pero en su mayor parte el único código puede ejecutar es código para la arquitectura de su procesador.

Para la compilación cruzada, no solo el programa, sino todas las bibliotecas que utiliza, deben ser compatibles con el procesador de destino. A veces esto significa tener instalado un segundo compilador, a veces solo se trata de tener disponible el módulo adicional correcto para el compilador. El compilador cruzado para gcc is actually a seperate executable, though it can sometimes be accessed via a command line switch. Los compiladores cruzados de gcc para varias arquitecturas probablemente sean instalaciones separadas.

Cuestiones relacionadas