Clang tooling sensitivity to tool name

Hi,

I have a downstream clang tool that traverses the AST and prints some stuff.

It supports 2 modes: single file or a build directory (compile_commands.json). I’m struggling to clang to find the system headers in both cases and with both a local build of LLVM & the ubuntu package.

Eventually I realized that clang is sensitive to the tool name. So the fix for the single file was to set the clang binary:

clang::tooling::runToolOnCodeWithArgs(action, code, args, "input.cpp", CLANG_EXECUTABLE);

This solves the issue for single file. Then I have some cmake hackery to set CLANG_EXECUTABLE:

find_package(LLVM REQUIRED CONFIG)
find_package(Clang REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using ClangConfig.cmake in: ${Clang_DIR}")

list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CLANG_CMAKE_DIR}")
include(AddLLVM)
include(AddClang)

if (NOT CMAKE_CXX_COMPILER MATCHES "clang")
  set(CMAKE_CXX_COMPILER "${CLANG_CMAKE_DIR}/../../../bin/clang++")
endif()

target_compile_definitions(tool PUBLIC "-DCLANG_EXECUTABLE=\"${CMAKE_CXX_COMPILER}\"")

But the build directory version doesn’t seem to pickup the system header files even if arg[0] of all commands has the path to clang++:

  auto compile_dbase = clang::tooling::CompilationDatabase::loadFromDirectory(
      build_dir, error_message);

  std::vector<std::string> files;
  for (const auto &compile_command : compile_dbase->getAllCompileCommands()) {
    // these don't help; still can't find stddef.h
    compile_command.CommandLine.push_back("-resource-dir");
    compile_command.CommandLine.push_back("/home/nuno/llvm/build/lib/clang/20");
    compile_command.CommandLine.push_back("-internal-isystem");
    compile_command.CommandLine.push_back("/home/nuno/llvm/build/lib/clang/20/include");
    files.emplace_back(compile_command.Filename);
  }

  clang::tooling::ClangTool Tool(*compile_dbase, files);
  Tool.run(&factory);

Am I missing some shortcut to make clang find the system headers consistently?

Thanks,
Nuno

Partially replying to myself, this hack fixes the problem:

diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index 88b7349ce8fe..e09b28cbd321 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -609,7 +609,7 @@ int ClangTool::run(ToolAction *Action) {
       // FIXME: On linux, GetMainExecutable is independent of the value of the
       // first argument, thus allowing ClangTool and runToolOnCode to just
       // pass in made-up names here. Make sure this works on other platforms.
-      injectResourceDir(CommandLine, "clang_tool", &StaticSymbol);
+      //injectResourceDir(CommandLine, "clang_tool", &StaticSymbol);

       // FIXME: We need a callback mechanism for the tool writer to output a
       // customized message for each file.

It seems the code needs some love to handle linux better. Not sure what’s the best way forward though?