all those c++ ABI variations in ports

Don Lewis truckman at FreeBSD.org
Mon Apr 13 10:55:45 UTC 2015


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.



More information about the freebsd-ports mailing list