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

时间:2022-09-04 02:38:57

I'm using Intel's C++ compiler, which on Linux relies on the GNU-supplied libc.so and libstdc++.so.

我正在使用Intel的c++编译器,它在Linux上依赖于gnu提供的libc。所以和libstdc + + . so。

Here's my problem. To have access to some of the newest C++11 features, I need to use the libstdc++ which ships with GCC 4.7 or higher. But I'm stuck using CentOS 6.4.

这是我的问题。要访问一些最新的c++特性,我需要使用libstdc+,它附带的GCC 4.7或更高版本。但我用的是CentOS 4。4。

On CentOS 6.4, the native version of GCC is 4.4. But using a RedHat thing called "SCL" and a package named "devtoolset-1.1", I'm able to get GCC 4.7 installed under "/opt".

在CentOS 6.4上,GCC的本地版本是4.4。但是使用一个名为“SCL”的RedHat程序和一个名为“devtoolset-1.1”的包,我可以在“/opt”下安装GCC 4.7。

I set things up to be using GCC 4.7 in the manner mentioned above, I can use the newer C++11 features.

我按照上面提到的方式将事情设置为使用GCC 4.7,我可以使用较新的c++ 11特性。

So here's my question: If a user runs my program with only the GCC 4.4 versions of libc.so / libstdc++.so in the library path, is there a risk that my program will have bugs due to some mismatch between the 4.4 and 4.7 versions of those libraries?

我的问题是:如果用户只使用GCC 4.4版本的libc运行我的程序。所以/ libstdc + +。那么在库路径中,我的程序会不会因为4.4和4.7版本库之间的不匹配而出现错误呢?

If there is a potential problem, can I work around it by statically linking in GCC 4.7's versions of libc and libstdc++? Or is that setting myself up for other problems if/when other libraries that my code dynamically loads pick up the older libc / libstdc++ supplied by the system-wide GCC 4.4 package?

如果有潜在的问题,我可以通过在GCC 4.7版本的libc和libstdc++中静态链接来解决吗?或者,如果我的代码动态加载的其他库使用系统范围内的GCC 4.4包提供的旧的libc / libstdc++ +,那么这是否为我自己设置了其他问题?

1 个解决方案

#1


17  

As Praetorian pointed out in the comments below, the use of devtoolset actually solves the problem I originally described in this answer. I've corrected the answer.

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

is there a risk that my program will have bugs due to some mismatch between the 4.4 and 4.7 versions of those libraries?

由于这些库的4.4和4.7版本之间的不匹配,我的程序是否有可能出现bug ?

Yes. Linking against a newer libstdc++.so and then trying to run against and older one is 100% not supported. If any object in your program or any libraries it uses is compiled with GCC 4.7 and linked to the libstdc++.so from 4.7 then you need to use the libstdc++.so from 4.7 (or newer) at runtime. It probably won't even run, but if it does there may be silent bugs due to incompatibilities. But that's not a problem in your case, because you're not linking to GCC 4.7's libstdc++.so, see below.

是的。链接到更新的libstdc++。然后试着运行和旧的是100%不支持的。如果您的程序或它使用的任何库中的任何对象使用GCC 4.7编译并链接到libstdc++ +。从4。7开始,你需要使用libstdc++。从运行时的4.7(或更新)开始。它甚至可能不会运行,但是如果运行的话,可能会因为不兼容而出现无声的bug。但这在您的例子中不是问题,因为您没有链接到GCC 4.7的libstdc++。所以,见下文。

can I work around it by statically linking in GCC 4.7's versions of libc and libstdc++?

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

1) You would only need to do that for libstdc++, because there is no such thing as "GCC 4.7's version of libc". Glibc is a completely separate project from GCC. When you are using GCC 4.7 you're not using a different libc, you're still using the system libc from CentOS 6.4. (As an aside, be aware that statically linking glibc is strongly advised against by the glibc maintainers, and some features of glibc will not work when statically linked.)

1)您只需要在libstdc++中这样做,因为不存在“GCC 4.7版本的libc”。Glibc是一个与GCC完全独立的项目。当您使用GCC 4.7时,您没有使用不同的libc,您仍然使用CentOS 6.4中的系统libc。(顺便说一句,请注意,glibc的维护人员强烈建议不要使用静态链接glibc,并且当静态链接时,glibc的一些特性将不起作用。)

2) Statically linking libstdc++ would work around the problem, but you don't need to, because that's what the Red Hat Developer Toolset (devtoolset) does for you anyway. The whole point of devtoolset is that it allows you to use a newer GCC and newer libstdc++ but without creating any run-time dependencies on the newer libstdc++ library. The compiled executables only need the system version of libstdc++.so that is always present on RHEL/CentOS, even systems without devtoolset installed. (What devtoolset does is package all the new libstdc++ features in a static library, called libstdc++_nonshared.a so that all the pieces not present in the system libstdc++.so get statically linked in, and everything else will come from the system libstdc++.so).

静态地链接libstdc++可以解决这个问题,但是您不需要,因为这是Red Hat Developer工具集(devtoolset)为您做的事情。devtoolset的整个要点是,它允许您使用新的GCC和更新的libstdc++,但不需要在更新的libstdc++库中创建任何运行时依赖项。编译后的可执行文件只需要libstdc++的系统版本。所以这总是出现在RHEL/CentOS上,甚至是没有安装devtoolset的系统。(devtoolset所做的是将静态库中的所有新libstdc++ +特性打包,称为libstdc++_nonshared。这样就不会出现在系统libstdc++中。所以要静态链接,其他的一切都将来自系统libstdc+ so)。

If you weren't using devtoolset then another option instead of statically linking libstdc++ would be to ship the newer libstdc++.so with your code and ensure it is found first (e.g. by linking your code with an RPATH that refers to the newer libstdc++.so). But with devtoolset that's not necessary.

如果您没有使用devtoolset,那么另一个替代静态链接libstdc++ +的选项将是发送更新的libstdc++ +。因此,使用您的代码并确保首先找到它(例如,通过将您的代码链接到引用较新的libstdc+ so的RPATH)。但是对于devtoolset来说,这是不必要的。

Or is that setting myself up for other problems if/when other libraries that my code dynamically loads pick up the older libc / libstdc++ supplied by the system-wide GCC 4.4 package?

或者,如果我的代码动态加载的其他库使用系统范围内的GCC 4.4包提供的旧的libc / libstdc++ +,那么这是否为我自己设置了其他问题?

There will be no such problems when using devtoolset, because you're always using the older libstdc++, and so there is never a conflict.

使用devtoolset时不会出现这样的问题,因为您总是使用旧的libstdc++,因此不会出现冲突。

#1


17  

As Praetorian pointed out in the comments below, the use of devtoolset actually solves the problem I originally described in this answer. I've corrected the answer.

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

is there a risk that my program will have bugs due to some mismatch between the 4.4 and 4.7 versions of those libraries?

由于这些库的4.4和4.7版本之间的不匹配,我的程序是否有可能出现bug ?

Yes. Linking against a newer libstdc++.so and then trying to run against and older one is 100% not supported. If any object in your program or any libraries it uses is compiled with GCC 4.7 and linked to the libstdc++.so from 4.7 then you need to use the libstdc++.so from 4.7 (or newer) at runtime. It probably won't even run, but if it does there may be silent bugs due to incompatibilities. But that's not a problem in your case, because you're not linking to GCC 4.7's libstdc++.so, see below.

是的。链接到更新的libstdc++。然后试着运行和旧的是100%不支持的。如果您的程序或它使用的任何库中的任何对象使用GCC 4.7编译并链接到libstdc++ +。从4。7开始,你需要使用libstdc++。从运行时的4.7(或更新)开始。它甚至可能不会运行,但是如果运行的话,可能会因为不兼容而出现无声的bug。但这在您的例子中不是问题,因为您没有链接到GCC 4.7的libstdc++。所以,见下文。

can I work around it by statically linking in GCC 4.7's versions of libc and libstdc++?

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

1) You would only need to do that for libstdc++, because there is no such thing as "GCC 4.7's version of libc". Glibc is a completely separate project from GCC. When you are using GCC 4.7 you're not using a different libc, you're still using the system libc from CentOS 6.4. (As an aside, be aware that statically linking glibc is strongly advised against by the glibc maintainers, and some features of glibc will not work when statically linked.)

1)您只需要在libstdc++中这样做,因为不存在“GCC 4.7版本的libc”。Glibc是一个与GCC完全独立的项目。当您使用GCC 4.7时,您没有使用不同的libc,您仍然使用CentOS 6.4中的系统libc。(顺便说一句,请注意,glibc的维护人员强烈建议不要使用静态链接glibc,并且当静态链接时,glibc的一些特性将不起作用。)

2) Statically linking libstdc++ would work around the problem, but you don't need to, because that's what the Red Hat Developer Toolset (devtoolset) does for you anyway. The whole point of devtoolset is that it allows you to use a newer GCC and newer libstdc++ but without creating any run-time dependencies on the newer libstdc++ library. The compiled executables only need the system version of libstdc++.so that is always present on RHEL/CentOS, even systems without devtoolset installed. (What devtoolset does is package all the new libstdc++ features in a static library, called libstdc++_nonshared.a so that all the pieces not present in the system libstdc++.so get statically linked in, and everything else will come from the system libstdc++.so).

静态地链接libstdc++可以解决这个问题,但是您不需要,因为这是Red Hat Developer工具集(devtoolset)为您做的事情。devtoolset的整个要点是,它允许您使用新的GCC和更新的libstdc++,但不需要在更新的libstdc++库中创建任何运行时依赖项。编译后的可执行文件只需要libstdc++的系统版本。所以这总是出现在RHEL/CentOS上,甚至是没有安装devtoolset的系统。(devtoolset所做的是将静态库中的所有新libstdc++ +特性打包,称为libstdc++_nonshared。这样就不会出现在系统libstdc++中。所以要静态链接,其他的一切都将来自系统libstdc+ so)。

If you weren't using devtoolset then another option instead of statically linking libstdc++ would be to ship the newer libstdc++.so with your code and ensure it is found first (e.g. by linking your code with an RPATH that refers to the newer libstdc++.so). But with devtoolset that's not necessary.

如果您没有使用devtoolset,那么另一个替代静态链接libstdc++ +的选项将是发送更新的libstdc++ +。因此,使用您的代码并确保首先找到它(例如,通过将您的代码链接到引用较新的libstdc+ so的RPATH)。但是对于devtoolset来说,这是不必要的。

Or is that setting myself up for other problems if/when other libraries that my code dynamically loads pick up the older libc / libstdc++ supplied by the system-wide GCC 4.4 package?

或者,如果我的代码动态加载的其他库使用系统范围内的GCC 4.4包提供的旧的libc / libstdc++ +,那么这是否为我自己设置了其他问题?

There will be no such problems when using devtoolset, because you're always using the older libstdc++, and so there is never a conflict.

使用devtoolset时不会出现这样的问题,因为您总是使用旧的libstdc++,因此不会出现冲突。