3

We have manually installed GCC 6.2.0 on a Scientific Linux machine. The compilation of a C++ application seems fine but we get lots of undefined references to CXX11 at linking time

file.cpp:(.text+0x16cb): undefined reference to `std::__cxx11::list<void*, std::allocator<void*> >::list(std::__cxx11::list<void*, std::allocator<void*> > const&)'

We are aware of the double ABI issue but compiling with -D_GLIBCXX_USE_CXX11_ABI=0 makes no difference. What other options do we have?

UPDATE

The CMAKE configuration is as follow:

-- The C compiler identification is GNU 6.2.0
-- The CXX compiler identification is GNU 6.2.0
-- Check for working C compiler: /opt/GNU/gcc-6.2.0/bin/gcc
-- Check for working C compiler: /opt/GNU/gcc-6.2.0/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /opt/GNU/gcc-6.2.0/bin/g++
-- Check for working CXX compiler: /opt/GNU/gcc-6.2.0/bin/g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done

This is the compilation line of file.cpp

gcc-6.2.0/bin/g++ -O3 -fopenmp -DNO_HDF5 -D_GLIBCXX_USE_CXX11_ABI=0  -I./include -I/opt/mpich/3.2/include  -o file.cpp.o -c file.cpp

and linking (where it actually fails)

gcc-6.2.0/bin/g++ -O3 -fopenmp -DNO_HDF5 -D_GLIBCXX_USE_CXX11_ABI=0     main.cpp.o  -o ASTEP -rdynamic libMainASTEPlib.a -lhdf5_hl -lhdf5 -lz -lm -lhdf5_hl -lhdf5 -lz -lm /opt/mpich/3.2/lib/libmpicxx.so /opt/mpich/3.2/lib/libmpi.so -Wl,-rpath,/opt/mpich/3.2/lib

Also, MPICH 3.2 has been built with the new compiler (gcc 6.2.0)

Manolete
  • 3,431
  • 7
  • 54
  • 92
  • *How* are you linking your program? With `ld`? With `gcc`? With `g++`? – Some programmer dude Dec 08 '16 at 12:03
  • Remove the object file and recompile. – Maxim Egorushkin Dec 08 '16 at 12:06
  • 3
    When installing gcc, gcc prefers to assume, very much, that its libraries are going to get installed into /usr/lib(64)?, irrespective where you're actually shoving gcc into. As such your code ends up getting linked with the system's standard libraries. Unfortunately, I forgot the gory details of how to beat the crap out of gcc's configuration, in order to set it up correctly to link with its libraries where you install them. You'll have to figure it out, like I did ~10 years ago... If I remembered all of that, I'd post an answer. – Sam Varshavchik Dec 08 '16 at 12:06
  • @Someprogrammerdude We create a library and link it with g++ – Manolete Dec 08 '16 at 12:07
  • @MaximEgorushkin Nah, that didn't work... – Manolete Dec 08 '16 at 12:11
  • 1
    That means `file.cpp` is not compiled with `-D_GLIBCXX_USE_CXX11_ABI=0`. Post the compiler and linker command lines as they are issued by your build system. – Maxim Egorushkin Dec 08 '16 at 12:16
  • Did you only install the compiler, or also the package with the new libraries (libstdc++)? My guess is that the new std::__cxx11:: symbols are not found in the old library. – Rene Dec 08 '16 at 12:41
  • @MaximEgorushkin Updated – Manolete Dec 08 '16 at 13:11
  • @Rene We only installed the package gcc-6.2.0.tar.gz following the installation instructions https://gcc.gnu.org/wiki/InstallingGCC – Manolete Dec 08 '16 at 13:13
  • The linker command line does not mention `file.cpp.o`. Is it in an `.a` or `.so` that was not recompiled? – Maxim Egorushkin Dec 08 '16 at 13:24
  • @MaximEgorushkin A library `libMainASTEPlib.a` is created with all source files and then finally linked against the `main.cpp` file. So `file.cpp` is included in `libMainASTEPlib.a` as many other files. – Manolete Dec 08 '16 at 13:29
  • @Manolete Looks like the `.a` did not get rebuilt with the new `file.cpp.o`. – Maxim Egorushkin Dec 08 '16 at 13:32
  • @Manulete Can you reduce this to a simpler case ? Does a simple hello world program utilizing a std::list work/link ? – nos Dec 08 '16 at 14:00
  • @SamVarshavchik "gcc prefers to assume" --- it very much doesn't (just installed gcc to a non-standard place for the N+1th time, it **does not** look in /usr/lib/whatever but in its own installation directory). The *run-time* linking is wrong if you don't specify =Wl,-rpath, but this is a whole different story. – n. m. could be an AI Dec 08 '16 at 14:54
  • I cannot reproduce your issue. Have gcc 6.1.0 installed in a home directory on a very old Linux machine. It does the right thing. __cxx11 symbols correctly appear and disappear according to the value of _GLIBCXX_USE_CXX11_ABI macro. – n. m. could be an AI Dec 08 '16 at 15:07
  • @n.m. One potential problem that I see here is that the application uses `HDF5` which has been installed in the system place where is also located the original and old `libstdc++`. Could this cause a problem? – Manolete Dec 08 '16 at 15:20
  • The pretty much only explanation to your problem is that two different files named file.cpp.o exist in your build. – n. m. could be an AI Dec 08 '16 at 15:49
  • @n.m. Unfortunately it is not the case. I will post an answer whenever I figure it out, but there is definitely something else going on here... – Manolete Dec 08 '16 at 16:13
  • It is rather easy to verify. Compile your file with these flags and then run `nm file.cpp.o | grep cxx11`. See anything? – n. m. could be an AI Dec 08 '16 at 16:40
  • Well, another possibility is that you have a broken or non-standard gcc install. This doesn't happen too often, but I'd rather install gcc from sources and check. – n. m. could be an AI Dec 08 '16 at 16:57
  • 1
    @n.m. -- that's exactly what I meant. It's not unreasonable to expect that when I install GCC AND libstdc++ in some dir, I just link my code normally, everything works without arcane link options. Freebsd packages GCC correctly, multiple gccNN commands, each one links with its libstdc++ and supplies the rpath for runtime. – Sam Varshavchik Dec 08 '16 at 17:30

1 Answers1

1

I don't understand why your object still has references to std::__cxx11::list when you have compiled with -D_GLIBCXX_USE_CXX11ABI=0, unless the macro is then being redefined in a header/source file. You should make certain the file.o object is correctly being placed into whatever archive is supposed to contain it (and that any old version is definitely gone). With that said:

You may need to link against the libstdc++ library that comes with gcc 6.2.0, not with the system version of that library which seemingly corresponds to an earlier compiler.

This may require using -nostdlib and then manually adding -L/(path)/gcc-6.2.0/lib -lstdc++ -lc or similar.

Alternatively, you may be able to compile using the system C++ headers rather than the gcc 6.2.0 headers. Then you should also be able to successfully link against the system libstdc++ library. In that case you want -nostdinc++ and then -I/usr/include/c++/5 (for example). Note that in this case, -D_GLIBCXX_USE_CXX11_ABI=0 will have no effect and is unnecessary; the old library does not have the dual ABI.

davmac
  • 20,150
  • 1
  • 40
  • 68
  • 2
    `gcc` searches for `libstdc++` in its own installation rather than in the system place (I install gcc to non-standard places all the time). – n. m. could be an AI Dec 08 '16 at 14:49
  • @n.m. It is clearly not doing so in this case, however. – davmac Dec 08 '16 at 16:16
  • The fact is, gcc does so by default. In this case we have some indirect observations of some unknown phenomena at hand. It is a long road from here to clearly established anything. Until a verbose build log us posted at the very least. – n. m. could be an AI Dec 08 '16 at 16:36
  • @n.m. my personal knowledge/experience leads me to the conclusion that, if the symbol mentioned in the error is not found by the linker, that the appropriate version of libstdc++.so.6 is not being linked. Either the wrong version of that library is preceding it or it is being omitted altogether. I'd rather suggest a solution that might help in either case than just ponder countless other somewhat less likely possibilities. – davmac Dec 08 '16 at 16:48
  • It looks like a wrong library *and* a wrong object are being linked. Your theory doesn't explain that. Some other problem must be present. – n. m. could be an AI Dec 09 '16 at 07:05
  • @n.m. "wrong object are being linked" - as per first paragraph in my answer. – davmac Dec 09 '16 at 10:02
  • With -D_GLIBCXX_USE_CXX11ABI=0 the cxx11 symbols should not show up in the object at all. This happens before any linking is done, so how the standard library was compiled is irrelevant (even if we assume it was intentionally compiled with no C++03 support --- it is impossible to do that by accident). – n. m. could be an AI Dec 09 '16 at 10:07
  • @n.m If you build the library without dual ABI support, then `-D_GLIBCXX_USE_CXX11ABI=0` should have no effect and you will get either cxx11 symbols exclusively or non-cxx11 symbols exclusively depending on configure time options. This is because the contents of the library header files are affected. (actually, I don't know this for certain. But it is certainly possibly to build libstdc++ without dual ABI support, and with support for either the old or new ABI only). – davmac Dec 09 '16 at 10:11
  • @n.m. in any case, I already made it very clear in the answer that OP should ensure that the correct object file is being linked. I don't understand why are you are constantly trying to detract from my answer. Downvote it if you feel it's factually wrong, or better yet write your own. I've tried to give the most helpful answer possible given the limited information provided by OP. – davmac Dec 09 '16 at 10:16
  • In fact I don't see any way to configure gcc or the standard library without dual ABI support. There is a way to change the default, but not to disable C++03 completely. – n. m. could be an AI Dec 09 '16 at 10:22
  • @n.m. `--disable-libstdcxx-dual-abi` when configuring libstdc++. – davmac Dec 09 '16 at 10:23
  • This disables the C++11 abi, not the C++03 abi. – n. m. could be an AI Dec 09 '16 at 10:24
  • @nm. I thought `--disable-libstdcxx-dual-abi --with-default-libstdcxx-abi=new` built a library with only the new ABI, but that appears not to be the case. I've edited the answer. Thanks. – davmac Dec 09 '16 at 10:38