How can I deploy a C++11 program (with dependencies) on CentOS 6, whose GCC is C++03?

蓝咒 提交于 2019-11-30 04:52:12
dhaumann

Actually, you can distribute a program compiled with a newer g++ compiler on a vanilla CentOS 6 platform. There are several ways to do this: The easiest is to use the DevToolset 3, which will give you g++ 4.9.2 (the dev toolset 2 will give you gcc 4.8.2). Then, just compile your application with this g++. When distributing your software, you need to make sure to also ship the libstdc++.so that is being shipped with g++ 4.9. Either set the LD_LIBRARY_PATH so it gets picked up on startup, or set the RPATH to tell your executable where to look first for libraries.

Essentially, you can do this also with newer compilers, but then you first need to compile the compiler itself. If you don't want to compile a compiler first, go with a respective dev toolset and you should be fine.

Yes, you can also try to statically link libstdc++.a. Search for the option -static-libstdc++:

When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.

But if you statically link, you will not get any security updates etc. Granted, you will not get the updates, if you ship libstdc++.so on your own as well, but incremental updates maybe easier.

And with respect to running your application: The rule of thumb is: Compile on the oldest platform you need to support, then your binaries (with self-shipped libstdc++ and other required libs) will likely work also on newer versions. That is, if you compile on CentoOS 6, and it works, then you can expect it to also work on CentOS 7. On a related subject, this is exactly the reason why for instance AppImage and related solutions recommend to build on an old system.

There is a wonderful page on this matter: https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

In short, C++11 in gcc is mostly ABI compatible with c++98, but there are a couple of mismatches. Page above lists all of those.

To alleviate the issue I can suggest following approach:

  • Clearly identify all your dependencies which are C++ libraries. You usually do not have too many of them - boost comes to mind first, do you have anything else?
  • Than you check if the symbols your app needs are in the list of broken ABI (see above). If they are not, you are in the clear.
  • If they are, you recompile the lib, and either distribute it as shared lib together with your app (playing with Rpath flags to make sure your app loads your version) or link statically against it.

Just in case, you might as well link statically against libstdc++.

user1503944

In my company we use gcc 5.1.0, compiled and used on CentOS 5.5 (with old gcc on-board).

When we deploy our application we also redistribute libstdc++.so and libgcc_s.so, compiled from gcc 5.1.0 sources.

For example:

/opt/ourapp/lib/libstdc++.so
/opt/ourapp/lib/libgcc_s.so
/opt/ourapp/bin/myapp

And for starting the binary correctly we execute:

LD_LIBRARY_PATH=/opt/ourapp/lib/ myapp.

Hope it helps.

Drawbacks: At least you can't use native gdb on such an environment because DWARF format incompatibilities.

If you build your C++11 program with the define _GLIBCXX_USE_CXX11_ABI=0 (see this) and the option --abi-version=2 (see this) you should be compatible with any library build with GCC 4.3, including libstdc++.

The default ABI version was 2 through 4.9, it seems like a safe assumption that CentOS uses the default ABI.

The _GLIBCXX_USE_CXX11_ABI macro will affect the standard library's types, to use the same layout as the pre C++11 version. This will introduce some C++11 conformance issues (the reason why they were changed in the first place), things like the complexity of std::list<>::size().

The --abi-version= command line option affects the compiler's ABI, calling conventions, name mangling etc. The default ABI was 2 from 3.4 through 4.9.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!