Search code examples
gcclinkerldqnx

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


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?


Solution

  • 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
    $