How to compile C++ header units?

I am basically seeking the answer for this question How to compile c++20 module header unit with clang++ - Stack Overflow.

Does clang 16 or 17 support compiling header units as modules to be later used with import <header>; syntax?
For example with GCC I would call g++ -std=c++20 -fmodules-ts -x c++-system-header iostream and it would generate a module file.

At the bottom of this document are instructions about header units.

I tried that at some point but I am getting an error.
I am using clang 16.0.0~rc1

$ clang++ -std=c++20 -xc++-system-header --precompile iostream -o iostream.pcm
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:36:13: warning: #pragma system_header ignored in main file [-Wpragma-system-header-outside-header]
#pragma GCC system_header
            ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/exception:168:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/exception_ptr.h:43:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/move.h:57:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/type_traits:2393:10: error: non-inline external definitions are not permitted in C++ header units
    auto declval() noexcept -> decltype(__declval<_Tp>(0))
         ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/exception:168:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/exception_ptr.h:240:5: error: non-inline external definitions are not permitted in C++ header units
    make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:45:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/compare:39:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/concepts:217:22: error: no matching function for call to 'declval'
          noexcept(noexcept(std::declval<const _Swap&>()(*__e1, *__e2)))
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/type_traits:2393:10: note: candidate template ignored: substitution failure [with _Tp = const _Swap &]
    auto declval() noexcept -> decltype(__declval<_Tp>(0))
         ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:46:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:61:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_iterator_base_types.h:71:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/iterator_concepts.h:966:7: error: non-inline external definitions are not permitted in C++ header units
      __begin(_Tp& __t)
      ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:351:4: error: no matching function for call to 'construct_at'
          std::construct_at(__builtin_addressof(__c1), __c2);
          ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:262:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s1 + __i, __s2[__i]);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:219:4: note: in instantiation of member function '__gnu_cxx::char_traits<char>::copy' requested here
          copy(__tmp, __s2, __n);
          ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:417:46: note: in instantiation of member function '__gnu_cxx::char_traits<char>::move' requested here
          return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:281:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s + __i, __a);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:441:46: note: in instantiation of member function '__gnu_cxx::char_traits<char>::assign' requested here
          return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:489:4: error: no matching function for call to 'construct_at'
          std::construct_at(__builtin_addressof(__c1), __c2);
          ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:262:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s1 + __i, __s2[__i]);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:219:4: note: in instantiation of member function '__gnu_cxx::char_traits<wchar_t>::copy' requested here
          copy(__tmp, __s2, __n);
          ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:544:46: note: in instantiation of member function '__gnu_cxx::char_traits<wchar_t>::move' requested here
          return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:281:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s + __i, __a);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:568:46: note: in instantiation of member function '__gnu_cxx::char_traits<wchar_t>::assign' requested here
          return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:617:4: error: no matching function for call to 'construct_at'
          std::construct_at(__builtin_addressof(__c1), __c2);
          ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:262:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s1 + __i, __s2[__i]);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:219:4: note: in instantiation of member function '__gnu_cxx::char_traits<char8_t>::copy' requested here
          copy(__tmp, __s2, __n);
          ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:675:46: note: in instantiation of member function '__gnu_cxx::char_traits<char8_t>::move' requested here
          return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:281:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s + __i, __a);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:699:46: note: in instantiation of member function '__gnu_cxx::char_traits<char8_t>::assign' requested here
          return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:760:4: error: no matching function for call to 'construct_at'
          std::construct_at(__builtin_addressof(__c1), __c2);
          ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:262:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s1 + __i, __s2[__i]);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:219:4: note: in instantiation of member function '__gnu_cxx::char_traits<char16_t>::copy' requested here
          copy(__tmp, __s2, __n);
          ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:810:46: note: in instantiation of member function '__gnu_cxx::char_traits<char16_t>::move' requested here
          return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:881:4: error: no matching function for call to 'construct_at'
          std::construct_at(__builtin_addressof(__c1), __c2);
          ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:40:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:262:6: error: no matching function for call to 'construct_at'
            std::construct_at(__s1 + __i, __s2[__i]);
            ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:219:4: note: in instantiation of member function '__gnu_cxx::char_traits<char32_t>::copy' requested here
          copy(__tmp, __s2, __n);
          ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/char_traits.h:931:46: note: in instantiation of member function '__gnu_cxx::char_traits<char32_t>::move' requested here
          return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
                                                    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = char_type, _Args = <const char_type &>]: no matching function for call to 'declval'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/ios:42:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/ios_base.h:41:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/locale_classes.h:40:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/string:44:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/ostream_insert.h:77:5: error: non-inline external definitions are not permitted in C++ header units
    __ostream_insert(basic_ostream<_CharT, _Traits>& __out,
    ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/ostream_insert.h:119:28: error: explicit instantiation of '__ostream_insert' does not refer to a function template, variable template, member function, member class, or static data member
  extern template ostream& __ostream_insert(ostream&, const char*, streamsize);
                           ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/ostream_insert.h:77:5: note: candidate template ignored: substitution failure [with _CharT = char, _Traits = std::char_traits<char>]
    __ostream_insert(basic_ostream<_CharT, _Traits>& __out,
    ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
1 warning and 20 errors generated.

Here is a comment (at the bottom) by a libc++ maintainer that they do not support modules. However, they want to look into it soonish.

Ah wait. That is a gcc libstdcpp header.

I just got my hands on clang 16.0.0~rc3 and I can precompile with libstdc++!

Hmm… no, I don’t think it works any more than before.