Skip to content

Commit 9d9d463

Browse files
committed
[Clang] Prioritise built-in headers, even on musl.
Clang was putting its built-in headers at the end of the search path if running on musl; this was a mistake, because it breaks libc++, as the latter tries to include the built-in header and then the `#include_next` in the built-in header fails. The right solution here is to have the built-in headers remain in their usual location in the search path, and then if it's desirable to override them for musl, have them explicitly include the musl header with `#include_next`. This is the solution that is already in use for other platforms. rdar://118881637
1 parent 8aff003 commit 9d9d463

File tree

4 files changed

+30
-17
lines changed

4 files changed

+30
-17
lines changed

clang/lib/Basic/Targets/OSTargets.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
384384
} else {
385385
Builder.defineMacro("__gnu_linux__");
386386
}
387+
388+
if (Triple.isMusl())
389+
Builder.defineMacro("__musl__", "1");
387390
if (Opts.POSIXThreads)
388391
Builder.defineMacro("_REENTRANT");
389392
if (Opts.CPlusPlus)

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -618,14 +618,21 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
618618

619619
// Add 'include' in the resource directory, which is similar to
620620
// GCC_INCLUDE_DIR (private headers) in GCC. Note: the include directory
621-
// contains some files conflicting with system /usr/include. musl systems
622-
// prefer the /usr/include copies which are more relevant.
623-
SmallString<128> ResourceDirInclude(D.ResourceDir);
624-
llvm::sys::path::append(ResourceDirInclude, "include");
625-
if (!DriverArgs.hasArg(options::OPT_nobuiltininc) &&
626-
(!getTriple().isMusl() || DriverArgs.hasArg(options::OPT_nostdlibinc)))
621+
// contains some files conflicting with system /usr/include.
622+
//
623+
// Note: the include order used to be different on musl systems because
624+
// of the expectation that that users of that C library would use the
625+
// C library's copies of the "built-in" headers. This was a mistake;
626+
// it's better to adapt the built-in headers to fall through in that case
627+
// (using #include_next), since otherwise if they get pulled in through
628+
// some other mechanism, __has_include_next(<header>) will fail and then
629+
// they'll try to redefine things, which causes errors.
630+
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
631+
SmallString<128> ResourceDirInclude(D.ResourceDir);
632+
llvm::sys::path::append(ResourceDirInclude, "include");
627633
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
628-
634+
}
635+
629636
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
630637
return;
631638

@@ -665,9 +672,6 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
665672
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));
666673

667674
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));
668-
669-
if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl())
670-
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
671675
}
672676

673677
void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,

clang/lib/Headers/float.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,11 @@
1010
#ifndef __CLANG_FLOAT_H
1111
#define __CLANG_FLOAT_H
1212

13-
/* If we're on MinGW, fall back to the system's float.h, which might have
14-
* additional definitions provided for Windows.
15-
* For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx
16-
*
17-
* Also fall back on Darwin and AIX to allow additional definitions and
18-
* implementation-defined values.
13+
/* On various platforms, fall back to the system's float.h, which might have
14+
* additional definitions and/or implementation-defined values.
1915
*/
2016
#if (defined(__APPLE__) || defined(__MINGW32__) || defined(_MSC_VER) || \
21-
defined(_AIX)) && \
17+
defined(_AIX) || defined(__musl__)) && \
2218
__STDC_HOSTED__ && __has_include_next(<float.h>)
2319

2420
/* Prior to Apple's 10.7 SDK, float.h SDK header used to apply an extra level

clang/lib/Headers/stddef.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
* When clang modules are not enabled, the header guards can function in the
2929
* normal simple fashion.
3030
*/
31+
32+
#if defined(__musl__)
33+
34+
// On musl systems, use the system header
35+
#include_next <stddef.h>
36+
37+
#else
38+
3139
#if !defined(__STDDEF_H) || __has_feature(modules) || \
3240
(defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1) || \
3341
defined(__need_ptrdiff_t) || defined(__need_size_t) || \
@@ -123,3 +131,5 @@ __WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
123131
#endif /* __need_wint_t */
124132

125133
#endif
134+
135+
#endif /* !defined(__musl__) */

0 commit comments

Comments
 (0)