Skip to content

Conversation

@simpal01
Copy link
Contributor

@simpal01 simpal01 commented Oct 27, 2025

The current baremetal driver implementation does not have a way to derive the target-triple-level include path within the sysroot.

This feature is especially useful in setups where header paths deviate from the default bare-metal assumptions. For example, when headers are shared across target triples, it becomes necessary to organise them under target-triple-specific directories to ensure correct resolution..

…lution in Baremetal Driver

The current baremetal driver implementation does not have a way to
derive the target-triple-level include path within the sysroot.

This feature is especially useful in setups where header paths
deviate from the default bare-metal assumptions. For example,
when headers are shared across target triples, it becomes necessary
to organize them under target-triple-specific directories to ensure
correct resolution..
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Oct 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2025

@llvm/pr-subscribers-clang

Author: Simi Pallipurath (simpal01)

Changes

The current baremetal driver implementation does not have a way to derive the target-triple-level include path within the sysroot.

This feature is especially useful in setups where header paths deviate from the default bare-metal assumptions. For example, when headers are shared across target triples, it becomes necessary to organise them under target-triple-specific directories to ensure correct resolution..


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

1 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/BareMetal.cpp (+14-1)
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 9b7f58c392885..d048f228f4572 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -408,6 +408,8 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
+  const Driver &D = getDriver();
+
   if (std::optional<std::string> Path = getStdlibIncludePath())
     addSystemInclude(DriverArgs, CC1Args, *Path);
 
@@ -418,6 +420,13 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
       llvm::sys::path::append(Dir, M.includeSuffix());
       llvm::sys::path::append(Dir, "include");
       addSystemInclude(DriverArgs, CC1Args, Dir.str());
+
+      Dir = SysRootDir;
+      llvm::sys::path::append(Dir, getTripleString());
+      if (D.getVFS().exists(Dir)) {
+        llvm::sys::path::append(Dir, "include");
+        addSystemInclude(DriverArgs, CC1Args, Dir.str());
+      }
     }
   }
 }
@@ -498,9 +507,13 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
         addSystemInclude(DriverArgs, CC1Args, TargetDir.str());
         break;
       }
-      // Add generic path if nothing else succeeded so far.
+      // Add generic paths if nothing else succeeded so far.
       llvm::sys::path::append(Dir, "include", "c++", "v1");
       addSystemInclude(DriverArgs, CC1Args, Dir.str());
+      Dir = SysRootDir;
+      llvm::sys::path::append(Dir, Target, "include", "c++", "v1");
+      if (D.getVFS().exists(Dir))
+        addSystemInclude(DriverArgs, CC1Args, Dir.str());
       break;
     }
     case ToolChain::CST_Libstdcxx: {

@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2025

@llvm/pr-subscribers-clang-driver

Author: Simi Pallipurath (simpal01)

Changes

The current baremetal driver implementation does not have a way to derive the target-triple-level include path within the sysroot.

This feature is especially useful in setups where header paths deviate from the default bare-metal assumptions. For example, when headers are shared across target triples, it becomes necessary to organise them under target-triple-specific directories to ensure correct resolution..


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

1 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/BareMetal.cpp (+14-1)
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 9b7f58c392885..d048f228f4572 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -408,6 +408,8 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
+  const Driver &D = getDriver();
+
   if (std::optional<std::string> Path = getStdlibIncludePath())
     addSystemInclude(DriverArgs, CC1Args, *Path);
 
@@ -418,6 +420,13 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
       llvm::sys::path::append(Dir, M.includeSuffix());
       llvm::sys::path::append(Dir, "include");
       addSystemInclude(DriverArgs, CC1Args, Dir.str());
+
+      Dir = SysRootDir;
+      llvm::sys::path::append(Dir, getTripleString());
+      if (D.getVFS().exists(Dir)) {
+        llvm::sys::path::append(Dir, "include");
+        addSystemInclude(DriverArgs, CC1Args, Dir.str());
+      }
     }
   }
 }
@@ -498,9 +507,13 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
         addSystemInclude(DriverArgs, CC1Args, TargetDir.str());
         break;
       }
-      // Add generic path if nothing else succeeded so far.
+      // Add generic paths if nothing else succeeded so far.
       llvm::sys::path::append(Dir, "include", "c++", "v1");
       addSystemInclude(DriverArgs, CC1Args, Dir.str());
+      Dir = SysRootDir;
+      llvm::sys::path::append(Dir, Target, "include", "c++", "v1");
+      if (D.getVFS().exists(Dir))
+        addSystemInclude(DriverArgs, CC1Args, Dir.str());
       break;
     }
     case ToolChain::CST_Libstdcxx: {

@simpal01 simpal01 requested a review from petrhosek October 28, 2025 10:56
@simpal01
Copy link
Contributor Author

@petrhosek Please review this patch. This is one of the solutions provided to support Target Triple–specific include paths in the bare-metal driver via hard coded path.

and another solution is via multilib.yaml which is added here #146651. This is more favourable both within the team and based on the feedback received in the RFC https://discourse.llvm.org/t/rfc-support-target-triple-specific-include-paths-derived-from-sysroot-via-multilib-yaml-or-driver-logic/86925/6

Comment on lines +513 to +516
Dir = SysRootDir;
llvm::sys::path::append(Dir, Target, "include", "c++", "v1");
if (D.getVFS().exists(Dir))
addSystemInclude(DriverArgs, CC1Args, Dir.str());
Copy link
Member

Choose a reason for hiding this comment

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

Since this logic is unrelated to multilibs, this should be done inside AddCXXIncludePath.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AddCXXIncludePath(Path) is currently passed a path derived from a top-level include directory that isn’t rooted in the active --sysroot. What this PR is actually aiming for is to derive the target-triple-level include path within the sysroot itself. But here the sysroot computation happens after the AddCXXIncludePath(Path) call.

Copy link
Member

Choose a reason for hiding this comment

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

I see, I still think we need to move this logic outside of the multilib loop to avoid adding the include directory multiple times. I think this entire loop might need to be restructured since I don't think it's actually correct, so it might be probably easiest for now to just move the new logic outside.

Comment on lines 424 to 428
Dir = SysRootDir;
llvm::sys::path::append(Dir, getTripleString());
if (D.getVFS().exists(Dir)) {
llvm::sys::path::append(Dir, "include");
addSystemInclude(DriverArgs, CC1Args, Dir.str());
Copy link
Member

Choose a reason for hiding this comment

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

This is unrelated to multilibs so should be done outside of the loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@petrhosek
Copy link
Member

Would it be possible to also add a test case in clang/test/Driver/baremetal.cpp?

@simpal01 simpal01 force-pushed the add-target-level-include-paths branch from ed2e69d to c664b02 Compare November 17, 2025 20:58
@github-actions
Copy link

🐧 Linux x64 Test Results

  • 111272 tests passed
  • 4418 tests skipped

@simpal01
Copy link
Contributor Author

support Target Triple–specific include paths in the bare-metal driver

In this patch, the target-triple–specific header path is added only if the corresponding directory exists on the host system. Since the LLVM test environment doesn’t include such a layout, it’s not possible to test this behaviour purely within clang/test/Driver using the in-tree setup.

I did verify it locally using the Arm Toolchain for Embedded (ATFE), which provides exactly this header layout, and confirmed that the driver picks up the correct triple-specific include directory.

Separately, I have an alternate patch that adds support for target-triple-specific include paths in the bare-metal driver via multilib.yaml configuration, #146651 . That approach is what our team prefers, and in that case I was able to include appropriate driver tests, as the include paths are conditionally added based on entries available in the multilib.yaml file. Would you like to take a look at that patch too?

llvm::sys::path::append(Dir, "include");
addSystemInclude(DriverArgs, CC1Args, Dir.str());
}
SmallString<128> Dir = SysRootDir;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I'd use copy constructor over assignment operator for consistency with the existing code.

Suggested change
SmallString<128> Dir = SysRootDir;
SmallString<128> Dir(SysRootDir);

@petrhosek
Copy link
Member

support Target Triple–specific include paths in the bare-metal driver

In this patch, the target-triple–specific header path is added only if the corresponding directory exists on the host system. Since the LLVM test environment doesn’t include such a layout, it’s not possible to test this behaviour purely within clang/test/Driver using the in-tree setup.

The way we typically handle that is by constructing the artificial directory layout in https://github.com/llvm/llvm-project/tree/main/clang/test/Driver/Inputs for testing, see for example https://github.com/llvm/llvm-project/tree/main/clang/test/Driver/Inputs/basic_baremetal_tree.

Separately, I have an alternate patch that adds support for target-triple-specific include paths in the bare-metal driver via multilib.yaml configuration, #146651 . That approach is what our team prefers, and in that case I was able to include appropriate driver tests, as the include paths are conditionally added based on entries available in the multilib.yaml file. Would you like to take a look at that patch too?

Sure, but I'd like to merge this change as well since we have customers who don't use multilib.yaml and asked for this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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