views:

307

answers:

2

How does one combine two GCC compiled .o object files into a third .o file?

$ 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

If you have access to the source files the -combine GCC flag will merge the source files before compilation:

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

However this only works for source files, and GCC does not accept .o files as input for this command.

Normally, linking .o files does not work properly, as you cannot use the output of the linker as input for it. The result is a shared library and is not linked statically into the resulting executable.

$ 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
+2  A: 

If you want to create an archive of two or more .o files (i.e.. a static library) use the ar command:

ar rvs mylib.a file1.o file2.o
anon
Yes there is. I spent a good part of a day searching for a way to do this. I only asked this so I can provide the answer here too so others (or myself) would find it easier.
Lucian Adrian Grijincu
@Lucian But why would you want to do this? A static library is much more convenient to link against than a .o file.
anon
I need to run `objcopy` on the resulting file and make some kinds of symbols local to the file so that they are not visible externally. Some of the symbols that need be localized are referenced between the `a.o` and `b.o` files. I can't localize individual files – as the symbols would not be found at linker time – and I can't localize symbols from the static archive either.
Lucian Adrian Grijincu
+4  A: 

Passing -r (or --relocatable) to ld will create an object that is suitable as input of ld.

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

The generated file is of the same type as the original .o files.

$ 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