Bug 281540

Summary: devel/sfml: fix build with libc++ 19
Product: Ports & Packages Reporter: Dimitry Andric <dim>
Component: Individual Port(s)Assignee: Dmitry Marakasov <amdmi3>
Status: Closed Not Accepted    
Severity: Affects Some People CC: agh
Priority: --- Flags: bugzilla: maintainer-feedback? (amdmi3)
Version: Latest   
Hardware: Any   
OS: Any   
Bug Depends on:    
Bug Blocks: 280562    
Attachments:
Description Flags
devel/sfml: fix build with libc++ 19 none

Description Dimitry Andric freebsd_committer freebsd_triage 2024-09-16 18:00:10 UTC
As noted in the libc++ 19 release notes [1], std::char_traits<> is now
only provided for char, char8_t, char16_t, char32_t and wchar_t, and any
instantiation for other types will fail.

This causes devel/sfml to fail to compile with clang 19 and libc++ 19,
resulting in errors similar to:

  /usr/include/c++/v1/string:820:42: error: implicit instantiation of undefined template 'std::char_traits<unsigned int>'
    820 |   static_assert(is_same<_CharT, typename traits_type::char_type>::value,
        |                                          ^
  /wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/include/SFML/System/String.hpp:52:18: note: in instantiation of template class 'std::basic_string<unsigned int>' requested here
     52 |     typedef std::basic_string<Uint32>::iterator       Iterator;      //!< Iterator type
        |                  ^
  /usr/include/c++/v1/__fwd/string.h:23:29: note: template is declared here
     23 | struct _LIBCPP_TEMPLATE_VIS char_traits;
        |                             ^

SFML makes heavy use of the no-longer-existing basic_string variants, so
I had to add a rudimentary set of char_traits classes, for unsigned
char, unsigned short and unsigned int, otherwise this would not compile.

[1] https://libcxx.llvm.org/ReleaseNotes/19.html#deprecations-and-removals
Comment 1 Dimitry Andric freebsd_committer freebsd_triage 2024-09-16 18:01:34 UTC
Created attachment 253608 [details]
devel/sfml: fix build with libc++ 19
Comment 2 Dmitry Marakasov freebsd_committer freebsd_triage 2024-09-23 16:08:50 UTC
Adding stuff which is not template specialization to namespace std is UB: https://en.cppreference.com/w/cpp/language/extending_std, no?

Was this reported upstream? Is there an easy way to reproduce the build problem?
Comment 3 Dimitry Andric freebsd_committer freebsd_triage 2024-09-23 16:31:34 UTC
(In reply to Dmitry Marakasov from comment #2)
In this particular case it is allowed, see https://en.cppreference.com/w/cpp/string/char_traits:

> The char_traits class template serves as a basis for explicit instantiations. The user can provide a specialization for any custom character types. Several explicit specializations are provided for the standard character types (see below), other specializations are not required to satisfy the requirements of CharTraits. 

I haven't reported any of this upstream, as they seem to rely a great deal on std::basic_string with a bunch of non-standard types.

The easiest way to reproduce is to compile the port against a world built from https://github.com/DimitryAndric/freebsd-src/tree/llvm-19-update, but otherwise with libc++ 18 from -CURRENT, you should already get some warnings about the char_traits templates other than the standard ones being depecrated, so I think you can turn on -Werror to get it to error on them.
Comment 4 Dmitry Marakasov freebsd_committer freebsd_triage 2024-09-24 14:38:33 UTC
Is there a way to reproduce without rebuilding world, e.g. with llvm from ports? Can it be reproduced on linux? In which FreeBSD version will libc++ 19 appear? If that's 15 I'd prefer marking sfml as BROKEN on 15 for now and letting upstream handle it.
Comment 5 Dimitry Andric freebsd_committer freebsd_triage 2024-09-24 15:25:25 UTC
(In reply to Dmitry Marakasov from comment #4)
Add a line:

CXXFLAGS+=     -Werror

to the port Makefile, and build on recent -CURRENT (I tried the 20240919 snapshot), you should get:

FAILED: src/SFML/System/CMakeFiles/sfml-system.dir/String.cpp.o
/usr/bin/c++ -DSFML_SYSTEM_EXPORTS -I/wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/include -I/wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/src -O2 -pipe -fstack-protector-strong -fno-strict-aliasing  -Werror -O2 -pipe -fstack-protector-strong -fno-strict-aliasing  -Werror  -DNDEBUG -fPIC -fvisibility=hidden  -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wcast-align -Wunused -Woverloaded-virtual -Wconversion -Wsign-conversion -Wdouble-promotion -Wformat=2 -Wnull-dereference -Wold-style-cast -Wpedantic -Wno-unknown-warning-option -MD -MT src/SFML/System/CMakeFiles/sfml-system.dir/String.cpp.o -MF src/SFML/System/CMakeFiles/sfml-system.dir/String.cpp.o.d -o src/SFML/System/CMakeFiles/sfml-system.dir/String.cpp.o -c /wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/src/SFML/System/String.cpp
In file included from /wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/src/SFML/System/String.cpp:28:
In file included from /wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/include/SFML/System/String.hpp:32:
In file included from /wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/include/SFML/System/Utf.hpp:32:
In file included from /usr/include/c++/v1/algorithm:1810:
In file included from /usr/include/c++/v1/__algorithm/for_each.h:16:
In file included from /usr/include/c++/v1/__ranges/movable_box.h:23:
In file included from /usr/include/c++/v1/optional:1293:
In file included from /usr/include/c++/v1/iterator:683:
In file included from /usr/include/c++/v1/__iterator/common_iterator.h:31:
In file included from /usr/include/c++/v1/variant:253:
In file included from /usr/include/c++/v1/tuple:1456:
In file included from /usr/include/c++/v1/iosfwd:111:
In file included from /usr/include/c++/v1/__fwd/fstream.h:13:
/usr/include/c++/v1/__fwd/string.h:45:41: error: 'char_traits<unsigned int>' is deprecated: char_traits<T> for T not equal to char, wchar_t, char8_t, char16_t or char32_t is non-standard and is provided for a temporary period. It will be removed in LLVM 19, so please migrate off of it. [-Werror,-Wdeprecated-declarations]
   45 | template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
      |                                         ^
/wrkdirs/usr/ports/devel/sfml/work/SFML-2.6.1/include/SFML/System/String.hpp:53:18: note: in instantiation of default argument for 'basic_string<Uint32>' required here
   53 |     typedef std::basic_string<Uint32>::const_iterator ConstIterator; //!< Read-only iterator type
      |                  ^~~~~~~~~~~~~~~~~~~~
/usr/include/c++/v1/__string/char_traits.h:81:8: note: 'char_traits<unsigned int>' has been explicitly marked deprecated here
   81 | struct _LIBCPP_DEPRECATED_(
      |        ^
/usr/include/c++/v1/__config:978:53: note: expanded from macro '_LIBCPP_DEPRECATED_'
  978 | #      define _LIBCPP_DEPRECATED_(m) __attribute__((__deprecated__(m)))
      |                                                     ^

And so on.

The exp-run for llvm 19 is done in bug 280562, as soon as I get permission from portmgr I will merge llvm 19 to 15-CURRENT, with a MFC time of 1 month. Then I will merge it to stable/14 and stable/13, unless re@ disagrees of course.

I'm fine with marking the port broken while this is checked with upstream.

For a number of other ports that ran into this issue, I replaced std::basic_string<T> with std:vector<T>, which most of the time is sufficient if the program is using it to store blobs or other forms of binary data.
Comment 6 Dmitry Marakasov freebsd_committer freebsd_triage 2024-11-08 15:22:04 UTC
I'm OK with it marked BROKEN for the time being.
Comment 7 Dimitry Andric freebsd_committer freebsd_triage 2024-11-08 16:13:21 UTC
FWIW upstream has fixed this in their master branch, see e.g.:

https://github.com/SFML/SFML/commit/e2528de2 Replace `sf::Uint8` with `std::uint8_t`
https://github.com/SFML/SFML/commit/ff9c9131 Replace `sf::Uint16` with `std::uint16_t`
https://github.com/SFML/SFML/commit/e294090c Replace `sf::Uint32` with `std::uint32_t`
https://github.com/SFML/SFML/commit/f371a99b Implement `sf::String` in terms of `std::u32string`
https://github.com/SFML/SFML/commit/9022d956 Define character traits for `std::uint8_t`

but backporting these is fairly annoying since they touch lots of the code.
Comment 8 commit-hook freebsd_committer freebsd_triage 2024-11-17 18:50:29 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/ports/commit/?id=38e12e980ad5d43ed70ee71b6fa5ea23c91ed47c

commit 38e12e980ad5d43ed70ee71b6fa5ea23c91ed47c
Author:     Dimitry Andric <dim@FreeBSD.org>
AuthorDate: 2024-11-17 18:49:12 +0000
Commit:     Dimitry Andric <dim@FreeBSD.org>
CommitDate: 2024-11-17 18:49:12 +0000

    devel/smfl: mark broken on FreeBSD 15

    PR:             281540
    Approved by:    amdmi3 (maintainer)
    MFH:            2024Q4

 devel/sfml/Makefile | 2 ++
 1 file changed, 2 insertions(+)
Comment 9 commit-hook freebsd_committer freebsd_triage 2024-11-17 18:51:30 UTC
A commit in branch 2024Q4 references this bug:

URL: https://cgit.FreeBSD.org/ports/commit/?id=738f9cd35f5ff3f5bacaded749ae28fa7973a7a0

commit 738f9cd35f5ff3f5bacaded749ae28fa7973a7a0
Author:     Dimitry Andric <dim@FreeBSD.org>
AuthorDate: 2024-11-17 18:49:12 +0000
Commit:     Dimitry Andric <dim@FreeBSD.org>
CommitDate: 2024-11-17 18:50:34 +0000

    devel/smfl: mark broken on FreeBSD 15

    PR:             281540
    Approved by:    amdmi3 (maintainer)
    MFH:            2024Q4

    (cherry picked from commit 38e12e980ad5d43ed70ee71b6fa5ea23c91ed47c)

 devel/sfml/Makefile | 2 ++
 1 file changed, 2 insertions(+)