Skip to content

Commit e578bd7

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 b21fa18 commit e578bd7

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
@@ -8265,6 +8265,11 @@ def internal_externc_isystem : Separate<["-"], "internal-externc-isystem">,
82658265
"implicit extern \"C\" semantics; these are assumed to not be "
82668266
"user-provided and are used to model system and standard headers' "
82678267
"paths.">;
8268+
def internal_iframework : Separate<["-"], "internal-iframework">,
8269+
MetaVarName<"<directory>">,
8270+
HelpText<"Add directory to the internal system framework include search path; these "
8271+
"are assumed to not be user-provided and are used to model system "
8272+
"and standard frameworks' paths.">;
82688273

82698274
} // let Visibility = [CC1Option]
82708275

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
}
@@ -2539,6 +2550,18 @@ void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs
25392550
llvm::sys::path::append(P, "usr", "include");
25402551
addExternCSystemInclude(DriverArgs, CC1Args, P.str());
25412552
}
2553+
2554+
// Add default framework search paths
2555+
auto addFrameworkInclude = [&](auto ...Path) {
2556+
SmallString<128> P(Sysroot);
2557+
llvm::sys::path::append(P, Path...);
2558+
2559+
CC1Args.push_back("-internal-iframework");
2560+
CC1Args.push_back(DriverArgs.MakeArgString(P));
2561+
};
2562+
addFrameworkInclude("System", "Library", "Frameworks");
2563+
addFrameworkInclude("System", "Library", "SubFrameworks");
2564+
addFrameworkInclude("Library", "Frameworks");
25422565
}
25432566

25442567
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
@@ -3413,11 +3413,14 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
34133413

34143414
// Add the internal paths from a driver that detects standard include paths.
34153415
for (const auto *A :
3416-
Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3416+
Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem, OPT_internal_iframework)) {
34173417
frontend::IncludeDirGroup Group = frontend::System;
3418+
bool IsFramework = false;
34183419
if (A->getOption().matches(OPT_internal_externc_isystem))
34193420
Group = frontend::ExternCSystem;
3420-
Opts.AddPath(A->getValue(), Group, false, true);
3421+
if (A->getOption().matches(OPT_internal_iframework))
3422+
IsFramework = true;
3423+
Opts.AddPath(A->getValue(), Group, IsFramework, true);
34213424
}
34223425

34233426
// 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
@@ -320,6 +320,9 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
320320
break;
321321
}
322322

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

@@ -334,22 +337,6 @@ void InitHeaderSearch::AddDefaultIncludePaths(
334337
if (!ShouldAddDefaultIncludePaths(triple))
335338
return;
336339

337-
// NOTE: some additional header search logic is handled in the driver for
338-
// Darwin.
339-
if (triple.isOSDarwin()) {
340-
if (HSOpts.UseStandardSystemIncludes) {
341-
// Add the default framework include paths on Darwin.
342-
if (triple.isDriverKit()) {
343-
AddPath("/System/DriverKit/System/Library/Frameworks", System, true);
344-
} else {
345-
AddPath("/System/Library/Frameworks", System, true);
346-
AddPath("/System/Library/SubFrameworks", System, true);
347-
AddPath("/Library/Frameworks", System, true);
348-
}
349-
}
350-
return;
351-
}
352-
353340
if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
354341
HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
355342
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)