代码之家  ›  专栏  ›  技术社区  ›  ptomato

便利库中的符号无法在可执行文件中导出

  •  6
  • ptomato  · 技术社区  · 14 年前

    我有个计划, myprogram ,它与一个静态便利库相链接,称之为 libconvenience.a ,它包含一个函数, func() . 功能 函数() 在任何地方都没有 我的计划 ;它需要能够从插件库调用, plugin.so .

    符号 函数() 无法在中动态导出 我的计划 . 如果我跑

    nm myprogram | grep func
    

    我什么也得不到。然而,它并没有从 利布福斯特.a :

    nm libconvenience/libconvenience.a | grep func
    00000000吨func

    我正在使用automake,但是如果我在命令行上手动执行最后一步链接,它也不起作用:

    gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries`
    

    但是,如果我像这样链接程序,则跳过使用便利库并链接本应进入的对象文件 利布福斯特.a 直接, 函数() 出现在 我的计划 的符号:

    gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries`
    

    如果我给 函数() 在某处 我的计划 ,然后 函数() 也出现在 我的计划 的符号。但我觉得 --export-dynamic 应该导出所有符号,不管它们是否在程序中使用!

    我在Fedora14上使用Automake1.11.1和GCC4.5.1。我也在使用Libtool 2.2.10来构建 插件.so (但不是便利图书馆。)

    我没有忘记 -Wl,--export-dynamic 在里面 myprogram_LDFLAGS ,我也没有忘记将包含 函数() 在里面 libconvenience_a_SOURCES (一些google显示这些是导致这个问题的常见原因。)

    有人能帮我弄明白这是怎么回事吗?

    2 回复  |  直到 14 年前
        1
  •  4
  •   ptomato    14 年前

    我设法解决了。正是约翰·卡尔科特(John Calcote)优秀的自动工具书中的这张便条,指引了我正确的方向:

    链接器将命令行中显式指定的每个对象文件添加到二进制产品中,但它们仅从存档中提取在链接的代码中实际引用的那些对象文件。

    为了抵消这种行为,可以使用 --whole-archive 标记为libtool。但是,这会导致所有系统库中的所有符号也被拉入,从而导致许多双符号定义错误。所以 --整个档案 必须在之前 libconvenience.a 在链接器命令行中,它需要后跟 --no-whole-archive 这样其他库就不会被那样对待了。这有点困难,因为automake和libtool并不能保证在命令行上保持标记的顺序不变,但是 Makefile.am 做了个诡计:

    myprogram_LDFLAGS = -Wl,--export-dynamic \
        -Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive
    
        2
  •  0
  •   ldav1s    14 年前

    如果你需要func在plugin.so中,如果可能的话,你应该尝试在那里找到它。便利库就是这样——作为中间步骤链接到可执行文件或lib的便利。