2010-01-23 17 views

Respuesta

18

No. En general, los formatos de archivo de objetos pueden ser los mismos, p. ELF, pero el contenido de los archivos objeto variará de un sistema a otro.

archivo Un objeto contiene cosas como:

Object code that implements the desired functionality 
A symbol table that can be used to resolve references 
Relocation information to allow the linker to locate the object code in memory 
Debugging information 

El código objeto es por lo general no solo procesador específico, sino también del sistema operativo específico si, por ejemplo, contiene las llamadas al sistema.


Editar:

Is it possible to compile program on one platform and link with other ? 

Absolutamente. Si usa un compilador cruzado. Este compilador se dirige específicamente a una plataforma y genera archivos de objeto (y programas) que son compatibles con la plataforma de destino. De modo que puede usar un sistema X86 Linux, por ejemplo, para crear programas para un sistema powerpc o basado en ARM utilizando el compilador cruzado apropiado. Lo hago here.

16

¿Es posible compilar programas en una plataforma y vincular con otros?

En general, no. Los archivos de objeto son específicos del compilador. Algunos compiladores escupieron COFF, otros escupieron ELF, etc. Además de eso, debe preocuparse por las convenciones de llamadas, llamadas al sistema, etc. Esto depende de la plataforma.

¿Qué contiene el archivo objeto?

tablas de símbolos, código, ubicación, información de enlace y depuración.

Si lo que busca es la portabilidad, escriba C/C++ portátil y permita que un compilador compatible con plataforma específica haga el trabajo.

+4

No creo que vaya tan lejos como para decir que la compilación cruzada es peligrosa. Muy pocas aplicaciones de iPhone se compilan directamente en el iPhone. O aplicaciones de Wii. ;-) –

+0

@Richard, sí, pero se usa un "modo" de compilación diferente para compilar las aplicaciones de Iphone con las aplicaciones OS X. Está siendo compilado en una plataforma diferente, pero está específicamente destinado a hacer justamente eso. : D –

+4

@CrazyJugglerDrummer: Mi punto exactamente. La compilación cruzada es una cosa muy común y segura de hacer. –

3

Dependen de la plataforma. Por ejemplo, el comando de archivo imprime lo siguiente:

$ file foo.o 
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped 
5

En la práctica, no. Hay varias cosas que deberían ser las mismas: - Interfaz del sistema operativo (las mismas llamadas al sistema) - diseño de memoria de datos (endianness, relleno estructural, etc.) - convención de llamadas - formato de archivo de objeto (por ejemplo, ELF es bonita estándar en Linux)

Buscar ABI para obtener más información.

4

No hace falta decirlo nuevamente: los archivos de objeto C/C++ no son portátiles.

Por otro lado, ANSI C es uno de los idiomas más portátiles que existen. Es posible que no pueda recoger sus archivos objeto, pero la recompilación de su fuente probablemente funcione si se apega al estándar ANSI C. Esto también podría ser cierto para C++ también.

No sé cuán universal es GNU C++, pero si puede compilar con gcc en una computadora, es bueno que vaya a cualquier otra máquina que también tenga instalado gcc. Casi todas las máquinas en las que se puede pensar tienen un compilador de C. Eso es portabilidad.

+1

¡Java es aún mejor! : p – abc

+5

Derecha ... compilar una vez, ejecutar en cualquier lugar ... lentamente ;-) –

+2

¿Casi todas las máquinas en las que se puede imaginar tienen una VM Java? Nah ... – Frunsi

4

No. No son plataformas independientes. Tomemos, por ejemplo, el compilador GNU C (gcc), que genera archivos binarios ELF. Los compiladores de Windows (Borland, Microsoft, Open Watcom) pueden producir el formato Windows Binary PE (Portable Executable). Los archivos binarios de Novell son NLM (Módulo de Netware Loadabable).

Estos ejemplos anteriores de las diferentes salidas que dependen del compilador, no hay manera, un enlazador en una plataforma Windows, sabría algo sobre formato ELF o formato NLM, por lo tanto es imposible combinar diferentes formatos para producir un ejecutable que se puede ejecutar en cualquier plataforma.

Tome la Mac OSX de Apple (antes de que se pusieran los chips de Intel), se ejecutaban en la plataforma PowerPC, incluso si tiene el compilador GNU C, el binario es específicamente para la plataforma PowerPC, si tuviera que tomar ese binario y lo copia en una plataforma Linux, no se ejecutará como resultado de las diferencias en las instrucciones del microprocesador de la plataforma, es decir, PowerPC.

Nuevamente, el mismo principio se aplicaría al sistema de sistema principal OS/390, un compilador GNU C que produce un binario para esa plataforma no se ejecutará en un Apple Mac OSX anterior a Intel.

Editar: Para aclarar mejor cómo sería un formato ELF, ver más abajo, esto se obtuvo ejecutando objdump -s main.o bajo Linux.

 
main.o:  file format elf32-i386 

Contents of section .text: 
0000 8d4c2404 83e4f0ff 71fc5589 e55183ec .L$.....q.U..Q.. 
0010 14894df4 a1000000 00a30000 0000a100 ..M............. 
0020 000000a3 00000000 8b45f483 38010f8e .........E..8... 
0030 9c000000 8b55f48b 420483c0 048b0083 .....U..B....... 
0040 ec086800 00000050 e8fcffff ff83c410 ..h....P........ 
0050 a3000000 00a10000 000085c0 7520a100 ............u .. 
0060 00000050 6a1f6a01 68040000 00e8fcff ...Pj.j.h....... 
0070 ffff83c4 10c745f8 01000000 eb5a8b45 ......E......Z.E 
0080 f4833802 7e218b55 f48b4204 83c0088b ..8.~!.U..B..... 
0090 0083ec08 68240000 0050e8fc ffffff83 ....h$...P...... 
00a0 c410a300 000000a1 00000000 85c07520 ..............u 
00b0 a1000000 00506a20 6a016828 000000e8 .....Pj j.h(.... 
00c0 fcffffff 83c410c7 45f80100 0000eb08 ........E....... 
00d0 e8fcffff ff8945f8 8b45f88b 4dfcc98d ......E..E..M... 
00e0 61fcc3        a.. 
Contents of section .rodata: 
0000 72000000 4552524f 52202d20 63616e6e r...ERROR - cann 
0010 6f74206f 70656e20 696e7075 74206669 ot open input fi 
0020 6c650a00 77000000 4552524f 52202d20 le..w...ERROR - 
0030 63616e6e 6f74206f 70656e20 6f757470 cannot open outp 
0040 75742066 696c650a 00     ut file.. 
Contents of section .comment: 
0000 00474343 3a202847 4e552920 342e322e .GCC: (GNU) 4.2. 
0010 3400         4. 

Ahora compara eso con un formato PE para un simple DLL

 
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin>dumpbin /summary "C:\Documents and Settings\Tom\My Documents\Visual Studio 2008\Projects\SimpleLib\Release\SimpleLib.dll" 
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 
Copyright (C) Microsoft Corporation. All rights reserved. 


Dump of file C:\Documents and Settings\Tom\My Documents\Visual Studio 2008\Projects\SimpleLib\Release\SimpleLib.dll 

File Type: DLL 

    Summary 

     1000 .data 
     1000 .rdata 
     1000 .reloc 
     1000 .rsrc 
     1000 .text 

notar las diferencias en las secciones, bajo ELF, hay .bss, .text, .rodata y .comment, y es un formato ELF para el procesador i386.

Espero que esto ayude, Saludos cordiales, Tom.

2

C++ tiene el detalle adicional de que los nombres que pone en un archivo de objeto suelen ser 'destrozados' para tratar la seguridad de tipo para los nombres que están sobrecargados. Los métodos utilizados para modificar los nombres no son parte del estándar C++ (de hecho, el cambio de nombre es un detalle de implementación que no se requiere en absoluto si el proveedor puede encontrar una forma diferente de implementar la sobrecarga). Por lo tanto, incluso para el mismo objetivo de plataforma, no puede contar con poder vincular archivos de objeto de un proveedor de compilador a otro.

En ocasiones, un proveedor de compiladores puede cambiar el esquema de creación de nombres de una versión de compilación a otra. Por ejemplo, creo que hay versiones de MSVC para las cuales no puede vincular de manera confiable los archivos de objeto de C++ de una versión anterior a una versión más nueva.

Algunas plataformas tienen el nombre Mangling especificado en un estándar ABI para la plataforma (como ARM que usa el nombre Mangling especificado en el genérico C++ ABI desarrollado originalmente para SVr4 en Itanium), pero otras no (Windows) Incluso para ARM, no estoy seguro de qué tan interoperable es el estándar ABI para vincular archivos de objetos C++ que fueron creados por diferentes compiladores.

+0

MSVC++ 6 no es realmente compatible con MSVC++ 7; no en el nivel ABI y no en el cambio de nombre. Este último evita accidentes. – MSalters

2

Sólo quería decir que el tiempo que utilizan el mismo arquitectura del procesador y formato de objeto, así como la convención de llamada (por lo general hoy en día, el fabricante de procesador crea uno), hay muchas posibilidades de que los ficheros objeto para trabajar indistintamente

Sin embargo, incluso en C, el compilador hace suposiciones sobre ciertas funciones de la biblioteca, como la protección de la pila (que yo sepa), que no tiene por qué ser igual en ambas plataformas. en el caso de que se genere dicho código, los objetos no serán directamente compatibles.

Las llamadas al sistema no son realmente relevantes siempre que los sistemas las compartan como normalmente se llaman a través de C wrappers en las bibliotecas estándar.

Al final esto solo se aplica a C y sistemas operativos muy similares como Linux y BSD, pero puede suceder.

1

Es posible compilar con GCC y crear un archivo de objeto en formato de archivo ELF y convertir el archivo de objeto para trabajar en Visual Studio. Lo he hecho varias veces ahora.

Hay tres cosas que necesita saber para hacer esto: la convención de llamada a función, el formato del archivo de objeto y el nombre de la función de manipulación.

Convenciones de llamada a función: Para el modo de 32 bits, la convención de llamada a función es sencilla: son las mismas para Windows y Unix. Para el modo de 64 bits, Windows y Unix utilizan diferentes convenciones de llamadas. Por lo tanto, en el modo de 64 bits, debe obtener la convención de llamadas correcta. Puede hacer esto cuando compila o desde el archivo de objeto mismo. Es mucho más fácil hacer esto cuando compilas. Para que GCC use la convención de llamadas de Windows, use -mabi=ms. Para hacer esto desde el archivo objeto necesita una herramienta. La herramienta objconv de Agner Fog puede hacer esto para algunas funciones.

Formato de archivo objecto: Para convertir el formato de archivo de objeto, necesita una herramienta. Utilizo la herramienta objconv de Agner Fog para esto. Puede convertir desde varios formatos diferentes de archivos de objetos. Por ejemplo, para convertir ELF64 en COFF64 (PE32 +), haga objconv -fcoff64 foo.o foo.obj.

Nombre de la función mangling: Debido a la sobrecarga de la función en los compiladores de C++ mangle los nombres de las funciones. Los detalles para cada compilador se pueden encontrar en el manual de Agner Fog calling convetions. Los nombres de la función mangle de GCC y Visual Studio son diferentes. Para evitar las definiciones de funciones de proceder con extern "C"

Si obtiene las tres correctas y no realiza ninguna llamada específica del sistema operativo, podrá utilizar correctamente los archivos de objeto entre los compiladores. Hay otros problemas que pueden ocurrir, por supuesto. Consulte el manual en objconv para más detalles. Pero hasta ahora este método me había funcionado bien.

Cuestiones relacionadas