combine two GCC compiled .o object files into a third .o file
compiler-construction, gcc, ld, linker, object-files
Solution
Passing `-relocatable` or `-r` to `ld` will create an object that is suitable as input of `ld`.
$ ld -relocatable 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
For an in-depth explanation see MaskRay's Relocatable linking article.
Problem
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 ```