MaskRay updated this revision to Diff 375751.
MaskRay marked an inline comment as done.
MaskRay retitled this revision from "[Driver] Support Debian multiarch style 
lib/clang/14.0.0/x86_64-linux-gnu runtime path" to "[Driver] Support Debian 
multiarch style lib/clang/14.0.0/x86_64-linux-gnu runtime path and 
include/x86_64-linux-gnu/c++/v1 libc++ path".
MaskRay edited the summary of this revision.
MaskRay added a comment.

Fix libc++ include path as well
Prefer unnormalized over normalized (@smeenai)
Fix getStdlibPath as well


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D110663/new/

https://reviews.llvm.org/D110663

Files:
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/test/Driver/Inputs/debian_per_target_tree/usr/lib/llvm-14/bin/.keep
  
clang/test/Driver/Inputs/debian_per_target_tree/usr/lib/llvm-14/include/c++/v1/.keep
  
clang/test/Driver/Inputs/debian_per_target_tree/usr/lib/llvm-14/include/x86_64-linux-gnu/c++/v1/.keep
  
clang/test/Driver/Inputs/debian_per_target_tree/usr/lib/llvm-14/lib/clang/14.0.0/lib/x86_64-linux-gnu/libclang_rt.builtins.a
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir_debian/lib/x86_64-linux-gnu/libclang_rt.builtins.a
  clang/test/Driver/linux-cross.cpp


Index: clang/test/Driver/linux-cross.cpp
===================================================================
--- clang/test/Driver/linux-cross.cpp
+++ clang/test/Driver/linux-cross.cpp
@@ -151,6 +151,34 @@
 // DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib"
 // DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib"
 
+/// Test native x86-64 with -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=on.
+// RUN: %clang -### %s --target=x86_64-linux-gnu 
--sysroot=%S/Inputs/debian_multiarch_tree \
+// RUN:   -ccc-install-dir 
%S/Inputs/debian_per_target_tree/usr/lib/llvm-14/bin 
-resource-dir=%S/Inputs/debian_per_target_tree/usr/lib/llvm-14/lib/clang/14.0.0 
\
+// RUN:   --stdlib=libc++ --rtlib=compiler-rt 2>&1 | FileCheck %s 
--check-prefix=DEBIAN_X86_64_PER_TARGET
+// DEBIAN_X86_64_PER_TARGET:      "-resource-dir" "[[RESOURCE:[^"]+]]"
+// DEBIAN_X86_64_PER_TARGET:      "-internal-isystem"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} 
"[[PREFIX:[^"]+llvm-14]]/bin/../include/x86_64-linux-gnu/c++/v1"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" 
"[[PREFIX]]/bin/../include/c++/v1"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" 
"[[RESOURCE]]/include"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" 
"[[SYSROOT:[^"]+]]/usr/local/include"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" 
"[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include"
+
+// DEBIAN_X86_64_PER_TARGET:      "-L
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}}[[PREFIX]]/bin/../lib/x86_64-linux-gnu"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} 
"-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10"
+/// Debian patches MULTILIB_OSDIRNAMES (../lib64 -> ../lib), so gcc uses 'lib' 
instead of 'lib64'.
+/// This difference does not matter in practice.
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} 
"-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib64"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/lib/x86_64-linux-gnu"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} 
"-L[[SYSROOT]]/usr/lib/x86_64-linux-gnu"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib64"
+/// /usr/x86_64-linux-gnu does not exist, so there is no 
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/lib.
+/// -ccc-install-dir is not within sysroot. No bin/../lib.
+/// $sysroot/lib and $sysroot/usr/lib. Fallback when GCC installation is 
unavailable.
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/lib"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/usr/lib"
+
 /// LDSO_ARCH is i386 for all x86-32 variants.
 // RUN: %clang -### %s --target=i686-linux-musl --sysroot= \
 // RUN:   --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s 
--check-prefix=MUSL_I686
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2910,9 +2910,16 @@
       return false;
 
     // First add the per-target include path if it exists.
-    std::string TargetDir = Path + "/" + Target + "/c++/" + Version;
-    if (D.getVFS().exists(TargetDir))
+    std::string TargetDir = Path + "/" + D.getTargetTriple() + "/c++/" + 
Version;
+    if (D.getVFS().exists(TargetDir)) {
+      // Unnormalized D.getTargetTriple(), e.g. x86_64-linux-gnu if --target
+      // does not contain vendor part.
       addSystemInclude(DriverArgs, CC1Args, TargetDir);
+    } else {
+      // Normalized Target, e.g. x86_64-unknown-linux-gnu.
+      TargetDir = Path + "/" + Target + "/c++/" + Version;
+      addSystemInclude(DriverArgs, CC1Args, TargetDir);
+    }
 
     // Second add the generic one.
     addSystemInclude(DriverArgs, CC1Args, Path + "/c++/" + Version);
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -488,15 +488,31 @@
 }
 
 std::string ToolChain::getRuntimePath() const {
+  // Prefer unnormalized D.getTargetTriple() (e.g. x86_64-linux-gnu) over the
+  // normalized getTripleString() (e.g. x86_64-unknown-linux-gnu). This is
+  // essential when LLVM_DEFAULT_TARGET_TRIPLE uses Debian multiarch style
+  // "x86_64-linux-gnu" (no vendor part).
   SmallString<128> P(D.ResourceDir);
+  llvm::sys::path::append(P, D.ResourceDir, "lib", D.getTargetTriple());
+  if (getVFS().exists(P))
+    return std::string(P);
+
+  P.assign(D.ResourceDir);
   llvm::sys::path::append(P, "lib", getTripleString());
-  return std::string(P.str());
+  return std::string(P);
 }
 
 std::string ToolChain::getStdlibPath() const {
   SmallString<128> P(D.Dir);
+  // First try the unnormalized triple a la getRuntimePath().
+  llvm::sys::path::append(P, "..", "lib", D.getTargetTriple());
+  if (getVFS().exists(P))
+    return std::string(P);
+
+  // Then try the normalized triple, e.g. x86_64-unknown-linux-gnu.
+  P.assign(D.ResourceDir);
   llvm::sys::path::append(P, "..", "lib", getTripleString());
-  return std::string(P.str());
+  return std::string(P);
 }
 
 std::string ToolChain::getArchSpecificLibPath() const {


Index: clang/test/Driver/linux-cross.cpp
===================================================================
--- clang/test/Driver/linux-cross.cpp
+++ clang/test/Driver/linux-cross.cpp
@@ -151,6 +151,34 @@
 // DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib"
 // DEBIAN_AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib"
 
+/// Test native x86-64 with -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=on.
+// RUN: %clang -### %s --target=x86_64-linux-gnu --sysroot=%S/Inputs/debian_multiarch_tree \
+// RUN:   -ccc-install-dir %S/Inputs/debian_per_target_tree/usr/lib/llvm-14/bin -resource-dir=%S/Inputs/debian_per_target_tree/usr/lib/llvm-14/lib/clang/14.0.0 \
+// RUN:   --stdlib=libc++ --rtlib=compiler-rt 2>&1 | FileCheck %s --check-prefix=DEBIAN_X86_64_PER_TARGET
+// DEBIAN_X86_64_PER_TARGET:      "-resource-dir" "[[RESOURCE:[^"]+]]"
+// DEBIAN_X86_64_PER_TARGET:      "-internal-isystem"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "[[PREFIX:[^"]+llvm-14]]/bin/../include/x86_64-linux-gnu/c++/v1"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" "[[PREFIX]]/bin/../include/c++/v1"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]/include"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/local/include"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include"
+
+// DEBIAN_X86_64_PER_TARGET:      "-L
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}}[[PREFIX]]/bin/../lib/x86_64-linux-gnu"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10"
+/// Debian patches MULTILIB_OSDIRNAMES (../lib64 -> ../lib), so gcc uses 'lib' instead of 'lib64'.
+/// This difference does not matter in practice.
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib64"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/lib/x86_64-linux-gnu"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/x86_64-linux-gnu"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib64"
+/// /usr/x86_64-linux-gnu does not exist, so there is no /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/lib.
+/// -ccc-install-dir is not within sysroot. No bin/../lib.
+/// $sysroot/lib and $sysroot/usr/lib. Fallback when GCC installation is unavailable.
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/lib"
+// DEBIAN_X86_64_PER_TARGET-SAME: {{^}} "-L[[SYSROOT]]/usr/lib"
+
 /// LDSO_ARCH is i386 for all x86-32 variants.
 // RUN: %clang -### %s --target=i686-linux-musl --sysroot= \
 // RUN:   --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=MUSL_I686
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2910,9 +2910,16 @@
       return false;
 
     // First add the per-target include path if it exists.
-    std::string TargetDir = Path + "/" + Target + "/c++/" + Version;
-    if (D.getVFS().exists(TargetDir))
+    std::string TargetDir = Path + "/" + D.getTargetTriple() + "/c++/" + Version;
+    if (D.getVFS().exists(TargetDir)) {
+      // Unnormalized D.getTargetTriple(), e.g. x86_64-linux-gnu if --target
+      // does not contain vendor part.
       addSystemInclude(DriverArgs, CC1Args, TargetDir);
+    } else {
+      // Normalized Target, e.g. x86_64-unknown-linux-gnu.
+      TargetDir = Path + "/" + Target + "/c++/" + Version;
+      addSystemInclude(DriverArgs, CC1Args, TargetDir);
+    }
 
     // Second add the generic one.
     addSystemInclude(DriverArgs, CC1Args, Path + "/c++/" + Version);
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -488,15 +488,31 @@
 }
 
 std::string ToolChain::getRuntimePath() const {
+  // Prefer unnormalized D.getTargetTriple() (e.g. x86_64-linux-gnu) over the
+  // normalized getTripleString() (e.g. x86_64-unknown-linux-gnu). This is
+  // essential when LLVM_DEFAULT_TARGET_TRIPLE uses Debian multiarch style
+  // "x86_64-linux-gnu" (no vendor part).
   SmallString<128> P(D.ResourceDir);
+  llvm::sys::path::append(P, D.ResourceDir, "lib", D.getTargetTriple());
+  if (getVFS().exists(P))
+    return std::string(P);
+
+  P.assign(D.ResourceDir);
   llvm::sys::path::append(P, "lib", getTripleString());
-  return std::string(P.str());
+  return std::string(P);
 }
 
 std::string ToolChain::getStdlibPath() const {
   SmallString<128> P(D.Dir);
+  // First try the unnormalized triple a la getRuntimePath().
+  llvm::sys::path::append(P, "..", "lib", D.getTargetTriple());
+  if (getVFS().exists(P))
+    return std::string(P);
+
+  // Then try the normalized triple, e.g. x86_64-unknown-linux-gnu.
+  P.assign(D.ResourceDir);
   llvm::sys::path::append(P, "..", "lib", getTripleString());
-  return std::string(P.str());
+  return std::string(P);
 }
 
 std::string ToolChain::getArchSpecificLibPath() const {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to