强制或阻止使用特定的次要版本的libstdc

为了使用C 11和c 14功能,我有一个使用的编译应用程序
更新版本的 gcc(4.9.1),因此是更新版本的libstdc.该应用程序包含许多
小程序所以我将libstdc作为共享库而不是静态库链接
(即我不想使用-static-libstdc)

我希望使用/ opt // lib64下的应用程序发布新版本的libstdc
(注意:根据GPL的例外,这是特别允许的)

新版本的libstdc .so与目标平台上的版本只有次要版本不同.
libstdc旨在向前兼容,以便现有程序可以使用新版本的库.但是,我观察到一些行为(即错误)的微妙差异
程序使用新版本而不是旧版本.我希望防止这种情况发生.

我还发现ld会尝试将我的应用程序与libstdc的系统版本链接起来,除非
我先把/ opt // lib64放在LD_LIBRARY_PATH上.
据推测,您可以使用-l:< library>.< version>强制链接特定版本,但是,这似乎不起作用.我怀疑它会用于用户创建的库而不是用于
像libstd这样的语言运行库,因为gcc本身会生成链接描述文件.
同样在我的一个目标平台(RHEL5)上,gcc / ld甚至都不了解它.
我认为这可以通过使用-nostdlib并在我的构建系统中链接所需的所有内容(例如-lgcc)
而不是把它留给我更喜欢的gcc.到目前为止我还没试过这个.

解决此问题的一种简单方法是在运行应用程序时确保LD_LIBRARY_PATH包含/ opt // lib64
而不是其他或同样我可以使用LD_PRELOAD与正确的库版本.
如果有人决定忽略我的建议和运行,这个问题

@H_301_24@export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/<vendor>/lib64

它可能会导致细微而难以诊断的问题.所以我一直在寻找更好的方法.

我想知道是否有某种方法可以将libstdc重命名为lib_stdc并链接到该soname.
重命名libstdc是不够的,因为您需要更改readelf给出的文件中的soname.即

@H_301_24@0x000000000000000e (SONAME) Library soname: [libstdc++.so.6]

如果你在gcc链接的普通程序上执行此操作,即使使用-l:stdc .so.6.0.20,你会注意到这一点
给出主要版本而不是特定的次要版本.

@H_301_24@readelf -d <myapp> 0x0000000e (SONAME) Library soname: [libstdc++.so.6]

而不是:

@H_301_24@0x0000000e (SONAME) Library soname: [libstdc++.so.6.0.20]

所以我改为创建了一个虚拟共享库,其中包含我想要依赖的soname,以便添加依赖项,如下所示:

@H_301_24@gcc dummy.o -Wl,-soname,lib<vendor>_stdc++.so.6.0.20 -nostdlib -shared -o lib<vender>_dummycpp.so

(其中dummy.o是一个空的目标文件,由空的源文件制成,用于停止-nostdlib导致投诉)

然后:

@H_301_24@gcc <myapp> -l<vendor>_dummycpp

根据需要,我现在得到:

@H_301_24@readelf -d <myapp> 0x0000000000000001 (NEEDED) Shared library: [lib<vendor>_stdc++.so.6.0.20]

代替

@H_301_24@0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]

dummycpp库包含libstdc中的所有符号,因为它是libstd,因此根本不需要gcc与soname libstdc链接.我似乎完全解决了这个问题.

它让我感到有些狡猾,因此我想问的问题是:

>这是个好主意吗?
>如果不是为什么不呢?
>有更好/更正确的方法吗?

注意:如果在RPM中将libstdc与其他名称(例如lib_stdc .so.6.0.20)打包在一起,则会缺少对它的依赖,需要使用–nodeps进行安装.这是因为RPM扫描链接时间依赖性.解决方法是安装虚拟库.然后RPM将从虚拟库中获取soname而不是声称它丢失了.

解决方法

libstdc FAQ条目 How do I insure that the dynamically linked library will be found链接到手册部分 Finding Dynamic or Shared Libraries,该部分解释了如何使用RPATH.

我首选的方法是使用$ORIGIN的RPATH,这意味着搜索动态库依赖项在与二进制文件相同的目录中开始(参见ld.so(8)).因此,如果您链​​接’-Wl,-rpath,$ORIGIN'(请注意引号以防止shell扩展$ORIGIN),那么您可以在与安装的二进制文件相同的目录中安装共享库,并且当您的二进制运行.或者使用’-Wl,$ORIGIN /../ lib’,如果你想在某个安装前缀下有单独的bin和lib目录.

将库与二进制文件一起安装在ldconfig不扫描的某个自定义路径中,并且没有LD_LIBRARY_PATH弄乱环境,不应该使用该版本的应用程序找不到新的libstdc.

确保还安装了指向libstdc .so.6.0.20文件的libstdc .so.6符号链接,以便libstdc .so.6的DT_NEEDED可以找到该文件.

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...