简体   繁体   English

将静态库链接到共享库?

[英]Link a static lib into a shared lib?

Background: 背景:

I want to link a few static libs into a shared lib. 我想将一些静态库链接到共享库。 The reason is that I want my application to use the specific lib versions that I have tested it with. 原因是我希望我的应用程序使用我测试过的特定lib版本。 I do not want to ship the static versions as shared libraries with my application. 我不想将静态版本作为共享库与我的应用程序一起发布。 I have created this sample lib and application to simplify as much as possible. 我已经创建了这个示例库和应用程序,以尽可能简化。 I would like to continue to link the shared lib to the application during linking. 我想在链接期间继续将共享库链接到应用程序。

Question: 题:

Why do I get the error messages listed below? 为什么我会收到下面列出的错误消息? What am I doing wrong? 我究竟做错了什么? Perhaps this is not the usual way of doing things on linux, but is it possible to do so? 也许这不是通常在linux上做事的方式,但有可能这样做吗? Is this boost specific? 这种提升是否具体?

---- library - - 图书馆

//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. 

---- sample application ----样本申请

//main.cpp
#include <iostream>
void doit();
int main()
{
    std::cout << "main\n";
    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

All source code is located in the same directory. 所有源代码都位于同一目录中。 Boost is installed in /usr/lib and /usr/include. Boost安装在/ usr / lib和/ usr / include中。 Boost, version 1.40, was installed using apt-get on a ubuntu 10.04 machine. Boost,版本1.40,是在ubuntu 10.04机器上使用apt-get安装的。

Thank you! 谢谢!

I think the easiest way for you is to use the --whole-archive linker switch (there are more SO questions on this topic, see one here how to link static library into dynamic library in gcc ). 我认为最简单的方法是使用--whole-archive链接器开关(关于此主题还有更多的SO问题,请参阅此处的一个如何将静态库链接到gcc中的动态库 )。

The downside of that is that your shared library will export all symbols from the Boost static libraries and you might have weird issues if you'll use your .so in an application that also uses Boost (but a different version or compiled with different switches). 这样做的缺点是您的共享库将导出Boost静态库中的所有符号,如果您在使用Boost的应用程序中使用.so (但是使用不同的版本或使用不同的开关编译),您可能会遇到奇怪的问题。

So you need to use a version script to hide what's exported from the library (see How to hide the exported symbols name within a shared library , also google for linker version scripts), leaving only doit() visible. 因此,您需要使用版本脚本来隐藏从库中导出的内容(请参阅如何在共享库中隐藏导出的符号名称 ,也可以使用谷歌搜索链接器版本脚本),只留下doit()可见。 In your case, such a version script could look like: 在您的情况下,这样的版本脚本可能如下所示:

{
global:
    doit*;
local:
    *;
}      

You also need to make sure that the static libraries you're linking with are compiled with -fPIC (which is unlikely, if you didn't tweak their build flags), other wise you'll have a performance penalty on i386 and might not link at all on amd64 . 你还需要确保你链接的静态库是用-fPIC编译的(如果你没有调整它们的构建标志,这是不太可能的),否则你将对i386产生性能损失,可能不会在amd64上链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM