@@ -180,7 +180,7 @@ createClangArgs(const ASTContext &ctx, clang::driver::Driver &clangDriver) {
180180
181181static bool shouldInjectLibcModulemap (const llvm::Triple &triple) {
182182 return triple.isOSGlibc () || triple.isOSOpenBSD () || triple.isOSFreeBSD () ||
183- triple.isAndroid () || triple.isOSWASI ();
183+ triple.isAndroid () || triple.isMusl () || triple. isOSWASI ();
184184}
185185
186186static SmallVector<std::pair<std::string, std::string>, 2 >
@@ -254,8 +254,9 @@ static void getLibStdCxxFileMapping(
254254 // We currently only need this when building for Linux.
255255 if (!triple.isOSLinux ())
256256 return ;
257- // Android uses libc++.
258- if (triple.isAndroid ())
257+ // Android uses libc++, as does our fully static Linux config.
258+ if (triple.isAndroid ()
259+ || (triple.isMusl () && triple.getVendor () == llvm::Triple::Swift))
259260 return ;
260261
261262 // Extract the libstdc++ installation path from Clang driver.
@@ -529,30 +530,44 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
529530
530531 const llvm::Triple &triple = ctx.LangOpts .Target ;
531532
533+ // For modulemaps that have all the C standard library headers together in
534+ // a single module, we end up with module cycles with the clang _Builtin_
535+ // modules. e.g. <inttypes.h> includes <stdint.h> on these platforms. The
536+ // clang builtin <stdint.h> include-nexts <stdint.h>. When both of those
537+ // platform headers are in the SwiftLibc module, there's a module cycle
538+ // SwiftLibc -> _Builtin_stdint -> SwiftLibc (i.e. inttypes.h (platform) ->
539+ // stdint.h (builtin) -> stdint.h (platform)).
540+ //
541+ // Until these modulemaps can be fixed, the builtin headers need to join
542+ // the system modules to avoid the cycle.
543+ //
544+ // Note that this does nothing to fix the same problem with C++ headers,
545+ // and that this is generally a fragile solution.
546+ //
547+ // We start by assuming we do *not* need to do this, then enable it for
548+ // affected modulemaps.
549+ result.requiresBuiltinHeadersInSystemModules = false ;
550+
532551 SmallVector<std::pair<std::string, std::string>, 2 > libcFileMapping;
533552 if (triple.isOSWASI ()) {
534553 // WASI Mappings
535554 libcFileMapping =
536555 getLibcFileMapping (ctx, " wasi-libc.modulemap" , std::nullopt , vfs);
556+
557+ // WASI's module map needs fixing
558+ result.requiresBuiltinHeadersInSystemModules = true ;
559+ } else if (triple.isMusl ()) {
560+ libcFileMapping =
561+ getLibcFileMapping (ctx, " musl.modulemap" , StringRef (" SwiftMusl.h" ), vfs);
537562 } else {
538563 // Android/BSD/Linux Mappings
539564 libcFileMapping = getLibcFileMapping (ctx, " glibc.modulemap" ,
540565 StringRef (" SwiftGlibc.h" ), vfs);
566+
567+ // glibc.modulemap needs fixing
568+ result.requiresBuiltinHeadersInSystemModules = true ;
541569 }
542570 result.redirectedFiles .append (libcFileMapping);
543- // Both libc module maps have the C standard library headers all together in a
544- // SwiftLibc module. That leads to module cycles with the clang _Builtin_
545- // modules. e.g. <inttypes.h> includes <stdint.h> on these platforms. The
546- // clang builtin <stdint.h> include-nexts <stdint.h>. When both of those
547- // platform headers are in the SwiftLibc module, there's a module cycle
548- // SwiftLibc -> _Builtin_stdint -> SwiftLibc (i.e. inttypes.h (platform) ->
549- // stdint.h (builtin) -> stdint.h (platform)). Until this can be fixed in
550- // these module maps, the clang builtin headers need to join the "system"
551- // modules (SwiftLibc). i.e. when the clang builtin stdint.h is in the
552- // SwiftLibc module too, the cycle goes away. Note that
553- // -fbuiltin-headers-in-system-modules does nothing to fix the same problem
554- // with C++ headers, and is generally fragile.
555- result.requiresBuiltinHeadersInSystemModules = !libcFileMapping.empty ();
556571
557572 if (ctx.LangOpts .EnableCXXInterop )
558573 getLibStdCxxFileMapping (result, ctx, vfs);
0 commit comments