Skip to content

Commit 0370e1e

Browse files
[Darwin][Driver][clang] apple-none-macho orders the resource directory after internal-externc-isystem when nostdlibinc is used
Embedded development often needs to use a different C standard library, replacing the existing one normally passed as -internal-externc-isystem. This works fine for an apple-macos target, but apple-none-macho doesn't work because the MachO driver doesn't implement AddClangSystemIncludeArgs to add the resource directory as -internal-isystem like most other drivers do. Move most of the search path logic from Darwin and DarwinClang down into an AppleMachO toolchain between the MachO and Darwin toolchains.
1 parent 21a6dbd commit 0370e1e

File tree

9 files changed

+159
-79
lines changed

9 files changed

+159
-79
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6604,7 +6604,10 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
66046604
else if (Target.isOSBinFormatELF())
66056605
TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
66066606
else if (Target.isOSBinFormatMachO())
6607-
TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
6607+
if (Target.getVendor() == llvm::Triple::Apple)
6608+
TC = std::make_unique<toolchains::AppleMachO>(*this, Target, Args);
6609+
else
6610+
TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
66086611
else
66096612
TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
66106613
}

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 62 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -966,10 +966,14 @@ MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
966966
getProgramPaths().push_back(getDriver().Dir);
967967
}
968968

969+
AppleMachO::AppleMachO(const Driver &D, const llvm::Triple &Triple,
970+
const ArgList &Args)
971+
: MachO(D, Triple, Args), CudaInstallation(D, Triple, Args),
972+
RocmInstallation(D, Triple, Args) {}
973+
969974
/// Darwin - Darwin tool chain for i386 and x86_64.
970975
Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
971-
: MachO(D, Triple, Args), TargetInitialized(false),
972-
CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {}
976+
: AppleMachO(D, Triple, Args), TargetInitialized(false) {}
973977

974978
types::ID MachO::LookupTypeForExtension(StringRef Ext) const {
975979
types::ID Ty = ToolChain::LookupTypeForExtension(Ext);
@@ -1018,13 +1022,13 @@ bool Darwin::hasBlocksRuntime() const {
10181022
}
10191023
}
10201024

1021-
void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs,
1022-
ArgStringList &CC1Args) const {
1025+
void AppleMachO::AddCudaIncludeArgs(const ArgList &DriverArgs,
1026+
ArgStringList &CC1Args) const {
10231027
CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args);
10241028
}
10251029

1026-
void Darwin::AddHIPIncludeArgs(const ArgList &DriverArgs,
1027-
ArgStringList &CC1Args) const {
1030+
void AppleMachO::AddHIPIncludeArgs(const ArgList &DriverArgs,
1031+
ArgStringList &CC1Args) const {
10281032
RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
10291033
}
10301034

@@ -2482,7 +2486,7 @@ static void AppendPlatformPrefix(SmallString<128> &Path,
24822486
// Returns the effective sysroot from either -isysroot or --sysroot, plus the
24832487
// platform prefix (if any).
24842488
llvm::SmallString<128>
2485-
DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
2489+
AppleMachO::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
24862490
llvm::SmallString<128> Path("/");
24872491
if (DriverArgs.hasArg(options::OPT_isysroot))
24882492
Path = DriverArgs.getLastArgValue(options::OPT_isysroot);
@@ -2495,8 +2499,9 @@ DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
24952499
return Path;
24962500
}
24972501

2498-
void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
2499-
llvm::opt::ArgStringList &CC1Args) const {
2502+
void AppleMachO::AddClangSystemIncludeArgs(
2503+
const llvm::opt::ArgList &DriverArgs,
2504+
llvm::opt::ArgStringList &CC1Args) const {
25002505
const Driver &D = getDriver();
25012506

25022507
llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
@@ -2574,7 +2579,7 @@ bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverAr
25742579
return getVFS().exists(Base);
25752580
}
25762581

2577-
void DarwinClang::AddClangCXXStdlibIncludeArgs(
2582+
void AppleMachO::AddClangCXXStdlibIncludeArgs(
25782583
const llvm::opt::ArgList &DriverArgs,
25792584
llvm::opt::ArgStringList &CC1Args) const {
25802585
// The implementation from a base class will pass through the -stdlib to
@@ -2631,55 +2636,60 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
26312636
}
26322637

26332638
case ToolChain::CST_Libstdcxx:
2634-
llvm::SmallString<128> UsrIncludeCxx = Sysroot;
2635-
llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");
2636-
2637-
llvm::Triple::ArchType arch = getTriple().getArch();
2638-
bool IsBaseFound = true;
2639-
switch (arch) {
2640-
default: break;
2641-
2642-
case llvm::Triple::x86:
2643-
case llvm::Triple::x86_64:
2644-
IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2645-
"4.2.1",
2646-
"i686-apple-darwin10",
2647-
arch == llvm::Triple::x86_64 ? "x86_64" : "");
2648-
IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2649-
"4.0.0", "i686-apple-darwin8",
2650-
"");
2651-
break;
2639+
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);
2640+
break;
2641+
}
2642+
}
26522643

2653-
case llvm::Triple::arm:
2654-
case llvm::Triple::thumb:
2655-
IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2656-
"4.2.1",
2657-
"arm-apple-darwin10",
2658-
"v7");
2659-
IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2660-
"4.2.1",
2661-
"arm-apple-darwin10",
2662-
"v6");
2663-
break;
2644+
void AppleMachO::AddGnuCPlusPlusIncludePaths(
2645+
const llvm::opt::ArgList &DriverArgs,
2646+
llvm::opt::ArgStringList &CC1Args) const {}
26642647

2665-
case llvm::Triple::aarch64:
2666-
IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2667-
"4.2.1",
2668-
"arm64-apple-darwin10",
2669-
"");
2670-
break;
2671-
}
2648+
void DarwinClang::AddGnuCPlusPlusIncludePaths(
2649+
const llvm::opt::ArgList &DriverArgs,
2650+
llvm::opt::ArgStringList &CC1Args) const {
2651+
llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs);
2652+
llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");
26722653

2673-
if (!IsBaseFound) {
2674-
getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
2675-
}
2654+
llvm::Triple::ArchType arch = getTriple().getArch();
2655+
bool IsBaseFound = true;
2656+
switch (arch) {
2657+
default:
2658+
break;
2659+
2660+
case llvm::Triple::x86:
2661+
case llvm::Triple::x86_64:
2662+
IsBaseFound = AddGnuCPlusPlusIncludePaths(
2663+
DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", "i686-apple-darwin10",
2664+
arch == llvm::Triple::x86_64 ? "x86_64" : "");
2665+
IsBaseFound |= AddGnuCPlusPlusIncludePaths(
2666+
DriverArgs, CC1Args, UsrIncludeCxx, "4.0.0", "i686-apple-darwin8", "");
2667+
break;
2668+
2669+
case llvm::Triple::arm:
2670+
case llvm::Triple::thumb:
2671+
IsBaseFound =
2672+
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2673+
"arm-apple-darwin10", "v7");
2674+
IsBaseFound |=
2675+
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2676+
"arm-apple-darwin10", "v6");
2677+
break;
26762678

2679+
case llvm::Triple::aarch64:
2680+
IsBaseFound =
2681+
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2682+
"arm64-apple-darwin10", "");
26772683
break;
26782684
}
2685+
2686+
if (!IsBaseFound) {
2687+
getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
2688+
}
26792689
}
26802690

2681-
void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
2682-
ArgStringList &CmdArgs) const {
2691+
void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,
2692+
ArgStringList &CmdArgs) const {
26832693
CXXStdlibType Type = GetCXXStdlibType(Args);
26842694

26852695
switch (Type) {
@@ -3615,7 +3625,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const {
36153625
return Res;
36163626
}
36173627

3618-
void Darwin::printVerboseInfo(raw_ostream &OS) const {
3628+
void AppleMachO::printVerboseInfo(raw_ostream &OS) const {
36193629
CudaInstallation->print(OS);
36203630
RocmInstallation->print(OS);
36213631
}

clang/lib/Driver/ToolChains/Darwin.h

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,50 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
290290
/// }
291291
};
292292

293+
/// Apple specific MachO extensions
294+
class LLVM_LIBRARY_VISIBILITY AppleMachO : public MachO {
295+
public:
296+
AppleMachO(const Driver &D, const llvm::Triple &Triple,
297+
const llvm::opt::ArgList &Args);
298+
~AppleMachO() override;
299+
300+
/// }
301+
/// @name Apple Specific ToolChain Implementation
302+
/// {
303+
void
304+
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
305+
llvm::opt::ArgStringList &CC1Args) const override;
306+
307+
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
308+
llvm::opt::ArgStringList &CC1Args) const override;
309+
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
310+
llvm::opt::ArgStringList &CC1Args) const override;
311+
312+
void AddClangCXXStdlibIncludeArgs(
313+
const llvm::opt::ArgList &DriverArgs,
314+
llvm::opt::ArgStringList &CC1Args) const override;
315+
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
316+
llvm::opt::ArgStringList &CmdArgs) const override;
317+
318+
void printVerboseInfo(raw_ostream &OS) const override;
319+
/// }
320+
321+
LazyDetector<CudaInstallationDetector> CudaInstallation;
322+
LazyDetector<RocmInstallationDetector> RocmInstallation;
323+
324+
protected:
325+
llvm::SmallString<128>
326+
GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const;
327+
328+
private:
329+
virtual void
330+
AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
331+
llvm::opt::ArgStringList &CC1Args) const;
332+
};
333+
334+
293335
/// Darwin - The base Darwin tool chain.
294-
class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
336+
class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
295337
public:
296338
/// Whether the information on the target has been initialized.
297339
//
@@ -329,9 +371,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
329371
/// The target variant triple that was specified (if any).
330372
mutable std::optional<llvm::Triple> TargetVariantTriple;
331373

332-
LazyDetector<CudaInstallationDetector> CudaInstallation;
333-
LazyDetector<RocmInstallationDetector> RocmInstallation;
334-
335374
private:
336375
void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
337376

@@ -343,7 +382,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
343382
std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
344383
types::ID InputType) const override;
345384

346-
/// @name Apple Specific Toolchain Implementation
385+
/// @name Darwin Specific Toolchain Implementation
347386
/// {
348387

349388
void addMinVersionArgs(const llvm::opt::ArgList &Args,
@@ -559,11 +598,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
559598
ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
560599
bool hasBlocksRuntime() const override;
561600

562-
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
563-
llvm::opt::ArgStringList &CC1Args) const override;
564-
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
565-
llvm::opt::ArgStringList &CC1Args) const override;
566-
567601
bool UseObjCMixedDispatch() const override {
568602
// This is only used with the non-fragile ABI and non-legacy dispatch.
569603

@@ -594,8 +628,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
594628
bool SupportsEmbeddedBitcode() const override;
595629

596630
SanitizerMask getSupportedSanitizers() const override;
597-
598-
void printVerboseInfo(raw_ostream &OS) const override;
599631
};
600632

601633
/// DarwinClang - The Darwin toolchain used by Clang.
@@ -613,16 +645,6 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
613645
llvm::opt::ArgStringList &CmdArgs,
614646
bool ForceLinkBuiltinRT = false) const override;
615647

616-
void AddClangCXXStdlibIncludeArgs(
617-
const llvm::opt::ArgList &DriverArgs,
618-
llvm::opt::ArgStringList &CC1Args) const override;
619-
620-
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
621-
llvm::opt::ArgStringList &CC1Args) const override;
622-
623-
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
624-
llvm::opt::ArgStringList &CmdArgs) const override;
625-
626648
void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
627649
llvm::opt::ArgStringList &CmdArgs) const override;
628650

@@ -647,15 +669,16 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
647669
StringRef Sanitizer,
648670
bool shared = true) const;
649671

672+
void
673+
AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
674+
llvm::opt::ArgStringList &CC1Args) const override;
675+
650676
bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
651677
llvm::opt::ArgStringList &CC1Args,
652678
llvm::SmallString<128> Base,
653679
llvm::StringRef Version,
654680
llvm::StringRef ArchDir,
655681
llvm::StringRef BitDir) const;
656-
657-
llvm::SmallString<128>
658-
GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const;
659682
};
660683

661684
} // end namespace toolchains

clang/lib/Lex/InitHeaderSearch.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,8 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
312312
break;
313313

314314
case llvm::Triple::UnknownOS:
315-
if (triple.isWasm())
315+
if (triple.isWasm() || ((triple.getVendor() == llvm::Triple::Apple) &&
316+
triple.isOSBinFormatMachO()))
316317
return false;
317318
break;
318319

clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/include/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/local/include/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/include/c++/v1/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/local/include/.keep

Whitespace-only changes.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// UNSUPPORTED: system-windows
2+
// Windows is unsupported because we use the Unix path separator `/` in the test.
3+
4+
// Unlike the Darwin driver, the MachO driver doesn't add any framework search paths,
5+
// only the normal header ones.
6+
// RUN: %clang -x c -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \
7+
// RUN: | FileCheck --check-prefixes=CC1,NO-CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s
8+
9+
// Unlike the Darwin driver, the MachO driver doesn't default to libc++
10+
// RUN: %clang -x c++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \
11+
// RUN: | FileCheck --check-prefixes=CC1,NO-CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s
12+
13+
// However, if the user requests libc++, the MachO driver should find the search path.
14+
// RUN: %clang -x c++ -stdlib=libc++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \
15+
// RUN: | FileCheck --check-prefixes=CC1,CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s
16+
17+
// Verify that embedded uses can swap in alternate usr/include and usr/local/include directories.
18+
// usr/local/include is specified in the driver as -internal-isystem, however, the driver generated
19+
// paths come before the paths in the driver arguments. In order to keep usr/local/include in the
20+
// same position, -isystem has to be used instead of -Xclang -internal-isystem. There isn't an
21+
// -externc-isystem, but it's ok to use -Xclang -internal-externc-isystem since the driver doesn't
22+
// use that if -nostdlibinc or -nostdinc is passed.
23+
// RUN: %clang -x c++ -stdlib=libc++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk \
24+
// RUN: -nostdlibinc -isystem %S/Inputs/MacOSX15.1.sdk/embedded/usr/local/include \
25+
// RUN: -Xclang -internal-externc-isystem -Xclang %S/Inputs/MacOSX15.1.sdk/embedded/usr/include \
26+
// RUN: -### -c %s 2>&1 | FileCheck --check-prefixes=CC1,NO-CXX,EULI,CI,EUI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s
27+
28+
29+
// The ordering of these flags doesn't matter, and so this test is a little
30+
// fragile. i.e. all of the -internal-isystem paths will be searched before the
31+
// -internal-externc-isystem ones, and their order on the command line doesn't
32+
// matter. The line order here is just the current order that the driver writes
33+
// the cc1 arguments.
34+
35+
// CC1: "-cc1"
36+
// NO-CXX-NOT: "-internal-isystem" "[[SDKROOT]]/usr/include/c++/v1"
37+
// CXX-SAME: "-internal-isystem" "[[SDKROOT]]/usr/include/c++/v1"
38+
// ULI-SAME: "-internal-isystem" "[[SDKROOT]]/usr/local/include"
39+
// EULI-SAME: "-isystem" "[[SDKROOT]]/embedded/usr/local/include"
40+
// CI-SAME: "-internal-isystem" "{{.*}}/clang/{{[[:digit:].]*}}/include"
41+
// UI-SAME: "-internal-externc-isystem" "[[SDKROOT]]/usr/include"
42+
// EUI-SAME: "-internal-externc-isystem" "[[SDKROOT]]/embedded/usr/include"
43+
// NO-FW-NOT: "-internal-iframework"

0 commit comments

Comments
 (0)