combinar dos archivos de objeto .o compilados por GCC en un tercer archivo .o

84

¿Cómo se combinan dos archivos de objeto .o compilados por GCC en un tercer archivo .o?

$ gcc -c  a.c -o a.o
$ gcc -c  b.c -o b.o
$ ??? a.o b.o -o c.o
$ gcc c.o other.o -o executable

Si tiene acceso a los archivos fuente, la -combinebandera GCC fusionará los archivos fuente antes de la compilación:

$ gcc -c -combine a.c b.c -o c.o

Sin embargo, esto solo funciona para archivos fuente y GCC no acepta .oarchivos como entrada para este comando.

Normalmente, vincular .oarchivos no funciona correctamente, ya que no puede utilizar la salida del vinculador como entrada para él. El resultado es una biblioteca compartida y no está vinculada estáticamente al ejecutable resultante.

$ gcc -shared a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable
./executable: error while loading shared libraries: c.o: cannot open shared object file: No such file or directory
$ file c.o
c.o: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Lucian Adrian Grijincu
fuente
1
gcc actualmente no tiene una -combineopción. Existe en gcc 4.1.2 y no existe en gcc 6.3.0 (alguien más puede averiguar cuándo se eliminó).
Keith Thompson

Respuestas:

98

Pasar -relocatableo -rpara ldcreará un objeto que es adecuado como entrada de ld.

$ ld -relocatable a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable

El archivo generado es del mismo tipo que los .oarchivos originales .

$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
$ file c.o
c.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Lucian Adrian Grijincu
fuente
2
¿Es posible hacer la operación inversa? es decir, producir ao y bo a partir de co?
Bert Regelink
7
@BertRegelink no, porque no hay un inverso único, en términos matemáticos, no forma un grupo: P
Alec Teal
7
Advertencia: --relocatableparece ser menos portátil. El ld que viene con Android NDK solo reconoce -relocatable. Si necesita portabilidad, apéguese -r.
Martin Bonner apoya a Monica el
3
@matthijs La palabra es la misma; la diferencia es uno menos o dos.
Martin Bonner apoya a Monica
1
Ah, no vi eso. Entonces, el NDK de Android solo reconoce -relocatable y -r , pero no --relocatable. ¡Gracias por aclararlo!
Matthijs Kooijman
10

Si desea crear un archivo de dos o más archivos .o (es decir, una biblioteca estática) use el arcomando:

ar rvs mylib.a file1.o file2.o

fuente
@Lucian Pero, ¿por qué querrías hacer esto? Es mucho más conveniente vincular una biblioteca estática que un archivo .o.
5
Necesito ejecutar objcopyen el archivo resultante y hacer algunos tipos de símbolos locales al archivo para que no sean visibles externamente. Algunos de los símbolos que necesitan ser localizados están referenciados entre los archivos a.oy b.o. No puedo localizar archivos individuales, ya que los símbolos no se encontrarían en el momento del enlazador, y tampoco puedo localizar símbolos del archivo estático.
Lucian Adrian Grijincu