Using standard C headers from LLVM/Clang

From: Brendan Shanks <bshanks_at_codeweavers.com>
Date: Fri, 24 May 2024 16:14:03 UTC
Hi all,

I work for CodeWeavers, contributing to the Wine project. When building Wine on FreeBSD, I found that Wine refuses to use LLVM/clang from ports as a PE cross-compiler because the standard C/C99 headers are not present. In this case Wine uses clang in the 'x86_64-windows' mode, which understandably doesn’t use includes from /usr/include. configure tries to build a sample file in this mode which includes <stdarg.h>, and this fails.

Normally clang would have its own version of the standard C header files to use, but FreeBSD doesn’t install these: <https://github.com/freebsd/freebsd-src/blob/1d3c23676de33762fd7fc2e3d890fd14738d3ee6/lib/clang/headers/Makefile#L187>, <https://cgit.freebsd.org/ports/tree/devel/llvm18/files/patch-clang_lib_Headers_CMakeLists.txt>.

To work around this, the wine-devel FreeBSD port actually includes clang's stdarg.h to satisfy configure.
But besides Wine’s usage, anyone trying to use ports clang to target a freestanding/bare-metal environment would not be able to use any of these standard header files.


I filed a bug for this: <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274542> ("devel/llvm: C99 include files are not included”), and the advice was that either the FreeBSD or clang headers would need patches so they can coexist.

I thought I’d start on this by creating a GitHub pull request (<https://github.com/freebsd/freebsd-src/pull/915>) to use iso646.h and varargs.h from clang, and remove the FreeBSD versions. These files are very simple, and the two versions are functionally identical.
The advice there was that this is a bigger philosophical change, and should be discussed further.


My question for everyone: should the Clang C headers be used instead of FreeBSD maintaining its own?
Is there still a philosophical reason for FreeBSD to maintain its own set of C header files?

My opinion is that the Clang headers should be used when possible.
For one, it would fix this bug which cripples Clang when cross-compiling for other architectures.
Also, supporting new versions of C (like C23) may need changes in both the compiler and headers. FreeBSD’s headers are certainly not being updated as regularly as LLVM’s.
Lastly, I don’t know what the benefit is of FreeBSD having its own copy of these.
In a quick survey of the other OSes I use (Gentoo Linux, macOS Xcode and Homebrew), they all use LLVM’s header files.

An alternate option would be to leave the system headers in-place, but also install the Clang versions (e.g. both /usr/lib/clang/16/include/stdint.h and /usr/include/stdint.h would exist). This would work, but it would be confusing to have 2 versions of these files. GCC from ports includes its own iso646.h and varargs.h, and I believe Clang would also be using its own.

Thank you!
Brendan