我有一个基本问题,但找不到解决方案。假设我构建了一个由以下头文件和源文件组成的共享库toto
:
toto.h
void print();
toto.cpp
#include <iostream>
#include "toto.h"
void print()
{
std::cout<<"WHAT A GREAT LIBRARY"<<std::endl;
}
基于这些文件,我使用以下命令创建了我的共享库:
g++ -fPIC -shared -I. -c toto.cpp -o libtoto.so
接下来,我想在测试文件中使用我刚刚创建的共享库:
test.cpp
#include "toto.h"
int main()
{
print();
}
为了做到这一点,我使用以下命令将我的可执行文件与共享库链接起来:
g++ -I. -L. -ltoto test.cpp
。然后我得到了a.out
可执行文件。当我运行ldd a.out
时,我会得到以下输出:linux-vdso.so.1 => (0x00007fff322f5000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb7e7c24000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb7e7865000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb7e7568000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb7e7f4d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb7e7352000)
我没有看到我的可执行文件对 toto
共享库有任何依赖。在链接过程中,我的库似乎已经被静态绑定到了我的可执行文件上。这一点得到了证实,因为我可以从任何地方调用 a.out
而无需将 LD_LIBRARY_PATH
设置为存储 libtoto.so
的路径。如果是这样的话,那么我在前面的命令中错过或误解了什么?
顺便说一下,这个例子是在 ubuntu 12.04、g++ 4.6.3 上运行的。
编辑:
与此同时,我发现这段代码生成了一个“正确”的可执行文件,即 ldd
显示它依赖于 libtoto
共享库,并且未设置 LD_LIBRARY_PATH
变量时无法启动可执行文件:
g++ -I ./mydylib/ -fpic -c mydylib/toto.cpp -o mydylib/toto.o
g++ -shared -o mydylib/libtoto.so mydylib/toto.o
g++ -I ./mydylib/ -L ./mydylib/ test.cpp -ltoto -o ldd_correct
虽然这个版本仍然可以生成具有上述功能的“错误”可执行文件:
g++ -I ./mydylib -fpic -shared -c mydylib/toto.cpp -o mydylib/libtoto.so
g++ -I ./mydylib -L ./mydylib test.cpp -ltoto -o ldd_wrong
g++
的参数顺序非常重要。-ltoto
应该放在源文件(例如toto.cpp
)和目标文件之后。 - Basile Starynkevitch./a.out
会打印消息吗?如果删除.so
并重新运行,会发生什么?(对于 Redhat Enterprise Linux Server 5.8,ldd显示了预期的依赖项,这表明可能是对ld
行为的其他更改,可能是在 Michael 提供的链接所做的更改之一)。 - Tony Delroy