On Jul 29, 2024, at 09:18, Dimitry Andric <[email protected]> wrote:
> On 29 Jul 2024, at 18:01, Mark Millard <[email protected]> wrote:
>>
>> On Jul 29, 2024, at 07:54, Charlie Li <[email protected]> wrote:
>>> ...
>
>>> While you're talking about std and std.compat, I have a related issue
>>> whilst working on the www/webkit2-gtk update. They have code that relies on
>>> a std::pair implementation/ABI that does not work with our base system
>>> libc++. This is because our base system uses LLVM libc++ ABI version 1, but
>>> the needed implementation is in ABI version 2, which they have still (even
>>> in trunk!) not declared stable.
>>
>> FreeBSD updating its C++ ABI would be a rather major change,
>> or so I would expect. Likely avoided as long as possible?
>>
>> I wonder what property of std::pair's implementation is at
>> issue for the ABI version distinction(s).
>
> It's a bit of a historical wart that is hard to get rid of. In FreeBSD we
> were "too early" and changed our standard C++ library to libc++ before this
> std::pair trivial copy constructor issue was hashed out in the standards
> committees.
Looking, I eventually found ( __config ):
# elif _LIBCPP_ABI_VERSION == 1
. . .
# if defined(__FreeBSD__)
# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
# endif
and ( __utility/pair.h ):
template <class _T1, class _T2>
struct _LIBCPP_TEMPLATE_VIS pair
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
: private __non_trivially_copyable_base<_T1, _T2>
#endif
{
. . .
So this is not a 1 vs. 2 issue: it is a FreeBSD-specific odd definition of 1
that
does not apply to other contexts with _LIBCPP_ABI_VERSION == 1 . I'd not
noticed that in the prior references that I'd run into. (It fits with your
wording
below, sort of "early 1 vs. late 1" to invent terminology.)
> After it was settled in those committees, libc++ changed its implementation
> to match, but this actually breaks the ABI!
Sort of "FreeBSD early libc++ ABI 1" vs. "normal late libc++ ABI 1" ABIs.
> For anybody who switched to libc++ after that time, there was no problem
> using the new ABI, but in FreeBSD we have been stuck with the older
> interpretation ever since.
>
> Changing the ABI involves bumping libc++.so to .2, and putting libc++.so.1
> into a 'compat' package for the sake of old binaries. I had originally wanted
> to do this for FreeBSD 14 but never got to it, and for some reason upstream
> is also stalled for years now in bumping their own official ABI version to 2.
If FreeBSD wants an officially stable libc++ without the forced
__non_trivially_copyable_base<_T1, _T2> then it could:
) have libc++.so use .2 for libc++ _LIBCPP_ABI_VERSION == 1 without
_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR defined
) have the _LIBCPP_ABI_VERSION == 1 with
_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR defined case for
libc++.so.1 put into that 'compat' package for the sake of old binaries
There is no reason to need to deal with _LIBCPP_ABI_VERSION == 2 at all for the
issue at hand.
(Yes, this would mean going forward that for N>= 1, libc++.so.(N+1) would be
for _LIBCPP_ABI_VERSION == N without the FreeBSD oddity.)
> It would be preferable if upstream libc++ bumps its 'stable' ABI to 2 and
> starts working on 3 as the then-experimental one, then all downstream
> consumers can upgrade, leaving all compat crutches behind.
>
How important is having a numerical match for libc++.so.(_LIBCPP_ABI_VERSION)
instead of the +/- 1 shifting between the .so and the _LIBCPP_ABI_VERSION ?
===
Mark Millard
marklmi at yahoo.com