Skip to content

Commit 0b32978

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 9f2a438 commit 0b32978

File tree

4 files changed

+26
-18
lines changed

4 files changed

+26
-18
lines changed

clang/lib/Basic/Targets/OSTargets.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,9 @@ class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
331331
} else {
332332
Builder.defineMacro("__gnu_linux__");
333333
}
334+
335+
if (Triple.isMusl())
336+
Builder.defineMacro("__musl__", "1");
334337
if (Opts.POSIXThreads)
335338
Builder.defineMacro("_REENTRANT");
336339
if (Opts.CPlusPlus)

clang/lib/Driver/ToolChains/Linux.cpp

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

631631
// Add 'include' in the resource directory, which is similar to
632632
// GCC_INCLUDE_DIR (private headers) in GCC. Note: the include directory
633-
// contains some files conflicting with system /usr/include. musl systems
634-
// prefer the /usr/include copies which are more relevant.
635-
SmallString<128> ResourceDirInclude(D.ResourceDir);
636-
llvm::sys::path::append(ResourceDirInclude, "include");
637-
if (!DriverArgs.hasArg(options::OPT_nobuiltininc) &&
638-
(!getTriple().isMusl() || DriverArgs.hasArg(options::OPT_nostdlibinc)))
633+
// contains some files conflicting with system /usr/include.
634+
//
635+
// Note: the include order used to be different on musl systems because
636+
// of the expectation that that users of that C library would use the
637+
// C library's copies of the "built-in" headers. This was a mistake;
638+
// it's better to adapt the built-in headers to fall through in that case
639+
// (using #include_next), since otherwise if they get pulled in through
640+
// some other mechanism, __has_include_next(<header>) will fail and then
641+
// they'll try to redefine things, which causes errors.
642+
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
643+
SmallString<128> ResourceDirInclude(D.ResourceDir);
644+
llvm::sys::path::append(ResourceDirInclude, "include");
639645
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
640-
646+
}
647+
641648
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
642649
return;
643650

@@ -677,9 +684,6 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
677684
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));
678685

679686
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));
680-
681-
if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl())
682-
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
683687
}
684688

685689
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
@@ -14,15 +14,11 @@
1414
#include_next <float.h>
1515
#else
1616

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

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

clang/lib/Headers/stddef.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
#undef __need_wint_t
3434
#include_next <stddef.h>
3535

36+
#elif defined(__musl__)
37+
38+
// On musl systems, use the system header
39+
#include_next <stddef.h>
40+
3641
#else
3742

3843
#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \
@@ -119,4 +124,4 @@ __WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
119124
#undef __need_wint_t
120125
#endif /* __need_wint_t */
121126

122-
#endif /* __MVS__ */
127+
#endif /* !defined(__MVS__) && !defined(__musl__) */

0 commit comments

Comments
 (0)