[PATCH v2] libstdc++: Fix build for AVR [PR115481, PR111639]

Detlef Vollmann dv@vollmann.ch
Tue Jun 18 12:56:07 GMT 2024


On 6/14/24 19:59, Jonathan Wakely wrote:
> On Fri, 14 Jun 2024 at 18:45, Xi Ruoyao wrote:
>>
>> On Fri, 2024-06-14 at 19:37 +0200, Detlef Vollmann wrote:
>>> diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
>>> index 5645e991af7..17dbae7bd87 100755
>>> --- a/libstdc++-v3/configure
>>> +++ b/libstdc++-v3/configure
>>> @@ -5080,7 +5080,7 @@ else
>>>       We can't simply define LARGE_OFF_T to be 9223372036854775807,
>>>       since some C++ compilers masquerading as C compilers
>>>       incorrectly reject 9223372036854775807.  */
>>> -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
>>> +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
>>>     int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
>>>                       && LARGE_OFF_T % 2147483647 == 1)
>>>                      ? 1 : -1];
>>
>> This shouldn't happen.  Please regenerate using *vanilla* autoconf-2.69.
> 
> Yes, please, if possible. But I can regenerate it locally before
> pushing if needed.

This version of the patch doesn't have the problem (this was the
easy part :-)

However, my tests show that this is only a partial solution.
But I believe the patch is correct, and it solves the build
problems for libstdc++ for AVR target.

However, at least for avr-libc 2.0.0 (the version that has the
*f functions as macros) it's not a complete patch:
std::sinf etc, and std::sinl etc are not provided
(::sinf and ::sinl are not provided either).
std::sin exists and has overloads for float, double and lon double.

And calling std::sin(float) only works if the call is inlined,
otherwise I get a linker error
".text._ZSt3sinf[_ZSt3sinf]+0x10): undefined reference to `sinf'".

I don't get a similar error for sinl when calling std::sin(long double).
I didn't have time to dig into the build of libstdc++ to find out
what the difference is.

For avr-libc 2.1.0 (that provides real *f functions but no *l)
I still get the error that std::sinl is not provided but none
of the other problems.

For avr-libc 2.2.0 (that provides real *f and *l functions) I don't
get any of the problems above.

But for all three avr-libc versions I get the problem that the
C++ sin(long double) returns a different value than the C sinl
(which is just another linker name for sin):
I don't really know about floating point representations, but
it looks like the C version fills the mantissa for a long double
return with 0, while the C++ version has bits there.
Looking at the implementation in math_stubs_long_double.cc,
which only calls the double version and promotes the return
to long double this looks strange.
But probably libstdc++ is compiled with different flags than
my test program.
And if I convert the long double result back to double I get
the same value as for C, so it's not really wrong, but it's
irritating...

So again, I think my patch helps, but is not a complete solution.

   Detlef
-------------- next part --------------
A non-text attachment was scrubbed...
Name: avr-math.patch
Type: text/x-patch
Size: 59877 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20240618/6133b5c4/attachment-0001.bin>


More information about the Libstdc++ mailing list