将可执行文件链接到共享库

时间:2015-02-16 11:17:41

标签: c++ linker g++

我有一个基本问题,我无法找到解决方案。 假设我构建了一个由以下头文件和源文件组成的共享库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

上运行

编辑:

我可以在此期间找到这个代码产生一个正确的&#34; 可执行文件,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

虽然这个仍然产生错误&#34;具有上述特征的可执行文件:

g++ -I ./mydylib -fpic -shared -c mydylib/toto.cpp -o mydylib/libtoto.so
g++ -I ./mydylib -L ./mydylib test.cpp -ltoto -o ldd_wrong

2 个答案:

答案 0 :(得分:1)

我的猜测是因为它是一个如此简单的库,它被优化了。更复杂的库是否还会发生?你试过传递-O0旗帜了吗?

我已经尝试但我无法重现结果 - 我的ldd节目

linux-vdso.so.1 =>  (0x00007fffb79fe000)
libtoto.so (0x00007f8a78316000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8a77f2e000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8a77c2a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8a7851a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8a77924000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8a7770d000)

在Ubuntu 14.04 gcc version 4.8.2上

但是,正如我所料,g++ -I. -L. -ltoto test.cpp无效 - 我必须改为运行g++ -I. -L. test.cpp -ltoto

答案 1 :(得分:0)

我终于找到了问题的原因:

在单个GCC步骤中编译和链接我的共享库时,我为我的toto.cpp源文件添加了错误的-c标志。通过比较以下三种构建模式,这似乎打破了可执行文件的构建:

为共享库构建两个GCC步骤

g++ -I. -fpic -c toto.cpp -o toto.o
g++ -shared -o libtoto.so toto.o
g++ -I. -L. test.cpp -ltoto -o ldd_correct

用于构建共享库的单个GCC步骤

g++ -I. -fpic -shared -o libtoto.so toto.cpp
g++ -I. -L. test.cpp -ltoto -o ldd_also_correct

用于构建共享库的单个GCC步骤 - &gt; -c打破了什么

g++ -I. -fpic -shared -o libtoto.so -c toto.cpp
g++ -I. -L. test.cpp -ltoto -o ldd_wrong