combine two GCC compiled .o object files into a third .o file
Asked Answered
R

2

99

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
Refurbish answered 5/6, 2010 at 11:17 Comment(1)
gcc does not currently have a -combine option. It exists in gcc 4.1.2 and does not exist in gcc 6.3.0 (someone else can figure out just when it was removed).Selfness
R
115

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.

Refurbish answered 5/6, 2010 at 11:26 Comment(8)
Is it possible to do the inverse operation? i.e. produce a.o and b.o from c.o?Detrition
@BertRegelink no, because there's no unique inverse, In maths terms, doesn't forma group :PAllotment
Warning: --relocatable seems to be less portable. The ld that comes with Android NDK only recognizes -relocatable. If you need portability, stick to -r.Novitiate
@Martin, your comment seems to contradict itself. I presume you mean Android NDK does not recognize --relocatable?Pentimento
@matthijs The word is the same; the difference is one minus or two.Novitiate
Ah, didn't see that. So, the Android NDK only recognizes -relocatable and -r, but not --relocatable. Thanks for clarifying!Pentimento
There's side effect of using ld to combine multiple .o files. If a.o has some weak functions which happen to be defined in b.o , these weak functions will become strong functions in the final c.o. And this may beat some purpose.Liger
@BertRegelink You can combine 3 and 4 and figure out that their sum is 7, but if you take 7 and want to figure out what their summands are, they could be 3 and 4, or they could be something like 2 and 5.Tropous
R
10

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
Recognition answered 5/6, 2010 at 11:19 Comment(1)
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.Refurbish

© 2022 - 2024 — McMap. All rights reserved.