gcc在静态库中链接未解析符号的顺序是什么? [英] What's the order for gcc to link unresolved symbol in static library

查看:203
本文介绍了gcc在静态库中链接未解析符号的顺序是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当调试函数符号冲突问题时,我发现了一个奇怪的gcc行为,我无法理解,通过以下示例代码说明:

main.c

  #include< stdio.h> 
int main()
{
b();
a();

$ / code>

ac

  #include< stdio.h> 
void a(void)
{
printf(func a in a \\\
);



bc

  #include< stdio.h> 

void a()
{
printf(func a in b\\\
);

void b()
{
printf(func b try to call a \\\
);
a();
}

汇编:

  gcc -c ac 
gcc -c bc
ar -cr liba.a ao
ar -cr libb.a bo
gcc main .c liba.a libb.a

执行:

  ./ a.out 
func b尝试调用
func a中的b
func a中的b

我的问题是:


  • 为什么在 main 函数中调用函数 a a in bc a in ac

  • 更改库命令后: gcc main.c libb.a liba。一个,结果是一样的。为什么?

  • 为什么在这种情况下链接器不报告符号冲突?
  • 解决方案

    解决方案


    $ b在对象文件中按照对象文件的外观顺序从左到右搜索要解析的符号。 $ b

    假设已准备好以下链接:

      gcc -c main.c 
    gcc -c ac
    gcc -c bc
    ar -cr liba.a ao
    ar -cr libb.a bo

    然后这个

      gcc -o main main.o liba.a libb .a 

    会产生:

    <$ p $ (ao):
    bc :(。text + 0x0):多重定义'a'
    liba.a(bo):在函数`a' :ac :(。text + 0x0):首先在这里定义
    collect2:ld返回1退出状态





    main.o 需要 a() b()。首先搜索 liba :找到 a() b()不是。所以其次搜索 libb 。找到 b(),但也会导致链接器错误另一个 a()如上所示。



    如果这样做:

      gcc -o main main main .o libb.a liba.a 

    没有错误, main 被创建。



    链接器执行以下操作:

    main.o 需要 a() b()。先搜索 libb a() b()被发现。由于没有任何东西可以解决,所以甚至没有人去查看/发现 libb liba in。



    在后一种情况下,程序( main )的输出为:

      func b尝试调用
    func a中的b
    func a中的b






    链接器将为/ c显示所有其他可能的排列 main .o liba.a libb.a 留作练习读者。 ;-)


    When debug the function symbols conflicts problem, I find a strange behavior of gcc i couldn't understand, illustrate by the following sample code:

    main.c

    #include <stdio.h>
    int  main()
    {
       b();
       a();
    }
    

    a.c

    #include <stdio.h>
    void  a(void)
    {
       printf("func a in a\n");
    }
    

    b.c

    #include <stdio.h>
    
    void a()
    {
       printf("func a in b\n");
    }
    void b()
    {
      printf( "func b try to call a  \n");
      a();
    }
    

    compile:

    gcc -c a.c
    gcc -c b.c
    ar -cr liba.a a.o
    ar -cr libb.a b.o
    gcc main.c liba.a libb.a
    

    execute:

    ./a.out
    func b try to call a  
    func a in b
    func a in b   
    

    My question is :

    • Why calling function a in main function is a in b.c instead of a in a.c ?
    • After change the library order: gcc main.c libb.a liba.a, the result is the same. Why?
    • Why the linker don't report symbol conflict in this situation?

    解决方案

    Object files are searched for symbols to be resolved in the order of the object files' appearances, left to right, in the options passed to the linker.

    Assumed the following had been run in preparation to linking:

    gcc -c main.c
    gcc -c a.c
    gcc -c b.c
    ar -cr liba.a a.o
    ar -cr libb.a b.o
    

    Then this

    gcc -o main main.o liba.a libb.a
    

    would produce:

    libb.a(b.o): In function `a':
    b.c:(.text+0x0): multiple definition of `a'
    liba.a(a.o):a.c:(.text+0x0): first defined here
    collect2: ld returned 1 exit status
    

    The linker did the following:

    main.o needs a() and b (). First liba is searched: a() is found, b() isn't. So secondly libb is searched. b() is found, but also another a() leading to the linker error shown above.

    If doing:

    gcc -o main main.o libb.a liba.a
    

    No errors are given and main is created.

    The linker did the following:

    main.o needs a() and b (). First libb is searched: a() and b() are is found. As there is nothing to resolve any more libb liba isn't even looked at/in.

    In the latter case the program's (main's) output is:

    func b try to call a  
    func a in b
    func a in b
    


    What the linker would do/show for all other possible permutation of main.o, liba.a and libb.a is left as an exercise to the reader. ;-)

    这篇关于gcc在静态库中链接未解析符号的顺序是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆