From dc32ed8a8e226db3677abb19eda62cfe80572aed Mon Sep 17 00:00:00 2001 From: Julian Lettner Date: Fri, 26 Aug 2022 15:25:37 -0700 Subject: [PATCH] [Clang][Driver] Refine/refactor DriverKit support Add special Framework header search path for DriverKit. --- clang/include/clang/Driver/ToolChain.h | 4 ++ clang/lib/Driver/ToolChains/Darwin.cpp | 75 +++++++++++++++------- clang/lib/Driver/ToolChains/Darwin.h | 3 +- clang/lib/Lex/InitHeaderSearch.cpp | 9 ++- .../DriverKit/System/Library/Frameworks/.keep | 0 .../System/DriverKit/usr/lib/.keep | 0 .../System/DriverKit/usr/local/include/.keep | 0 clang/test/Driver/driverkit-path.c | 32 +++++++++ 8 files changed, 96 insertions(+), 27 deletions(-) create mode 100644 clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/System/Library/Frameworks/.keep create mode 100644 clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/lib/.keep create mode 100644 clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/local/include/.keep create mode 100644 clang/test/Driver/driverkit-path.c diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index f444cf5..59d8daf 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -258,6 +258,10 @@ public: return EffectiveTriple; } + bool hasEffectiveTriple() const { + return !EffectiveTriple.getTriple().empty(); + } + path_list &getLibraryPaths() { return LibraryPaths; } const path_list &getLibraryPaths() const { return LibraryPaths; } diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 4482a55..b060a6a 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -522,6 +522,8 @@ static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, } } +static void AppendPlatformPrefix(SmallString<128> &Path, const llvm::Triple &T); + void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -719,22 +721,31 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } - // DriverKit's framework doesn't have the same layout as other frameworks. - // Add missing search paths if necessary. - if (getToolChain().getTriple().getOS() == llvm::Triple::DriverKit) { - if (const Arg *Root = Args.getLastArg(options::OPT_isysroot)) { + // Add non-standard, platform-specific search paths, e.g., for DriverKit: + // -L/System/DriverKit/usr/lib + // -F/System/DriverKit/System/Library/Framework + { + bool NonStandardSearchPath = false; + const auto &Triple = getToolChain().getTriple(); + if (Triple.isDriverKit()) { // ld64 fixed the implicit -F and -L paths in ld64-605.1+. - if (Version.getMajor() < 605 || - (Version.getMajor() == 605 && Version.getMinor().value_or(0) < 1)) { - - SmallString<128> L(Root->getValue()); - llvm::sys::path::append(L, "System", "DriverKit", "usr", "lib"); - CmdArgs.push_back(Args.MakeArgString(std::string("-L") + L)); + NonStandardSearchPath = + Version.getMajor() < 605 || + (Version.getMajor() == 605 && Version.getMinor().value_or(0) < 1); + } - SmallString<128> F(Root->getValue()); - llvm::sys::path::append(F, "System", "DriverKit"); - llvm::sys::path::append(F, "System", "Library", "Frameworks"); - CmdArgs.push_back(Args.MakeArgString(std::string("-F") + F)); + if (NonStandardSearchPath) { + if (auto *Sysroot = Args.getLastArg(options::OPT_isysroot)) { + auto AddSearchPath = [&](StringRef Flag, StringRef SearchPath) { + SmallString<128> P(Sysroot->getValue()); + AppendPlatformPrefix(P, Triple); + llvm::sys::path::append(P, SearchPath); + if (getToolChain().getVFS().exists(P)) { + CmdArgs.push_back(Args.MakeArgString(Flag + P)); + } + }; + AddSearchPath("-L", "/usr/lib"); + AddSearchPath("-F", "/System/Library/Frameworks"); } } } @@ -2265,21 +2276,37 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { } } -// Returns the effective header sysroot path to use. This comes either from -// -isysroot or --sysroot. -llvm::StringRef DarwinClang::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const { - if(DriverArgs.hasArg(options::OPT_isysroot)) - return DriverArgs.getLastArgValue(options::OPT_isysroot); - if (!getDriver().SysRoot.empty()) - return getDriver().SysRoot; - return "/"; +// For certain platforms/environments almost all resources (e.g., headers) are +// located in sub-directories, e.g., for DriverKit they live in +// /System/DriverKit/usr/include (instead of /usr/include). +static void AppendPlatformPrefix(SmallString<128> &Path, + const llvm::Triple &T) { + if (T.isDriverKit()) { + llvm::sys::path::append(Path, "System", "DriverKit"); + } +} + +// Returns the effective sysroot from either -isysroot or --sysroot, plus the +// platform prefix (if any). +llvm::SmallString<128> +DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const { + llvm::SmallString<128> Path("/"); + if (DriverArgs.hasArg(options::OPT_isysroot)) + Path = DriverArgs.getLastArgValue(options::OPT_isysroot); + else if (!getDriver().SysRoot.empty()) + Path = getDriver().SysRoot; + + if (hasEffectiveTriple()) { + AppendPlatformPrefix(Path, getEffectiveTriple()); + } + return Path; } void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { const Driver &D = getDriver(); - llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); + llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs); bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc); bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc); @@ -2368,7 +2395,7 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs( DriverArgs.hasArg(options::OPT_nostdincxx)) return; - llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); + llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs); switch (GetCXXStdlibType(DriverArgs)) { case ToolChain::CST_Libcxx: { diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index 4535d02..619c05d 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -628,7 +628,8 @@ private: llvm::StringRef ArchDir, llvm::StringRef BitDir) const; - llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const; + llvm::SmallString<128> + GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; }; } // end namespace toolchains diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp index cd32763..0caa776 100644 --- a/clang/lib/Lex/InitHeaderSearch.cpp +++ b/clang/lib/Lex/InitHeaderSearch.cpp @@ -461,8 +461,13 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, if (triple.isOSDarwin()) { if (HSOpts.UseStandardSystemIncludes) { // Add the default framework include paths on Darwin. - AddPath("/System/Library/Frameworks", System, true); - AddPath("/Library/Frameworks", System, true); + if (triple.isDriverKit()) { + AddPath("/System/DriverKit/System/Library/Frameworks", System, true); + } + else { + AddPath("/System/Library/Frameworks", System, true); + AddPath("/Library/Frameworks", System, true); + } } return; } diff --git a/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/System/Library/Frameworks/.keep b/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/System/Library/Frameworks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/lib/.keep b/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/lib/.keep new file mode 100644 index 0000000..e69de29 diff --git a/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/local/include/.keep b/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/local/include/.keep new file mode 100644 index 0000000..e69de29 diff --git a/clang/test/Driver/driverkit-path.c b/clang/test/Driver/driverkit-path.c new file mode 100644 index 0000000..755cb22 --- /dev/null +++ b/clang/test/Driver/driverkit-path.c @@ -0,0 +1,32 @@ +// REQUIRES: x86-registered-target +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -mlinker-version=0 \ +// RUN: -isysroot %S/Inputs/DriverKit19.0.sdk -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=LD64-OLD +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -mlinker-version=604.99 \ +// RUN: -isysroot %S/Inputs/DriverKit19.0.sdk -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=LD64-OLD +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -mlinker-version=605.0 \ +// RUN: -isysroot %S/Inputs/DriverKit19.0.sdk -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=LD64-OLD +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -mlinker-version=605.1 \ +// RUN: -isysroot %S/Inputs/DriverKit19.0.sdk -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=LD64-NEW + +int main() { return 0; } +// LD64-OLD: "-isysroot" "[[PATH:[^"]*]]Inputs/DriverKit19.0.sdk" +// LD64-OLD: "-L[[PATH]]Inputs/DriverKit19.0.sdk/System/DriverKit/usr/lib" +// LD64-OLD: "-F[[PATH]]Inputs/DriverKit19.0.sdk/System/DriverKit/System/Library/Frameworks" +// LD64-NEW: "-isysroot" "[[PATH:[^"]*]]Inputs/DriverKit19.0.sdk" +// LD64-NEW-NOT: "-L[[PATH]]Inputs/DriverKit19.0.sdk/System/DriverKit/usr/lib" +// LD64-NEW-NOT: "-F[[PATH]]Inputs/DriverKit19.0.sdk/System/DriverKit/System/Library/Frameworks" + + +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -isysroot %S/Inputs/DriverKit19.0.sdk -E -v -x c++ 2>&1 | FileCheck %s --check-prefix=INC +// RUN: %clang %s -arch x86_64 -isysroot %S/Inputs/DriverKit19.0.sdk -E -v -x c++ 2>&1 | FileCheck %s --check-prefix=INC +// +// INC: -isysroot [[PATH:[^ ]*/Inputs/DriverKit19.0.sdk]] +// INC-LABEL: #include <...> search starts here: +// INC: [[PATH]]/System/DriverKit/usr/local/include +// INC: /lib/clang/{{[0-9\.]+}}/include +// INC: [[PATH]]/System/DriverKit/usr/include +// INC: [[PATH]]/System/DriverKit/System/Library/Frameworks (framework directory) -- 2.7.4