将静态库链接到共享库? [英] Link a static lib into a shared lib?

查看:124
本文介绍了将静态库链接到共享库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:

我想将几个静态库链接到一个共享库中。原因是我希望我的应用程序使用我测试过的特定lib版本。我不想将静态版本作为共享库发布到我的应用程序中。我已经创建了这个样本库和应用程序以尽可能简化。我想在链接期间继续将共享库链接到应用程序。



问题:

为什么我收到下面列出的错误消息?我究竟做错了什么?也许这不是在Linux上做事的常用方式,但是可以这样做吗?这是提升具体吗?



----图书馆

  / /example.cpp 
#include< boost / thread.hpp>
void doit()
{
boost :: thread t1;
}

#build脚本
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确定。

----示例应用程序

  // main.cpp 
#include< iostream>
void doit();
int main()
{
std :: cout<< main\\\
;
doit();
返回0;
};

#build脚本。
g ++ -Wall -c main.cpp -o main.o
g ++ libexample.so main.o -o main

#error消息。
libexample.so:对`boost :: thread :: thread()'的未定义引用
libexample.so:对`boost :: thread ::〜thread()'的未定义引用
collect2 :ld返回1退出状态

所有源代码位于同一目录中。 Boost安装在/ usr / lib和/ usr / include中。 Boost,版本1.40,是在Ubuntu 10.04机器上使用apt-get安装的。



谢谢!

解决方案

我认为最简单的方法是使用 - 整个存档链接器开关(有关此主题的更多SO问题,请参阅这里如何将静态库链接到动态库在这种情况下,你的共享库将会从Boost静态库中导出所有的符号,并且你可能会遇到奇怪的问题,在一个也使用Boost的应用程序中使用 .so (但使用不同的版本或用不同的开关编译)。



<因此,您需要使用版本脚本来隐藏从库中导出的内容(请参阅
如何隐藏t他在一个共享库中导出了符号名称,而且链接器版本脚本也是google),只剩下 doit()可见。在你的情况下,这样的版本脚本可能如下所示:

  {
global:
doit *;
local:
*;
}

您还需要确保链接的静态库是用 -fPIC 编译(如果你不调整它们的构建标志,这是不太可能的),否则你将会在 i386 并且可能根本不链接 amd64


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. 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? 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, version 1.40, was installed using apt-get on a ubuntu 10.04 machine.

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

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

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

这篇关于将静态库链接到共享库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆