Date: Mon, 13 Apr 2015 03:55:34 -0700 (PDT) From: Don Lewis <truckman@FreeBSD.org> To: ports@FreeBSD.org Cc: gnome@FreeBSD.org, kwm@FreeBSD.org Subject: all those c++ ABI variations in ports Message-ID: <201504131055.t3DAtZUb004681@gw.catspoiler.org>
next in thread | raw e-mail | index | archive | help
A common problem lately has been triggered the conversion of www/webkit-gtk* to USES=compiler:c++11-lib. On FreeBSD 8 and 9, that triggers the use of gcc 4.8 from ports and its bundled libstdc++. A lot of ports have also needed to also make this change even though they don't use c++11. Without this change, they fail build due to link errors because they link in libstdc++ from base, which doesn't support the new libstdc++ ABI that gcc48 expects. I've been trying to get x11-fm/sushi to build and run on FreeBSD 8.4 (and also 9.3). Since it links to webkit-gtk3, I tried changing to USES=compiler:c++11-lib. That didn't fix the problem and only changed the error message. I'm guessing the latter was do to using a newer binutils from ports instead of the ancient one in base. I was finally able to make the build succeed by adding -lstdc++ to LDFLAGS. This turns out to be totally bogus since sushi appears to be totally written in C and shouldn't need to link to libstdc++ at all. It does link to a number of C++ libraries, but presumably uses their C interfaces. Some of those libraries are built with gcc from base, which were linked to the base libstdc++, and others were built with gcc 4.8 and linked to its bundled libstdc++. When sushi is linked, the version of libstdc++ that gets linked into the application by rtld probably just depends on the ordering of the libraries that request it. Even after I got sushi to build, when I ran it, it seemed to go through some initialization and then died with a SIGSEGV. My suspicion was that the cause was mixing c++ ABIs in one application. I don't think that gcc claims to support mixing gcc major versions within one C++ application because its C++ ABI has changed over time. The libstdc++ library does using symbol versioning to try to be backwards compatible, but what happens if the same object is manipulated by two different versions of the ABI? For more of the gory details: see <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=196078> I found that there were three libraries used by sushi that were expecting the base version of libstdc++: libgjs (lang/gjs), libmozjs (lang/spidermonkey24), and libgraphite2.so (graphics/graphite2). Since the stack trace was deeply nested under a bunch of function calls in libgjs and libmozjs, I changed those first. They were configured as USES=compiler:c11, which seems pretty bogus since they are c++ libraries and maybe c++0x would be more appropriate. Then I noticed that the logic in Uses/compiler.mk was causing them to be built with with clang from ports and linked to the base libstdc++. I never even knew that was possible! But then, I see that's what the base version of clang in FreeBSD 9.3 does. After changing them to USES=compiler:c++11-lib to force the using of gcc48 and its libstdc++, I was able to run sushi and not experience any core dumps. I am not able to verify that it actually works correctly because gnome-shell is still broken, but it's looking promising. After changing graphics/graphite2 to USES=compiler:c++11-lib, I was able to revert my changes to sushi and build it with base gcc once again without any linker errors. Unfortunately, this really seems to be a game of whack-a-mole, because changing things to fix one port is likely to break others. It also seems to be wrong to start sprinkling USES=compiler:c++11-lib all over the place. Unfortunately that is currently the only way to force linking to the newer version of libstdc++ to be compatible with other C++11 ports. Defaulting FAVORITE_COMPILER to gcc would help a lot, especially on FreeBSD 8. I think we have to bring in a compiler from ports for pretty much any compiler:whatever, so bringing in gcc 48 and getting the new libstdc++ would seem to be better than bringing in clang and using the base libstdc++. FreeBSD 9 is more problematical because the base version of clang satisfies the requirements for most of the the compiler settings, but unfortunately it uses the base libstdc++. Defaulting FAVORITE_COMPILER to gcc would seem to be the best bet for 9. Things look better for 10 and newer. For the platforms with clang in base, it can be used everywhere, and the only problem is likely to be with C++ ports that USE_GCC=yes. Platforms without clang are in the same boat as FreeBSD 8. This isn't painless by any means. Some of the ports that switch from building with clang to gcc will probably be found to ignore LDFLAGS, which is needed to specify the rpath for the ports gcc libstdc++. Also some ports will probably need USES=compiler additions. I still don't have an answer as to why building lang/gjs and lang/spidermonkey24 with clang causes sushi to core dump, but debugging that is very low on my priority list.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504131055.t3DAtZUb004681>