链接时:使用-l标志或仅将存档视为输入

时间:2010-08-19 13:17:52

标签: linker compilation shared-libraries

我在将静态库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标志和添加存档作为输入有什么区别?为什么以前的方法导致未定义的符号?

1 个答案:

答案 0 :(得分: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的某些命令行选项。但是,引用文件的选项,例如          as -l或-T,导致在相对于目标文件和命令行中选项出现的位置读取文件          其他文件选项。

     

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

     

-l namespec

     

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

虽然没有提到很清楚,但是给链接器链接文件的两种方式之间似乎没有任何区别。