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

Linker 链接时:使用-l标志或仅将存档作为输入,linker,compilation,shared-libraries,Linker,Compilation,Shared Libraries,我在将静态库stxxl链接到一个共享库时遇到了一些问题,如我的问题中所述 我使用的命令是 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 /u

我在将静态库stxxl链接到一个共享库时遇到了一些问题,如我的问题中所述

我使用的命令是

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”表示未定义

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

这样,新命令将被删除(末尾的差异)

++-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\u parts.so obj/Partition\u wrap.o obj/libstxxl.a

据我所知,这解决了问题


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

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

manld

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

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

ld的某些命令行选项可以在命令行中的任意点指定。但是,引用文件的选项,例如 作为-l或-T,使文件在命令行中选项出现的点处相对于对象文件和 其他文件选项。

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

-l名称规范

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

虽然没有很清楚地提到这一点,但这两种给链接器提供要链接的文件的方法似乎没有任何区别