我正在使用英特尔的C ++编译器,它在Linux上依赖于GNU提供的libc.so和libstdc ++。所以。
这是我的问题。要访问一些最新的C ++ 11功能,我需要使用随GCC 4.7或更高版本提供的libstdc ++。但是我坚持使用CentOS 6.4。
在CentOS 6.4上,GCC的原生版本是4.4。但是使用名为“SCL”的RedHat和名为“devtoolset-1.1”的软件包,我可以在“/ opt”下安装GCC 4.7。
我按照上面提到的方式设置了GCC 4.7,我可以使用更新的C ++ 11功能。
所以这是我的问题:如果用户只使用GCC 4.4版本的libc.so / libstdc ++来运行我的程序,那么在库路径中,由于4.4之间的某些不匹配,我的程序是否存在错误风险和这些库的4.7版本?
如果存在潜在问题,我可以通过静态链接GCC 4.7的libc和libstdc ++版本来解决这个问题吗?或者,如果/当我的代码动态加载的其他库获取系统范围的GCC 4.4包提供的旧的libc / libstdc ++时,是否为其他问题做好准备?
答案 0 :(得分:22)
正如Praetorian在下面的评论中指出的那样,使用devtoolset实际上解决了我最初在这个答案中描述的问题。我已经纠正了答案。
由于这些库的4.4和4.7版本之间存在一些不匹配,我的程序是否存在错误?
是。链接到较新的libstdc ++。所以然后尝试运行和更旧的一个是100%不支持。如果你的程序中的任何对象或它使用的任何库都使用GCC 4.7 编译并链接到libstdc ++。那么从4.7 那么你需要在运行时从4.7(或更新版本)使用libstdc ++。它可能甚至不会运行,但如果它确实存在,则由于不兼容性可能会出现无声错误。但这不是你的问题,因为你没有链接到GCC 4.7的libstdc ++。所以,见下文。
我可以通过静态链接GCC 4.7的libc和libstdc ++版本来解决它吗?
1)你只需要为libstdc ++做到这一点,因为没有“GCC 4.7版本的libc”这样的东西。 Glibc是一个与GCC完全独立的项目。当您使用GCC 4.7时,您没有使用不同的libc,您仍在使用CentOS 6.4中的系统libc。 (顺便说一句,请注意glibc维护者强烈建议静态链接glibc,并且静态链接时glibc的某些功能不起作用。)
2)静态链接libstdc ++可以解决问题,但你不需要,因为这就是Red Hat Developer Toolset(devtoolset)无论如何都会为你做的事情。 devtoolset的重点在于它允许您使用较新的GCC和较新的libstdc ++,但不会在较新的libstdc ++库上创建任何运行时依赖项。编译后的可执行文件只需要libstdc ++的系统版本。因此,即使没有安装devtoolset的系统,它也始终存在于RHEL / CentOS上。 (devtoolset所做的是将所有新的libstdc ++特性打包在静态库中,称为libstdc++_nonshared.a
,以便系统libstdc ++中不存在所有部分。所以静态链接,其他所有内容都来自系统libstdc ++。左右)。
如果您没有使用devtoolset,那么另一个选项而不是静态链接libstdc ++将是发布更新的libstdc ++。所以使用您的代码并确保首先找到它(例如通过将代码链接到引用更新的RPATH)的libstdc ++。如此)。但是使用devtoolset并不是必需的。
或者,当我的代码动态加载的其他库获取系统范围的GCC 4.4软件包提供的旧的libc / libstdc ++时,是否正在设置其他问题?
使用devtoolset时不会出现这样的问题,因为你总是使用较旧的libstdc ++,因此永远不会发生冲突。