我有一个使用许多共享库的程序。我可以在用于编译程序的机器上编译和运行程序。当我尝试将可执行文件复制到另一台机器并在通过apt-get安装所需的软件包后运行它时,我收到以下错误:
“加载共享库时出错:libconfig ++。so.8:无法打开共享对象文件:没有这样的文件或目录”
运行$ locate libconfig++.so
后,我了解到我在当前系统上安装了libconfig ++。so.9而不是libconfig.so.8。
然后我手动将所有共享库与可执行文件一起复制到新系统,然后程序运行正常。我不认为这将是一个长期的解决方案,因为图书馆不会收到他们通常会得到的补丁和更新,从而产生潜在的安全风险。
有没有什么方法可以编译我的程序,以便它依赖于libconfig ++。所以与libconfig ++。so.x相反或者是否有某种方法让我手动包含特定的共享库,同时仍然可以更新它们?
我还考虑过这样一个事实,即我正在以我分发程序的方式做错事。有没有办法以一种完全避免的方式分发我的程序?
答案 0 :(得分:3)
当您使用-lsomelibrary编译程序时,编译器将在您的系统中搜索libsomelibrary.so,它将链接到类似libsomelibrary.so.xy的东西。从现在开始,您的软件与该特定的相关联主要版本(名称中的x)。
这意味着它只适用于x系列库。如果发行版发布的版本与主版本相同(例如libsomelibrary.x.z),则应用程序应该可以正常工作。
但是,您不允许使用该库的其他主要版本。如果您这样做(通过将主要版本链接到不同的版本),就像有人在这里建议的那样,应用程序可能会启动(或者可能在开始时崩溃),但您永远不会确定应用程序是否会按计划运行。 / p>
<强> TL'DR:强>
编译时,链接器会查找libsomelibrary.so,它将链接到特定版本,如libsomelibrary.so.x.y。
当您运行应用程序时,系统将查找libsomelibrary.so.x。*(相同的主要版本,任何次要版本)
有关此问题的详细信息,请参阅http://www.ibm.com/developerworks/linux/library/l-shlibs/index.html
答案 1 :(得分:1)
回答上一段中的问题:分发二进制文件(特别是依赖于共享对象的文件)的标准方法是使用目标分发包管理系统(dpkg,rpm或两者)。这些包格式将要求系统安装依赖项(在您的情况下为libconfig ++)。如果没有,用户可以使用apt / yum自动下载和安装它们。
答案 2 :(得分:-1)
验证你的makefile是否要求加载版本9共享库。
它取决于程序调用的函数的用法。
假设你在8-9版本的库之间调用w.r.t函数没有重大改变,你就不需要复制lib了。
当然创造象征性的想要。
如果你认为,你的程序不应该依赖所有这些东西。
去静态库,你可以找到libconfig.a存档,你可以链接你的程序,因此当你运行其他机器时没有依赖。