【问题标题】:When Linking: use -l flag or just treat archives as input链接时:使用 -l 标志或仅将档案视为输入
【发布时间】:2011-04-01 03:10:19
【问题描述】:

我在将静态库 stxxl 链接到共享库时遇到了一些问题,如我的问题 Linking a static library into Boost Python (shared library) - Import Error 中所述

我使用的命令是

g++ -Wall -pthread -march=i686 -I/home/zenna/Downloads/stxxl-1.3.0/include -include stxxl/bits/defines.h -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -I /home/zenna/local/include/ -I /usr/include/python2.6/ -fPIC -c partition.cpp -o obj/Partition_wrap.o

并链接:

g++  -shared -lboost_python -L/home/zenna/local/lib/ -L/home/zenna/Downloads/stxxl-1.3.0/lib/bk/ -Wall -pthread -L/home/zenna/Downloads/stxxl-1.3.0/lib -lstxxl -o lib/fast_parts.so obj/Partition_wrap.o 

使用 nm 我发现丢失的符号在最终输出的共享对象库中,但类型为“U”表示未定义。

然后我将链接命令更改为不仅使用 -lstxxl,而且还将整个存档文件作为另一个输入添加到链接器

使得新命令是(末尾不同)

++ -shared -lboost_python -L/home/zenna/local/lib/ -L/home/zenna/Downloads/stxxl-1.3.0/lib/bk/ -Wall -pthread -L/home/zenna/下载/stxxl-1.3.0/lib -lstxxl -o lib/fast_parts.so obj/Partition_wrap.o obj/libstxxl.a

据我所知,这解决了问题。

然后我的问题是使用 -l 标志和添加存档作为输入有什么区别?为什么以前的方法会导致未定义的符号?

【问题讨论】:

    标签: linker compilation shared-libraries


    【解决方案1】:

    我认为您的问题是您在目标文件之前指定了 -lstxxl。当您将libstxxl.a 放在末尾时,将再次读取其中的符号并解析未定义的符号。您可以尝试在obj/Partition_wrap.o 之前移动它并检查它是否会导致未定义的符号。

    来自man ld

    ld -o /lib/crt0.o hello.o -lc

    这告诉 ld 生成一个名为 output 的文件,作为将文件 "/lib/crt0.o" 与 "hello.o" 和库 "libc.a" 链接的结果, 它将来自标准搜索目录。 (请参阅下面对 -l 选项的讨论。)

    ld 的某些命令行选项可以在命令行中的任何位置指定。但是,引用文件的选项,例如 作为 -l 或 -T,导致在选项出现在命令行中的点读取文件,相对于目标文件和 其他文件选项。

    非选项参数是要链接在一起的目标文件或档案。它们可能跟随、先于或混合在一起 命令行选项,但对象文件参数不能放在选项和它的参数之间。

    -l 名称规范

    链接器只会在命令行中指定的位置搜索存档一次。如果档案定义了一个 在命令行存档之前出现的某些对象中未定义的符号,链接器将包括 档案中的适当文件。但是,稍后在命令行中出现的对象中的未定义符号不会导致 再次搜索存档的链接器。

    虽然没有说得很清楚,但给链接器链接文件的两种方式似乎没有任何区别。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 2018-03-25
      相关资源
      最近更新 更多