[clang] [PS4, PS5][Driver] Detangle --sysroot and -isysroot (PR #107410)

Edd Dawson via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 5 07:52:51 PDT 2024


https://github.com/playstation-edd created https://github.com/llvm/llvm-project/pull/107410

The following discrepancies concerning `-isysroot` and `--sysroot` motivated this change:

- The SDK directory can be specified via `-isysroot`, but `--sysroot` has no influence over this. Yet, we check for the presence of either switch to determine whether we ought to warn about a missing SDK *headers*.

- The presence of `-isysroot` is ignored when deciding whether to warn about missing SDK *libraries*, depsite it being the only switch capable of specifying a non-default SDK location.

- The `--sysroot`s passed to the PlayStation linkers by the driver are unrelated to the SDK directory resolved in the PS4PS5Base constructor.

(We also ought to pass a sysroot-relative library search path to the linker via `-L=/target/lib`, but that's for another PR).

So we're half way between two worlds, currently:

- World 1: `-isysroot` and `--sysroot=` mean the same thing and each may
         override the SDK directory, from which both header and library
         search paths are derived.
- World 2: `-isysroot` influences header search paths and `--sysroot=`
         influences library search paths. Each independently defaults
         to the SDK directory.

This change commits to world 2, which seems to offer more flexibility for the user and better adheres to the principle of least surprise for those familiar with these options outside of a PlayStation development environment.

The test updates to ps{4,5}-sdk-root.c were of the scale of a rewrite so I also took the opportunity to clarify the purpose of each part, eliminate some redundancy and add some missing coverage.

SIE tracker: TOOLCHAIN-16704

>From a20158570f15b4200937650b90e07b99e230e3df Mon Sep 17 00:00:00 2001
From: Edd Dawson <edd.dawson at sony.com>
Date: Wed, 4 Sep 2024 12:30:11 +0100
Subject: [PATCH] [PS4,PS5][Driver] Detangle --sysroot and -isysroot

The following discrepancies concerning `-isysroot` and `--sysroot`
motivated this change:

- The SDK directory can be specified via `-isysroot`, but `--sysroot`
  has no influence over this. Yet, we check for the presence of either
  switch to determine whether we ought to warn about a missing SDK
  *headers*.

- The presence of `-isysroot` is ignored when deciding whether to warn
  about missing SDK *libraries*, depsite it being the only switch
  capable of specifying a non-default SDK location.

- The `--sysroot`s passed to the PlayStation linkers by the driver are
  unrelated to the SDK directory resolved in the PS4PS5Base constructor.

(We also ought to pass a sysroot-relative library search path to the
linker via `-L=/target/lib`, but that's for another PR).

So we're half way between two worlds, currently:

World 1: `-isysroot` and `--sysroot=` mean the same thing and each may
         override the SDK directory, from which both header and library
         search paths are derived.
World 2: `-isysroot` influences header search paths and `--sysroot=`
         influences library search paths. Each independently defaults
         to the SDK directory.

This change commits to world 2, which seems to offer more flexibility
for the user and better adheres to the principle of least surprise for
those familiar with these options outside of a PlayStation development
environment.

The test updates to ps{4,5}-sdk-root.c were of the scale of a rewrite so
I also took the opportunity to clarify the purpose of each part,
eliminate some redundancy and add some missing coverage.

SIE tracker: TOOLCHAIN-16704
---
 clang/lib/Driver/ToolChains/PS4CPU.cpp    | 81 ++++++++++++---------
 clang/lib/Driver/ToolChains/PS4CPU.h      |  7 +-
 clang/test/Driver/ps4-linker.c            |  9 +++
 clang/test/Driver/ps4-ps5-header-search.c |  4 +-
 clang/test/Driver/ps4-sdk-root.c          | 89 +++++++++++++----------
 clang/test/Driver/ps5-linker.c            |  9 +++
 clang/test/Driver/ps5-sdk-root.c          | 89 +++++++++++++----------
 7 files changed, 175 insertions(+), 113 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp
index 54ec59e6398f85..ddb5917b86a7c7 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp
@@ -135,8 +135,8 @@ void tools::PS4cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+  CmdArgs.push_back(
+      Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));
 
   if (Args.hasArg(options::OPT_pie))
     CmdArgs.push_back("-pie");
@@ -234,8 +234,8 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+  CmdArgs.push_back(
+      Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));
 
   // Default to PIE for non-static executables.
   const bool PIE =
@@ -323,46 +323,57 @@ toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const llvm::Triple &Triple,
                                    const ArgList &Args, StringRef Platform,
                                    const char *EnvVar)
     : Generic_ELF(D, Triple, Args) {
-  // Determine where to find the PS4/PS5 libraries.
-  // If -isysroot was passed, use that as the SDK base path.
-  // If not, we use the EnvVar if it exists; otherwise use the driver's
-  // installation path, which should be <SDK_DIR>/host_tools/bin.
+  // Determine the baseline SDK directory from the environment, else
+  // the driver's location, which should be <SDK_DIR>/host_tools/bin.
+  SmallString<128> SDKRootDir;
   SmallString<80> Whence;
-  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-    SDKRootDir = A->getValue();
-    if (!llvm::sys::fs::exists(SDKRootDir))
-      D.Diag(clang::diag::warn_missing_sysroot) << SDKRootDir;
-    Whence = A->getSpelling();
-  } else if (const char *EnvValue = getenv(EnvVar)) {
+  if (const char *EnvValue = getenv(EnvVar)) {
     SDKRootDir = EnvValue;
-    Whence = { "environment variable '", EnvVar, "'" };
+    Whence = {"environment variable '", EnvVar, "'"};
   } else {
     SDKRootDir = D.Dir + "/../../";
     Whence = "compiler's location";
   }
 
-  SmallString<512> SDKIncludeDir(SDKRootDir);
-  llvm::sys::path::append(SDKIncludeDir, "target/include");
-  if (!Args.hasArg(options::OPT_nostdinc) &&
-      !Args.hasArg(options::OPT_nostdlibinc) &&
-      !Args.hasArg(options::OPT_isysroot) &&
-      !Args.hasArg(options::OPT__sysroot_EQ) &&
-      !llvm::sys::fs::exists(SDKIncludeDir)) {
+  auto OverrideRoot = [&](const options::ID &Opt, std::string &Root) {
+    if (const Arg *A = Args.getLastArg(Opt)) {
+      Root = A->getValue();
+      if (!llvm::sys::fs::exists(Root))
+        D.Diag(clang::diag::warn_missing_sysroot) << Root;
+      return true;
+    }
+    Root = SDKRootDir.str();
+    return false;
+  };
+
+  auto CheckSDKPartExists = [&](StringRef Dir, StringRef Desc) {
+    if (llvm::sys::fs::exists(Dir))
+      return true;
     D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
-        << Twine(Platform, " system headers").str() << SDKIncludeDir << Whence;
+        << (Twine(Platform) + " " + Desc).str() << Dir << Whence;
+    return false;
+  };
+
+  // Allow -isysroot to override the root directory for header search, which
+  // we interpret as the user taking the reins and removing our obligation to
+  // check for the existence of SDK headers.
+  if (!OverrideRoot(options::OPT_isysroot, SDKHeaderRootDir) &&
+      !Args.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc)) {
+    SmallString<128> Dir(SDKHeaderRootDir);
+    llvm::sys::path::append(Dir, "target/include");
+    CheckSDKPartExists(Dir, "system headers");
   }
 
-  SmallString<512> SDKLibDir(SDKRootDir);
-  llvm::sys::path::append(SDKLibDir, "target/lib");
-  if (!Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
-      !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
-      !Args.hasArg(options::OPT_emit_ast) &&
-      !llvm::sys::fs::exists(SDKLibDir)) {
-    D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
-        << Twine(Platform, " system libraries").str() << SDKLibDir << Whence;
-    return;
+  // Similarly, allow --sysroot= to override the root directory for library
+  // search.
+  bool Linking = !Args.hasArg(options::OPT_E, options::OPT_c, options::OPT_S,
+                              options::OPT_emit_ast);
+  if (!OverrideRoot(options::OPT__sysroot_EQ, SDKLibraryRootDir) && Linking) {
+    SmallString<128> Dir(SDKLibraryRootDir);
+    llvm::sys::path::append(Dir, "target/lib");
+    if (CheckSDKPartExists(Dir, "system libraries"))
+      getFilePaths().push_back(std::string(Dir));
   }
-  getFilePaths().push_back(std::string(SDKLibDir));
 }
 
 void toolchains::PS4PS5Base::AddClangSystemIncludeArgs(
@@ -383,9 +394,9 @@ void toolchains::PS4PS5Base::AddClangSystemIncludeArgs(
     return;
 
   addExternCSystemInclude(DriverArgs, CC1Args,
-                          SDKRootDir + "/target/include");
+                          SDKHeaderRootDir + "/target/include");
   addExternCSystemInclude(DriverArgs, CC1Args,
-                          SDKRootDir + "/target/include_common");
+                          SDKHeaderRootDir + "/target/include_common");
 }
 
 Tool *toolchains::PS4CPU::buildAssembler() const {
diff --git a/clang/lib/Driver/ToolChains/PS4CPU.h b/clang/lib/Driver/ToolChains/PS4CPU.h
index a33728bce5186a..456e966c2d400a 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.h
+++ b/clang/lib/Driver/ToolChains/PS4CPU.h
@@ -128,9 +128,12 @@ class LLVM_LIBRARY_VISIBILITY PS4PS5Base : public Generic_ELF {
                                 const char *Suffix) const = 0;
   virtual const char *getProfileRTLibName() const = 0;
 
+  StringRef getSDKLibraryRootDir() const { return SDKLibraryRootDir; }
+
 private:
-  // We compute the SDK root dir in the ctor, and use it later.
-  std::string SDKRootDir;
+  // We compute the SDK locations in the ctor, and use them later.
+  std::string SDKHeaderRootDir;
+  std::string SDKLibraryRootDir;
 };
 
 // PS4-specific Toolchain class.
diff --git a/clang/test/Driver/ps4-linker.c b/clang/test/Driver/ps4-linker.c
index a1bc8f92537545..f3a304a956fd8a 100644
--- a/clang/test/Driver/ps4-linker.c
+++ b/clang/test/Driver/ps4-linker.c
@@ -28,3 +28,12 @@
 
 // RUN: %clang --target=x86_64-scei-ps4 %s -### 2>&1 | FileCheck --check-prefixes=CHECK-NO-LTO %s
 // CHECK-NO-LTO-NOT: -lto-debug-options
+
+// Test the driver passes a sysroot to the linker. Without --sysroot, its value
+// is sourced from the SDK environment variable.
+
+// RUN: env SCE_ORBIS_SDK_DIR=mysdk %clang --target=x64_64-scei-ps4 %s -### 2>&1 | FileCheck --check-prefixes=CHECK-SYSROOT %s
+// RUN: env SCE_ORBIS_SDK_DIR=other %clang --target=x64_64-scei-ps4 %s -### --sysroot=mysdk 2>&1 | FileCheck --check-prefixes=CHECK-SYSROOT %s
+
+// CHECK-SYSROOT: {{ld(\.exe)?}}"
+// CHECK-SYSROOT-SAME: "--sysroot=mysdk"
diff --git a/clang/test/Driver/ps4-ps5-header-search.c b/clang/test/Driver/ps4-ps5-header-search.c
index 066d284d08065e..7c24523df7a039 100644
--- a/clang/test/Driver/ps4-ps5-header-search.c
+++ b/clang/test/Driver/ps4-ps5-header-search.c
@@ -1,6 +1,6 @@
 /// PS4 and PS5 use the same SDK layout, so use the same tree for both.
-// RUN: env SCE_ORBIS_SDK_DIR=%S/Inputs/scei-ps4_tree %clang -target x86_64-scei-ps4 --sysroot="" -E -v %s 2>&1 | FileCheck %s --check-prefix=ENVPS4
-// RUN: env SCE_PROSPERO_SDK_DIR=%S/Inputs/scei-ps4_tree %clang -target x86_64-sie-ps5 --sysroot="" -E -v %s 2>&1 | FileCheck %s --check-prefix=ENVPS4
+// RUN: env SCE_ORBIS_SDK_DIR=%S/Inputs/scei-ps4_tree %clang -target x86_64-scei-ps4 -E -v %s 2>&1 | FileCheck %s --check-prefix=ENVPS4
+// RUN: env SCE_PROSPERO_SDK_DIR=%S/Inputs/scei-ps4_tree %clang -target x86_64-sie-ps5 -E -v %s 2>&1 | FileCheck %s --check-prefix=ENVPS4
 // ENVPS4: Inputs/scei-ps4_tree/target/include
 // ENVPS4: Inputs/scei-ps4_tree/target/include_common
 // ENVPS4-NOT: /usr/include
diff --git a/clang/test/Driver/ps4-sdk-root.c b/clang/test/Driver/ps4-sdk-root.c
index 3e02fa9fc3bc29..18c3c9c083eb32 100644
--- a/clang/test/Driver/ps4-sdk-root.c
+++ b/clang/test/Driver/ps4-sdk-root.c
@@ -1,42 +1,57 @@
-// Check that PS4 clang doesn't report a warning message when locating
-// system header files (either by looking at the value of SCE_ORBIS_SDK_DIR
-// or relative to the location of the compiler driver), if "-nostdinc",
-// "--sysroot" or "-isysroot" option is specified on the command line.
-// Otherwise, check that PS4 clang reports a warning.
-
-// Check that PS4 clang doesn't report a warning message when locating
-// system libraries (either by looking at the value of SCE_ORBIS_SDK_DIR
-// or relative to the location of the compiler driver), if "-c", "-S", "-E"
-// or "--sysroot" option is specified on the command line.
-// Otherwise, check that PS4 clang reports a warning.
-
-// Setting up SCE_ORBIS_SDK_DIR to existing location, which is not a PS4 SDK.
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### --sysroot=foo/ -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
+/// PS4 clang emits warnings when SDK headers or libraries are missing, or if a
+/// specified `-isysroot` or `--sysroot` does not exist.
+///
+/// If the user takes control of header or library search, the respective
+/// existence check is skipped. User control of header search is assumed if
+/// `-isysroot`, `-nostdinc` or `-nostdlibinc` is supplied. User control of
+/// library search is assumed if `--sysroot` is supplied.
+///
+/// The default sysroot for both headers and libraries is taken from the
+/// SCE_ORBIS_SDK_DIR environment variable.
+
+// RUN: echo "-### -Winvalid-or-nonexistent-directory -target x86_64-scei-ps4" > %t.rsp
+
+/// If SDK headers and/or libraries are found, associated warnings are absent.
+// RUN: rm -rf %t.inconly && mkdir -p %t.inconly/target/include
+// RUN: env SCE_ORBIS_SDK_DIR=%t.inconly %clang @%t.rsp %s 2>&1 | FileCheck -check-prefixes=WARN-SYS-LIBS,NO-WARN %s
+
+// RUN: rm -rf %t.libonly && mkdir -p %t.libonly/target/lib
+// RUN: env SCE_ORBIS_SDK_DIR=%t.libonly %clang @%t.rsp %s 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+
+// RUN: rm -rf %t.both && mkdir -p %t.both/target/lib && mkdir %t.both/target/include
+// RUN: env SCE_ORBIS_SDK_DIR=%t.both %clang @%t.rsp %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+
+/// In the following invocations, SCE_ORBIS_SDK_DIR is set to an existing
+/// location where SDK headers and libraries are absent.
+
+/// When compiling and linking, we should see a warnings about both missing
+/// headers and libraries.
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,WARN-SYS-LIBS,NO-WARN %s
+
+/// If `-c`, `-S`, `-E` or `-emit-ast` is supplied, the existence check for SDK
+/// libraries is skipped because no linking will be performed. We only expect
+/// warnings about missing headers.
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -c 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -S 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -E 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -emit-ast 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+
+/// If the user takes control of include paths, the existence check for headers
+/// is not performed.
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -c -nostdinc 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -c -nostdlibinc 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -c -isysroot . 2>&1 | FileCheck -check-prefixes=NO-WARN %s
+
+/// --sysroot disables the existence check for libraries.
+// RUN: touch %t.o
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s --sysroot=. 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+
+/// Warnings are emitted if non-existent -isysroot/--sysroot are supplied.
+// RUN: env SCE_ORBIS_SDK_DIR=.. %clang @%t.rsp %s -isysroot foo --sysroot=bar 2>&1 | FileCheck -check-prefixes=WARN-SYSROOT,WARN-SYSROOT2,NO-WARN %s
 
 // NO-WARN-NOT: {{warning:|error:}}
 // WARN-SYS-HEADERS: warning: unable to find PS4 system headers directory
-// WARN-ISYSROOT: warning: no such sysroot directory: 'foo'
+// WARN-SYSROOT: warning: no such sysroot directory: 'foo'
+// WARN-SYSROOT2: warning: no such sysroot directory: 'bar'
 // WARN-SYS-LIBS: warning: unable to find PS4 system libraries directory
 // NO-WARN-NOT: {{warning:|error:}}
diff --git a/clang/test/Driver/ps5-linker.c b/clang/test/Driver/ps5-linker.c
index 84363deb0337f7..c0cf0b864028c8 100644
--- a/clang/test/Driver/ps5-linker.c
+++ b/clang/test/Driver/ps5-linker.c
@@ -37,3 +37,12 @@
 // RUN: %clang --target=x86_64-sie-ps5 -flto -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG %s
 
 // CHECK-DIAG: -plugin-opt=-crash-diagnostics-dir=mydumps
+
+// Test the driver passes a sysroot to the linker. Without --sysroot, its value
+// is sourced from the SDK environment variable.
+
+// RUN: env SCE_PROSPERO_SDK_DIR=mysdk %clang --target=x64_64-sie-ps5 %s -### 2>&1 | FileCheck --check-prefixes=CHECK-SYSROOT %s
+// RUN: env SCE_PROSPERO_SDK_DIR=other %clang --target=x64_64-sie-ps5 %s -### --sysroot=mysdk 2>&1 | FileCheck --check-prefixes=CHECK-SYSROOT %s
+
+// CHECK-SYSROOT: {{ld(\.exe)?}}"
+// CHECK-SYSROOT-SAME: "--sysroot=mysdk"
diff --git a/clang/test/Driver/ps5-sdk-root.c b/clang/test/Driver/ps5-sdk-root.c
index 2a82d8e72283b7..d6668d721ee1fa 100644
--- a/clang/test/Driver/ps5-sdk-root.c
+++ b/clang/test/Driver/ps5-sdk-root.c
@@ -1,44 +1,59 @@
 /// (Essentially identical to ps4-sdk-root.c except for the target.)
 
-/// Check that PS5 clang doesn't report a warning message when locating
-/// system header files (either by looking at the value of SCE_PROSPERO_SDK_DIR
-/// or relative to the location of the compiler driver), if "-nostdinc",
-/// "--sysroot" or "-isysroot" option is specified on the command line.
-/// Otherwise, check that PS5 clang reports a warning.
-
-// Check that PS5 clang doesn't report a warning message when locating
-// system libraries (either by looking at the value of SCE_PROSPERO_SDK_DIR
-// or relative to the location of the compiler driver), if "-c", "-S", "-E"
-// or "--sysroot" option is specified on the command line.
-// Otherwise, check that PS5 clang reports a warning.
-
-// Setting up SCE_PROSPERO_SDK_DIR to existing location, which is not a PS5 SDK.
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s
-
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s
-
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c -nostdinc -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S -nostdinc -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E -nostdinc -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -nostdinc -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c --sysroot=foo/ -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S --sysroot=foo/ -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E --sysroot=foo/ -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast --sysroot=foo/ -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
-
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### --sysroot=foo/ -isysroot foo -target x86_64-sie-ps5 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
+/// PS5 clang emits warnings when SDK headers or libraries are missing, or if a
+/// specified `-isysroot` or `--sysroot` does not exist.
+///
+/// If the user takes control of header or library search, the respective
+/// existence check is skipped. User control of header search is assumed if
+/// `-isysroot`, `-nostdinc` or `-nostdlibinc` is supplied. User control of
+/// library search is assumed if `--sysroot` is supplied.
+///
+/// The default sysroot for both headers and libraries is taken from the
+/// SCE_PROSPERO_SDK_DIR environment variable.
+
+// RUN: echo "-### -Winvalid-or-nonexistent-directory -target x86_64-sie-ps5" > %t.rsp
+
+/// If SDK headers and/or libraries are found, associated warnings are absent.
+// RUN: rm -rf %t.inconly && mkdir -p %t.inconly/target/include
+// RUN: env SCE_PROSPERO_SDK_DIR=%t.inconly %clang @%t.rsp %s 2>&1 | FileCheck -check-prefixes=WARN-SYS-LIBS,NO-WARN %s
+
+// RUN: rm -rf %t.libonly && mkdir -p %t.libonly/target/lib
+// RUN: env SCE_PROSPERO_SDK_DIR=%t.libonly %clang @%t.rsp %s 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+
+// RUN: rm -rf %t.both && mkdir -p %t.both/target/lib && mkdir %t.both/target/include
+// RUN: env SCE_PROSPERO_SDK_DIR=%t.both %clang @%t.rsp %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+
+/// In the following invocations, SCE_PROSPERO_SDK_DIR is set to an existing
+/// location where SDK headers and libraries are absent.
+
+/// When compiling and linking, we should see a warnings about both missing
+/// headers and libraries.
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,WARN-SYS-LIBS,NO-WARN %s
+
+/// If `-c`, `-S`, `-E` or `-emit-ast` is supplied, the existence check for SDK
+/// libraries is skipped because no linking will be performed. We only expect
+/// warnings about missing headers.
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -c 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -S 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -E 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -emit-ast 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+
+/// If the user takes control of include paths, the existence check for headers
+/// is not performed.
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -c -nostdinc 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -c -nostdlibinc 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -c -isysroot . 2>&1 | FileCheck -check-prefixes=NO-WARN %s
+
+/// --sysroot disables the existence check for libraries.
+// RUN: touch %t.o
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s --sysroot=. 2>&1 | FileCheck -check-prefixes=WARN-SYS-HEADERS,NO-WARN %s
+
+/// Warnings are emitted if non-existent -isysroot/--sysroot are supplied.
+// RUN: env SCE_PROSPERO_SDK_DIR=.. %clang @%t.rsp %s -isysroot foo --sysroot=bar 2>&1 | FileCheck -check-prefixes=WARN-SYSROOT,WARN-SYSROOT2,NO-WARN %s
 
 // NO-WARN-NOT: {{warning:|error:}}
 // WARN-SYS-HEADERS: warning: unable to find PS5 system headers directory
-// WARN-ISYSROOT: warning: no such sysroot directory: 'foo'
+// WARN-SYSROOT: warning: no such sysroot directory: 'foo'
+// WARN-SYSROOT2: warning: no such sysroot directory: 'bar'
 // WARN-SYS-LIBS: warning: unable to find PS5 system libraries directory
 // NO-WARN-NOT: {{warning:|error:}}



More information about the cfe-commits mailing list