Skip to content

Commit ac16507

Browse files
committed
[clang][Darwin] Remove legacy framework search path logic in the frontend
This removes a long standing piece of technical debt. Most other platforms have moved all their header search path logic to the driver, but Darwin still had some logic for setting framework search paths present in the frontend. This patch moves that logic to the driver alongside existing logic that already handles part of these search paths. To achieve parity with the previous search path order, this patch introduces the -internal-iframework flag which is used to pass system framework paths from the driver to the frontend. These paths are handled specially in that they are added after normal framework search paths, which preserves the old frontend behavior for system frameworks. This patch is a re-application of llvm#75841 which was reverted in d34901f because it broke framework search paths. In fact, the original patch was only adding framework search paths to the linker job, but was not adding search paths for finding headers. That issue is resolved in this version of the patch, with added tests. Fixes llvm#75638
1 parent 71ddde8 commit ac16507

File tree

8 files changed

+79
-60
lines changed

8 files changed

+79
-60
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8298,6 +8298,11 @@ def internal_externc_isystem : Separate<["-"], "internal-externc-isystem">,
82988298
"implicit extern \"C\" semantics; these are assumed to not be "
82998299
"user-provided and are used to model system and standard headers' "
83008300
"paths.">;
8301+
def internal_iframework : Separate<["-"], "internal-iframework">,
8302+
MetaVarName<"<directory>">,
8303+
HelpText<"Add directory to the internal system framework include search path; these "
8304+
"are assumed to not be user-provided and are used to model system "
8305+
"and standard frameworks' paths.">;
83018306

83028307
} // let Visibility = [CC1Option]
83038308

clang/lib/Driver/Job.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,
7373
.Cases("-internal-externc-isystem", "-iprefix", true)
7474
.Cases("-iwithprefixbefore", "-isystem", "-iquote", true)
7575
.Cases("-isysroot", "-I", "-F", "-resource-dir", true)
76-
.Cases("-iframework", "-include-pch", true)
76+
.Cases("-internal-iframework", "-iframework", "-include-pch", true)
7777
.Default(false);
7878
if (IsInclude)
7979
return !HaveCrashVFS;

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -800,9 +800,15 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
800800
}
801801
}
802802

803-
// Add non-standard, platform-specific search paths, e.g., for DriverKit:
804-
// -L<sysroot>/System/DriverKit/usr/lib
805-
// -F<sysroot>/System/DriverKit/System/Library/Framework
803+
// Add framework include paths and library search paths.
804+
// There are two flavors:
805+
// 1. The "non-standard" paths, e.g. for DriverKit:
806+
// -L<sysroot>/System/DriverKit/usr/lib
807+
// -F<sysroot>/System/DriverKit/System/Library/Frameworks
808+
// 2. The "standard" paths, e.g. for macOS and iOS:
809+
// -F<sysroot>/System/Library/Frameworks
810+
// -F<sysroot>/System/Library/SubFrameworks
811+
// -F<sysroot>/Library/Frameworks
806812
{
807813
bool NonStandardSearchPath = false;
808814
const auto &Triple = getToolChain().getTriple();
@@ -813,18 +819,23 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
813819
(Version.getMajor() == 605 && Version.getMinor().value_or(0) < 1);
814820
}
815821

816-
if (NonStandardSearchPath) {
817-
if (auto *Sysroot = Args.getLastArg(options::OPT_isysroot)) {
818-
auto AddSearchPath = [&](StringRef Flag, StringRef SearchPath) {
819-
SmallString<128> P(Sysroot->getValue());
820-
AppendPlatformPrefix(P, Triple);
821-
llvm::sys::path::append(P, SearchPath);
822-
if (getToolChain().getVFS().exists(P)) {
823-
CmdArgs.push_back(Args.MakeArgString(Flag + P));
824-
}
825-
};
822+
if (auto *Sysroot = Args.getLastArg(options::OPT_isysroot)) {
823+
auto AddSearchPath = [&](StringRef Flag, StringRef SearchPath) {
824+
SmallString<128> P(Sysroot->getValue());
825+
AppendPlatformPrefix(P, Triple);
826+
llvm::sys::path::append(P, SearchPath);
827+
if (getToolChain().getVFS().exists(P)) {
828+
CmdArgs.push_back(Args.MakeArgString(Flag + P));
829+
}
830+
};
831+
832+
if (NonStandardSearchPath) {
826833
AddSearchPath("-L", "/usr/lib");
827834
AddSearchPath("-F", "/System/Library/Frameworks");
835+
} else if (!Triple.isDriverKit()) {
836+
AddSearchPath("-F", "/System/Library/Frameworks");
837+
AddSearchPath("-F", "/System/Library/SubFrameworks");
838+
AddSearchPath("-F", "/Library/Frameworks");
828839
}
829840
}
830841
}
@@ -2547,6 +2558,18 @@ void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs
25472558
llvm::sys::path::append(P, "usr", "include");
25482559
addExternCSystemInclude(DriverArgs, CC1Args, P.str());
25492560
}
2561+
2562+
// Add default framework search paths
2563+
auto addFrameworkInclude = [&](auto ...Path) {
2564+
SmallString<128> P(Sysroot);
2565+
llvm::sys::path::append(P, Path...);
2566+
2567+
CC1Args.push_back("-internal-iframework");
2568+
CC1Args.push_back(DriverArgs.MakeArgString(P));
2569+
};
2570+
addFrameworkInclude("System", "Library", "Frameworks");
2571+
addFrameworkInclude("System", "Library", "SubFrameworks");
2572+
addFrameworkInclude("Library", "Frameworks");
25502573
}
25512574

25522575
bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,11 +3436,14 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
34363436

34373437
// Add the internal paths from a driver that detects standard include paths.
34383438
for (const auto *A :
3439-
Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3439+
Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem, OPT_internal_iframework)) {
34403440
frontend::IncludeDirGroup Group = frontend::System;
3441+
bool IsFramework = false;
34413442
if (A->getOption().matches(OPT_internal_externc_isystem))
34423443
Group = frontend::ExternCSystem;
3443-
Opts.AddPath(A->getValue(), Group, false, true);
3444+
if (A->getOption().matches(OPT_internal_iframework))
3445+
IsFramework = true;
3446+
Opts.AddPath(A->getValue(), Group, IsFramework, true);
34443447
}
34453448

34463449
// Add the path prefixes which are implicitly treated as being system headers.

clang/lib/Lex/InitHeaderSearch.cpp

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
321321
break;
322322
}
323323

324+
if (triple.isOSDarwin())
325+
return false;
326+
324327
return true; // Everything else uses AddDefaultIncludePaths().
325328
}
326329

@@ -335,22 +338,6 @@ void InitHeaderSearch::AddDefaultIncludePaths(
335338
if (!ShouldAddDefaultIncludePaths(triple))
336339
return;
337340

338-
// NOTE: some additional header search logic is handled in the driver for
339-
// Darwin.
340-
if (triple.isOSDarwin()) {
341-
if (HSOpts.UseStandardSystemIncludes) {
342-
// Add the default framework include paths on Darwin.
343-
if (triple.isDriverKit()) {
344-
AddPath("/System/DriverKit/System/Library/Frameworks", System, true);
345-
} else {
346-
AddPath("/System/Library/Frameworks", System, true);
347-
AddPath("/System/Library/SubFrameworks", System, true);
348-
AddPath("/Library/Frameworks", System, true);
349-
}
350-
}
351-
return;
352-
}
353-
354341
if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
355342
HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
356343
if (HSOpts.UseLibcxx) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// UNSUPPORTED: system-windows
2+
// Windows is unsupported because we use the Unix path separator `/` in the test.
3+
4+
// Add default directories before running clang to check default
5+
// search paths.
6+
// RUN: rm -rf %t && mkdir -p %t
7+
// RUN: cp -R %S/Inputs/MacOSX15.1.sdk %t/
8+
// RUN: mkdir -p %t/MacOSX15.1.sdk/System/Library/Frameworks
9+
// RUN: mkdir -p %t/MacOSX15.1.sdk/System/Library/SubFrameworks
10+
// RUN: mkdir -p %t/MacOSX15.1.sdk/usr/include
11+
12+
// RUN: %clang -xc %s -target arm64-apple-darwin13.0 -isysroot %t/MacOSX15.1.sdk -E -v 2>&1 | FileCheck --check-prefix=CHECK-C %s
13+
//
14+
// CHECK-C: -isysroot [[PATH:[^ ]*/MacOSX15.1.sdk]]
15+
// CHECK-C: #include <...> search starts here:
16+
// CHECK-C: [[PATH]]/usr/include
17+
// CHECK-C: [[PATH]]/System/Library/Frameworks (framework directory)
18+
// CHECK-C: [[PATH]]/System/Library/SubFrameworks (framework directory)
19+
20+
// RUN: %clang -xc++ %s -target arm64-apple-darwin13.0 -isysroot %t/MacOSX15.1.sdk -E -v 2>&1 | FileCheck --check-prefix=CHECK-CXX %s
21+
//
22+
// CHECK-CXX: -isysroot [[PATH:[^ ]*/MacOSX15.1.sdk]]
23+
// CHECK-CXX: #include <...> search starts here:
24+
// CHECK-CXX: [[PATH]]/usr/include
25+
// CHECK-CXX: [[PATH]]/System/Library/Frameworks (framework directory)
26+
// CHECK-CXX: [[PATH]]/System/Library/SubFrameworks (framework directory)

clang/test/Driver/darwin-subframeworks.c

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
// RUN: %clang -cc1 -fcuda-is-device -isysroot /var/empty \
2-
// RUN: -triple nvptx-nvidia-cuda -aux-triple i386-apple-macosx \
3-
// RUN: -E -fcuda-is-device -v -o /dev/null -x cuda %s 2>&1 | FileCheck %s
4-
5-
// RUN: %clang -cc1 -isysroot /var/empty \
6-
// RUN: -triple i386-apple-macosx -aux-triple nvptx-nvidia-cuda \
7-
// RUN: -E -fcuda-is-device -v -o /dev/null -x cuda %s 2>&1 | FileCheck %s
8-
91
// Check that when we do CUDA host and device compiles on MacOS, we check for
102
// includes in /System/Library/Frameworks and /Library/Frameworks.
113

12-
// CHECK-DAG: ignoring nonexistent directory "/var/empty/System/Library/Frameworks"
13-
// CHECK-DAG: ignoring nonexistent directory "/var/empty/Library/Frameworks"
4+
// RUN: %clang -isysroot /var/empty -target unknown-nvidia-cuda -v -fsyntax-only -x cuda %s -### 2>&1 | FileCheck %s
5+
// CHECK-DAG: "-internal-iframework" "/var/empty/System/Library/Frameworks"
6+
// CHECK-DAG: "-internal-iframework" "/var/empty/Library/Frameworks"

0 commit comments

Comments
 (0)