【问题标题】:How to get around "multiple defined symbols" in linking with gcc如何在与 gcc 的链接中绕过“多个定义的符号”
【发布时间】:2010-07-14 16:25:04
【问题描述】:

我使用的是具有 gcc 2.95.3 的旧系统,我必须链接两个对象,尽管它们彼此无关,但它们每个都有类似命名的方法。我不能重命名它们中的任何一个,但我希望有一种方法可以构建它们,以免链接器抱怨。它所抱怨的方法都是由对象中的类在内部调用的。我能做什么?

【问题讨论】:

    标签: gcc linker ld qnx


    【解决方案1】:

    如果你有一个完整的 GNU 工具链,你应该能够使用 objcopy 解决你的问题,就像这样(如果我正确理解你的问题的话):

    这里有两个非常相似的对象,“foo”和“bar”,它们都导出了一个名为clash的符号——它在内部使用,但根本不需要导出:

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

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

    这是主要的代码,它想同时使用两者:

    $ cat main.c
    extern void foo(char *s);
    extern void bar(char *s);
    
    int main(void)
    {
        foo("Hello");
        bar("world");
        return 0;
    }
    $ 
    

    将它们链接在一起不起作用:

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

    因此,使用objcopy 更改clash 在一个(或两者,如果您愿意!)对象中的可见性:

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

    现在您可以与修改后的对象成功链接 - 程序的行为应如此:

    $ gcc -o test main.o foo.o bar2.o
    $ ./test
    foo: Hello
    bar: world
    $ 
    

    【讨论】:

    • 我怎样才能在它进入对象形式之前指定本地?理想情况下在代码中,但也可能作为对象编译的一部分?
    • 如果冲突函数只在单个文件中使用,则根本不需要导出,所以将其设置为static 应该可以。这适用于我上面的简单示例。 (当您说您不能重命名事物时,我假设您无法更改原始来源,而是需要使用对象。)如果您确实需要导出这些符号以用于对象之间的引用在较早的链接阶段(例如,链接部分对象或库),事情会变得更加困难,而将其分类将取决于构建过程的更精细细节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2021-11-18
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多