将静态库链接到共享库
Link a static lib into a shared lib?
背景:
我想把一些静态库链接到一个共享库中。原因是我希望我的应用程序使用我测试过的特定lib版本。我不想将静态版本作为共享库与我的应用程序一起发布。我创建了这个示例库和应用程序以尽可能简化。我希望在链接期间继续将共享库链接到应用程序。
问题:
为什么我会收到下面列出的错误消息?我做错了什么?也许这不是linux上通常的操作方式,但有可能做到吗?这种助推是特定的吗?
----库
//example.cpp
#include <boost/thread.hpp>
void doit()
{
boost::thread t1;
}
#build script
g++ -Wall -fPIC -I/usr/include -c example.cpp -o example.o
g++ -shared /usr/lib/libboost_thread.a /usr/lib/libboost_system.a
example.o -o libexample.so
#build OK.
----样品应用
//main.cpp
#include <iostream>
void doit();
int main()
{
std::cout << "mainn";
doit();
return 0;
};
#build script.
g++ -Wall -c main.cpp -o main.o
g++ libexample.so main.o -o main
#error message.
libexample.so: undefined reference to `boost::thread::thread()'
libexample.so: undefined reference to `boost::thread::~thread()'
collect2: ld returned 1 exit status
所有源代码都位于同一目录中。Boost安装在/usr/lib和/usr/include中。Boost,版本1.40,是使用apt-get在ubuntu 1004机器上安装的。
谢谢!
我认为最简单的方法是使用--whole-archive
链接器开关(关于这个主题还有更多SO问题,请参阅这里的一个问题,如何在gcc中将静态库链接到动态库)。
这样做的缺点是,您的共享库将从Boost静态库导出所有符号,如果您在同样使用Boost的应用程序中使用.so
(但版本不同或使用不同的开关编译),您可能会遇到奇怪的问题。
因此,您需要使用版本脚本来隐藏从库中导出的内容(请参阅如何在共享库中隐藏导出的符号名称,也可以在谷歌上搜索链接器版本脚本),只显示doit()
。在您的情况下,这样的版本脚本可能看起来像:
{
global:
doit*;
local:
*;
}
您还需要确保链接的静态库是用-fPIC
编译的(如果您不调整它们的构建标志,这是不可能的),否则您将在i386
上受到性能损失,并且可能根本无法在amd64
上链接。
相关文章:
- 无法在Ubuntu上将共享库与Eclipse链接
- CMake - 更改共享库链接选项
- 与共享库链接时未定义的引用
- 如何在 Linux 中构建共享库时使未定义引用的链接器失败
- 共享对象、符号、C/C++ 库链接和加载
- 如果同时存在共享库和动态库,则链接器将首选哪个库?
- 如何防止 CMake 在构建时(而不是在安装时)为共享库创建符号链接?
- c++ 链接器错误"针对'.rodata.str1.1'的重新定位R_X86_64_32"链接 CXX 共享库 libsrt.so
- 停止共享库链接丢弃未使用的类
- 链接二进制库或共享库时,为什么必须传入我依赖的共享库?
- 使用共享库编译可执行文件时仅链接所需的符号
- C++ 为什么要级联共享对象链接
- 与 32 位共享对象的链接问题
- 使用 pybind11 构建库,链接其他共享库
- 运行程序时找不到共享对象库,但在编译过程中链接了它
- 链接共享库依赖项未在 ldd 中列出
- 将共享对象与静态库链接
- CMake:修改共享库时的冗余链接
- 与MinGW的静态和动态/共享链接
- Qt-多个QtableWidget可以共享链接的项目