I have come across a slightly unexpected behaviour of the linking process and I would like to ask for clarification.
It seems that linking against an object file and against a static library containing the same set of symbols is not equivalent. The former results in multiple definition
error whereas the latter appears to link correctly.
Minimal example
File a.c
and b.c
are the same:
void myfunc() {
}
File c.c
is the "main":
void myfunc();
int main()
{
myfunc();
return -1;
}
The compile-link workflow goes as follows:
$ gcc -c a.c b.c c.c
$ gcc c.o a.o b.o # Breaks!
a.o: In function `myfunc':
a.c:(.text+0x0): multiple definition of `myfunc'
b.o:b.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
$ ar rvs libb.a b.o
$ gcc c.o a.o -L./ -lb # Works fine?
My question here is: why is the second linking allowed and the first is not if the symbols contained in the object and the static library are the same?
Also, is this behaviour compiler or system specific?
Extension
This is potentially a separate question, but maybe useful to put it here. The problem of multiple references re-emerges with a static library if an additional function is defined in b.c
file e.g. for b.c containing
void myfunc() {
}
void anotherfunc() {
}
And now the linking step breaks with the same error as before:
gcc b.c
gcc -L./ c.o -lb a.o
a.o: In function `myfunc':
a.c:(.text+0x0): multiple definition of `myfunc'
.//libb.a(b.o):b.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit stat