Skip to content

[Clang][Driver] Installation detectors in user facing include dir #151114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 30, 2025

Conversation

jchlanda
Copy link
Contributor

This patch moves LazyDetector and target specific (Cuda, Hip, SYCL) installation detectors to clang's include directory. It was problematic for downstream to use headers from clang's lib dir. The use of lib headers could lead to subtle errors, as some of the symbols there are annotated with LLVM_LIBRARY_VISIBILITY. For instance ROCMToolChain::getCommonDeviceLibNames is c++ public, but because of the annotation it ends up as ELF hidden symbol, which causes errors when accessed from another shared library.

@jchlanda jchlanda requested review from arsenm and jhuber6 July 29, 2025 09:52
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:AMDGPU clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Jul 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 29, 2025

@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-clang-driver

Author: Jakub Chlanda (jchlanda)

Changes

This patch moves LazyDetector and target specific (Cuda, Hip, SYCL) installation detectors to clang's include directory. It was problematic for downstream to use headers from clang's lib dir. The use of lib headers could lead to subtle errors, as some of the symbols there are annotated with LLVM_LIBRARY_VISIBILITY. For instance ROCMToolChain::getCommonDeviceLibNames is c++ public, but because of the annotation it ends up as ELF hidden symbol, which causes errors when accessed from another shared library.


Full diff: https://github.com/llvm/llvm-project/pull/151114.diff

14 Files Affected:

  • (added) clang/include/clang/Driver/CudaInstallationDetector.h (+76)
  • (renamed) clang/include/clang/Driver/LazyDetector.h (+3-3)
  • (renamed) clang/include/clang/Driver/RocmInstallationDetector.h (+6-17)
  • (added) clang/include/clang/Driver/SyclInstallationDetector.h (+29)
  • (modified) clang/lib/Driver/ToolChains/AMDGPU.h (-1)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+1)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+1)
  • (modified) clang/lib/Driver/ToolChains/Cuda.h (+1-55)
  • (modified) clang/lib/Driver/ToolChains/Darwin.h (+4-4)
  • (modified) clang/lib/Driver/ToolChains/Gnu.h (+4-4)
  • (modified) clang/lib/Driver/ToolChains/HIPAMD.h (+1)
  • (modified) clang/lib/Driver/ToolChains/MSVC.h (+4-4)
  • (modified) clang/lib/Driver/ToolChains/MinGW.h (+3-2)
  • (modified) clang/lib/Driver/ToolChains/SYCL.h (+1-10)
diff --git a/clang/include/clang/Driver/CudaInstallationDetector.h b/clang/include/clang/Driver/CudaInstallationDetector.h
new file mode 100644
index 0000000000000..0fecbfe069ca4
--- /dev/null
+++ b/clang/include/clang/Driver/CudaInstallationDetector.h
@@ -0,0 +1,76 @@
+//===-- CudaInstallationDetector.h - Cuda Instalation Detector --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVER_CUDAINSTALLATIONDETECTOR_H
+#define LLVM_CLANG_DRIVER_CUDAINSTALLATIONDETECTOR_H
+
+#include "clang/Basic/Cuda.h"
+#include "clang/Driver/Driver.h"
+#include <bitset>
+
+namespace clang {
+namespace driver {
+
+/// A class to find a viable CUDA installation
+class CudaInstallationDetector {
+private:
+  const Driver &D;
+  bool IsValid = false;
+  CudaVersion Version = CudaVersion::UNKNOWN;
+  std::string InstallPath;
+  std::string BinPath;
+  std::string LibDevicePath;
+  std::string IncludePath;
+  llvm::StringMap<std::string> LibDeviceMap;
+
+  // CUDA architectures for which we have raised an error in
+  // CheckCudaVersionSupportsArch.
+  mutable std::bitset<(int)OffloadArch::LAST> ArchsWithBadVersion;
+
+public:
+  CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
+                           const llvm::opt::ArgList &Args);
+
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const;
+
+  /// Emit an error if Version does not support the given Arch.
+  ///
+  /// If either Version or Arch is unknown, does not emit an error.  Emits at
+  /// most one error per Arch.
+  void CheckCudaVersionSupportsArch(OffloadArch Arch) const;
+
+  /// Check whether we detected a valid Cuda install.
+  bool isValid() const { return IsValid; }
+  /// Print information about the detected CUDA installation.
+  void print(raw_ostream &OS) const;
+
+  /// Get the detected Cuda install's version.
+  CudaVersion version() const {
+    return Version == CudaVersion::NEW ? CudaVersion::PARTIALLY_SUPPORTED
+                                       : Version;
+  }
+  /// Get the detected Cuda installation path.
+  StringRef getInstallPath() const { return InstallPath; }
+  /// Get the detected path to Cuda's bin directory.
+  StringRef getBinPath() const { return BinPath; }
+  /// Get the detected Cuda Include path.
+  StringRef getIncludePath() const { return IncludePath; }
+  /// Get the detected Cuda device library path.
+  StringRef getLibDevicePath() const { return LibDevicePath; }
+  /// Get libdevice file for given architecture
+  std::string getLibDeviceFile(StringRef Gpu) const {
+    return LibDeviceMap.lookup(Gpu);
+  }
+  void WarnIfUnsupportedVersion() const;
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // LLVM_CLANG_DRIVER_CUDAINSTALLATIONDETECTOR_H
diff --git a/clang/lib/Driver/ToolChains/LazyDetector.h b/clang/include/clang/Driver/LazyDetector.h
similarity index 87%
rename from clang/lib/Driver/ToolChains/LazyDetector.h
rename to clang/include/clang/Driver/LazyDetector.h
index 813d00a87bb88..5bd1d0131bbba 100644
--- a/clang/lib/Driver/ToolChains/LazyDetector.h
+++ b/clang/include/clang/Driver/LazyDetector.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LAZYDETECTOR_H
-#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LAZYDETECTOR_H
+#ifndef LLVM_CLANG_DRIVER_LAZYDETECTOR_H
+#define LLVM_CLANG_DRIVER_LAZYDETECTOR_H
 
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
@@ -42,4 +42,4 @@ template <class T> class LazyDetector {
 
 } // end namespace clang
 
-#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LAZYDETECTOR_H
+#endif // LLVM_CLANG_DRIVER_LAZYDETECTOR_H
diff --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/include/clang/Driver/RocmInstallationDetector.h
similarity index 93%
rename from clang/lib/Driver/ToolChains/ROCm.h
rename to clang/include/clang/Driver/RocmInstallationDetector.h
index ebd544367a5a8..3a325a61ddbb9 100644
--- a/clang/lib/Driver/ToolChains/ROCm.h
+++ b/clang/include/clang/Driver/RocmInstallationDetector.h
@@ -1,4 +1,4 @@
-//===--- ROCm.h - ROCm installation detector --------------------*- C++ -*-===//
+//===-- RocmInstallationDetector.h - ROCm Instalation Detector --*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,21 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
-#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
+#ifndef LLVM_CLANG_DRIVER_ROCMINSTALLATIONDETECTOR_H
+#define LLVM_CLANG_DRIVER_ROCMINSTALLATIONDETECTOR_H
 
-#include "clang/Basic/Cuda.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Driver/CommonArgs.h"
 #include "clang/Driver/Driver.h"
-#include "clang/Driver/Options.h"
-#include "clang/Driver/SanitizerArgs.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Support/VersionTuple.h"
-#include "llvm/TargetParser/TargetParser.h"
-#include "llvm/TargetParser/Triple.h"
 
 namespace clang {
 namespace driver {
@@ -308,7 +297,7 @@ class RocmInstallationDetector {
   StringRef getHIPVersion() const { return DetectedVersion; }
 };
 
-} // end namespace driver
-} // end namespace clang
+} // namespace driver
+} // namespace clang
 
-#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
+#endif // LLVM_CLANG_DRIVER_ROCMINSTALLATIONDETECTOR_H
diff --git a/clang/include/clang/Driver/SyclInstallationDetector.h b/clang/include/clang/Driver/SyclInstallationDetector.h
new file mode 100644
index 0000000000000..6925ec24bcd29
--- /dev/null
+++ b/clang/include/clang/Driver/SyclInstallationDetector.h
@@ -0,0 +1,29 @@
+//===-- SyclInstallationDetector.h - SYCL Instalation Detector --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVER_SYCLINSTALLATIONDETECTOR_H
+#define LLVM_CLANG_DRIVER_SYCLINSTALLATIONDETECTOR_H
+
+#include "clang/Driver/Driver.h"
+
+namespace clang {
+namespace driver {
+
+class SYCLInstallationDetector {
+public:
+  SYCLInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
+                           const llvm::opt::ArgList &Args);
+
+  void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const;
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // LLVM_CLANG_DRIVER_SYCLINSTALLATIONDETECTOR_H
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index 513c77df786fe..e5d41e2401db6 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -10,7 +10,6 @@
 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
 
 #include "Gnu.h"
-#include "ROCm.h"
 #include "clang/Basic/TargetID.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/Tool.h"
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 9d882dbfd0c65..0a1406726a2c4 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -16,6 +16,7 @@
 #include "Arch/SystemZ.h"
 #include "Hexagon.h"
 #include "PS4CPU.h"
+#include "ToolChains/Cuda.h"
 #include "clang/Basic/CLWarnings.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/HeaderInclude.h"
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 3086c14fdaa4a..256c2667c15e6 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -23,6 +23,7 @@
 #include "Hexagon.h"
 #include "MSP430.h"
 #include "Solaris.h"
+#include "ToolChains/Cuda.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/Action.h"
diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h
index 259eda6ebcadf..8aeba53dd0030 100644
--- a/clang/lib/Driver/ToolChains/Cuda.h
+++ b/clang/lib/Driver/ToolChains/Cuda.h
@@ -11,6 +11,7 @@
 
 #include "clang/Basic/Cuda.h"
 #include "clang/Driver/Action.h"
+#include "clang/Driver/CudaInstallationDetector.h"
 #include "clang/Driver/Multilib.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
@@ -22,61 +23,6 @@
 
 namespace clang {
 namespace driver {
-
-/// A class to find a viable CUDA installation
-class CudaInstallationDetector {
-private:
-  const Driver &D;
-  bool IsValid = false;
-  CudaVersion Version = CudaVersion::UNKNOWN;
-  std::string InstallPath;
-  std::string BinPath;
-  std::string LibDevicePath;
-  std::string IncludePath;
-  llvm::StringMap<std::string> LibDeviceMap;
-
-  // CUDA architectures for which we have raised an error in
-  // CheckCudaVersionSupportsArch.
-  mutable std::bitset<(int)OffloadArch::LAST> ArchsWithBadVersion;
-
-public:
-  CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
-                           const llvm::opt::ArgList &Args);
-
-  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                          llvm::opt::ArgStringList &CC1Args) const;
-
-  /// Emit an error if Version does not support the given Arch.
-  ///
-  /// If either Version or Arch is unknown, does not emit an error.  Emits at
-  /// most one error per Arch.
-  void CheckCudaVersionSupportsArch(OffloadArch Arch) const;
-
-  /// Check whether we detected a valid Cuda install.
-  bool isValid() const { return IsValid; }
-  /// Print information about the detected CUDA installation.
-  void print(raw_ostream &OS) const;
-
-  /// Get the detected Cuda install's version.
-  CudaVersion version() const {
-    return Version == CudaVersion::NEW ? CudaVersion::PARTIALLY_SUPPORTED
-                                       : Version;
-  }
-  /// Get the detected Cuda installation path.
-  StringRef getInstallPath() const { return InstallPath; }
-  /// Get the detected path to Cuda's bin directory.
-  StringRef getBinPath() const { return BinPath; }
-  /// Get the detected Cuda Include path.
-  StringRef getIncludePath() const { return IncludePath; }
-  /// Get the detected Cuda device library path.
-  StringRef getLibDevicePath() const { return LibDevicePath; }
-  /// Get libdevice file for given architecture
-  std::string getLibDeviceFile(StringRef Gpu) const {
-    return LibDeviceMap.lookup(Gpu);
-  }
-  void WarnIfUnsupportedVersion() const;
-};
-
 namespace tools {
 namespace NVPTX {
 
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index b38bfe6d1e554..d1cfb6f4a5bf7 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -9,12 +9,12 @@
 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
 
-#include "Cuda.h"
-#include "LazyDetector.h"
-#include "ROCm.h"
-#include "SYCL.h"
 #include "clang/Basic/DarwinSDKInfo.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Driver/CudaInstallationDetector.h"
+#include "clang/Driver/LazyDetector.h"
+#include "clang/Driver/RocmInstallationDetector.h"
+#include "clang/Driver/SyclInstallationDetector.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "clang/Driver/XRayArgs.h"
diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h
index 3b8df71bbf9d3..4c42a5e535d56 100644
--- a/clang/lib/Driver/ToolChains/Gnu.h
+++ b/clang/lib/Driver/ToolChains/Gnu.h
@@ -9,10 +9,10 @@
 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H
 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H
 
-#include "Cuda.h"
-#include "LazyDetector.h"
-#include "ROCm.h"
-#include "SYCL.h"
+#include "clang/Driver/CudaInstallationDetector.h"
+#include "clang/Driver/LazyDetector.h"
+#include "clang/Driver/RocmInstallationDetector.h"
+#include "clang/Driver/SyclInstallationDetector.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include <set>
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.h b/clang/lib/Driver/ToolChains/HIPAMD.h
index bcc3ebb0f33de..30fc01a2f8e40 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.h
+++ b/clang/lib/Driver/ToolChains/HIPAMD.h
@@ -10,6 +10,7 @@
 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HIPAMD_H
 
 #include "AMDGPU.h"
+#include "clang/Driver/SyclInstallationDetector.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 
diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h
index b35390c52a049..5c17edce087c7 100644
--- a/clang/lib/Driver/ToolChains/MSVC.h
+++ b/clang/lib/Driver/ToolChains/MSVC.h
@@ -9,11 +9,11 @@
 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H
 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H
 
-#include "AMDGPU.h"
-#include "Cuda.h"
-#include "LazyDetector.h"
-#include "SYCL.h"
 #include "clang/Driver/Compilation.h"
+#include "clang/Driver/CudaInstallationDetector.h"
+#include "clang/Driver/LazyDetector.h"
+#include "clang/Driver/RocmInstallationDetector.h"
+#include "clang/Driver/SyclInstallationDetector.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/Frontend/Debug/Options.h"
diff --git a/clang/lib/Driver/ToolChains/MinGW.h b/clang/lib/Driver/ToolChains/MinGW.h
index a9963d8d06c29..1730da48cd434 100644
--- a/clang/lib/Driver/ToolChains/MinGW.h
+++ b/clang/lib/Driver/ToolChains/MinGW.h
@@ -11,8 +11,9 @@
 
 #include "Cuda.h"
 #include "Gnu.h"
-#include "LazyDetector.h"
-#include "ROCm.h"
+#include "clang/Driver/CudaInstallationDetector.h"
+#include "clang/Driver/LazyDetector.h"
+#include "clang/Driver/RocmInstallationDetector.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/Support/ErrorOr.h"
diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h
index 2a8b4eca9e9f8..be4ba47cb3d52 100644
--- a/clang/lib/Driver/ToolChains/SYCL.h
+++ b/clang/lib/Driver/ToolChains/SYCL.h
@@ -9,21 +9,12 @@
 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SYCL_H
 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SYCL_H
 
+#include "clang/Driver/SyclInstallationDetector.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 
 namespace clang {
 namespace driver {
-
-class SYCLInstallationDetector {
-public:
-  SYCLInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
-                           const llvm::opt::ArgList &Args);
-
-  void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                          llvm::opt::ArgStringList &CC1Args) const;
-};
-
 namespace toolchains {
 
 class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain {

@jchlanda jchlanda force-pushed the jakub/installation_detectors branch from 828139e to 3afbf0e Compare July 29, 2025 09:54
@jchlanda
Copy link
Contributor Author

This patch serves the same purpose as: #149294, which is to try and simplify how we use clang as a tool when offloading to cuda/hip/sycl.

This patch moves `LazyDetector` and target specific (Cuda, Hip, SYCL)
installation detectors to clang's include directory. It was problematic
for downstream to use headers from clang's lib dir. The use of lib
headers could lead to subtle errors, as some of the symbols there are
annotated with `LLVM_LIBRARY_VISIBILITY`. For instance
[`ROCMToolChain::getCommonDeviceLibNames`](https://github.com/jchlanda/llvm-project/blob/jakub/installation_detectors/clang/lib/Driver/ToolChains/AMDGPU.h#L147)
is c++ public, but because of the annotation it ends up as ELF hidden
symbol, which causes errors when accessed from another shared library.
Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems straightforward enough.

@jchlanda jchlanda merged commit dba558b into llvm:main Jul 30, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AMDGPU clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants