How to get around "multiple defined symbols" in linking with gcc
Asked Answered
V

1

5

I am using an older system that has gcc 2.95.3, I have to link in two objects that although they have nothing to do with each other, they each have similarly named methods. I can't rename either of them, but I would hope there is a way to build them as to not have the linker complain. The methods it is complaining about are each internally called by classes within the object. What can I do?

Viperish answered 14/7, 2010 at 16:25 Comment(0)
S
9

If you have a complete GNU toolchain, you should be able to work around your problem using objcopy, like this (if I've understood your problem correctly):

Here are two very similar objects, "foo" and "bar", both of which export a symbol called clash - which is used internally, but doesn't really need to be exported at all:

$ cat foo.c
#include <stdio.h>
void clash(char *s) { printf("foo: %s\n", s); }
void foo(char *s) { clash(s); }
$ 

and

$ cat bar.c
#include <stdio.h>
void clash(char *s) { printf("bar: %s\n", s); }
void bar(char *s) { clash(s); }
$ 

And here's the main code, which wants to use both:

$ cat main.c
extern void foo(char *s);
extern void bar(char *s);

int main(void)
{
    foo("Hello");
    bar("world");
    return 0;
}
$ 

Linking them together doesn't work:

$ gcc -Wall -c foo.c  
$ gcc -Wall -c bar.c
$ gcc -Wall -c main.c
$ gcc -o test main.o foo.o bar.o
bar.o: In function `clash':
bar.c:(.text+0x0): multiple definition of `clash'
foo.o:foo.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status
$ 

So, use objcopy to change the visibility of clash in one (or both, if you like!) of the objects:

$ objcopy --localize-symbol=clash bar.o bar2.o
$ 

Now you can link successfully with the modified object - and the program behaves as it should:

$ gcc -o test main.o foo.o bar2.o
$ ./test
foo: Hello
bar: world
$ 
Stylographic answered 14/7, 2010 at 23:11 Comment(2)
How can I specify local before it gets to object form? In the code ideally, but also maybe as part of object compile?Viperish
If the clashing function is only used within a single file, it doesn't need to be exported at all, so making it static should work. This would work with my trivial example above. (I assumed you couldn't change the original source, and needed to work with the objects instead, when you said you couldn't rename things.) If you do need those symbols exported for references between objects at an earlier linking stage (e,g, linking a partial object or a library), then things would be more difficult, and sorting it out would depend on the finer details of the build process.Stylographic

© 2022 - 2024 — McMap. All rights reserved.