不同GCC版本在链接/运行时的风险是什么?

23
我在使用英特尔的C++编译器,在Linux上依赖于GNU提供的libc.so和libstdc++.so。
我的问题是:为了使用一些最新的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++.so,是否存在因为这些库的4.4版本与4.7版本之间不匹配而导致我的程序出现错误的风险?
如果存在潜在问题,我是否可以通过静态连接GCC 4.7的libc和libstdc++来解决?或者,如果/当我的代码动态加载其他库并获取系统范围内的GCC 4.4包提供的较旧的libc/libstdc++时,是否会遇到其他问题?
1个回答

28

如Praetorian在下面的评论中指出的那样,使用devtoolset实际上解决了我在这个答案中最初描述的问题。我已经更正了答案。

我的程序会不会因为4.4和4.7版本库之间存在某些不匹配而出现bug的风险?

是的。链接到较新的libstdc++.so并尝试针对旧版本运行是100%不支持的。如果您程序中的任何对象或使用的任何库是使用GCC 4.7编译并链接到4.7版本的libstdc++.so,则需要在运行时使用4.7(或更新)版本的libstdc++.so。它可能甚至无法运行,但如果运行,则可能由于不兼容性而导致静默错误。但在您的情况下,这不是一个问题,因为您并没有链接到GCC 4.7的libstdc++.so,请见下文。

我可以通过静态链接GCC 4.7版本的libc和libstdc++来解决这个问题吗?

1)您只需要为libstdc++做到这一点,因为不存在“GCC 4.7版本的libc”。Glibc是与GCC完全分离的项目。当您正在使用GCC 4.7时,您仍在使用来自CentOS 6.4的系统libc。(顺便说一下,静态链接glibc是强烈建议反对的,而且在静态链接时某些glibc功能将无法使用。)

2) 静态链接libstdc++可以解决这个问题,但您不需要这样做,因为这就是Red Hat开发工具集(devtoolset)为您完成的工作。整个devtoolset的重点在于它允许您使用更新的GCC和更新的libstdc++,但又不会创建任何运行时依赖项于更新的libstdc++库。编译后的可执行文件只需要system版本的libstdc++.so,在RHEL/CentOS上始终存在,即使没有安装devtoolset的系统也一样。(devtoolset所做的是将所有新的libstdc++功能打包到静态库中,称为libstdc++_nonshared.a,以便所有不在system libstdc++.so中的部分都静态链接,而其他所有内容都来自system libstdc++.so)。

如果您没有使用devtoolset,则除了静态链接libstdc++之外,另一个选择是随代码一起提供较新的libstdc++.so,并确保它被首先找到(例如,通过链接带有对较新的libstdc++.so的RPATH的代码)。但是使用devtoolset就不需要这样做。

或者,如果/当我的代码动态加载的其他库拾取由系统范围GCC 4.4软件包提供的旧libc/libstdc++,那么这是否会为我带来其他问题?

使用devtoolset时不会出现此类问题,因为您始终在使用旧版本的libstdc++,因此永远不会发生冲突。


谢谢Jonathan。我开始对英特尔决定让他们的C++编译器使用Gnu的libstdc++.so感到非常恼火。 - Christian Convey
谢谢Jonathan。我开始对英特尔决定让他们的C++编译器使用Gnu的libstdc++.so感到非常恼火。这使得在旧版Linux(CentOS 6.4)上使用它变得非常困难,而不会遇到严重的“DLL”地狱问题。 - Christian Convey
CentOS 6.4已经发布两周左右了,你遇到的问题是企业版发行版使用的“稳定”软件包集,而不是发行版的年龄。英特尔的替代方案将是开发他们自己的整个stdlib(一个巨大的任务),然后用ICC编译的代码将与使用GCC构建的任何系统库不兼容...这将更加令人烦恼。 - Jonathan Wakely
3
Jon,我在试图回答与原帖相同的问题时发现了这个。唯一的区别是我正在使用devtoolset-3。当然,你的答案一般来说是正确的,但对于devtoolset来说不是。这个PDF的第26页解释了devtoolset在一个静态库中提供了所有新的libstdc++和libgcc功能。因此,您的应用程序在运行时仍将链接到系统默认版本。这里是我的新的libstdc++.so包含的内容。我错过了什么吗?(抄送@ChristianConvey) - Praetorian
2
更新了那个PDF文件的链接,其中包含第26页(由Praetorian提到):http://kr.redhat.com/summit/2012/pdf/2012-DevDay-How-To-Toolset-Newsome.pdf - jfritz42
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接