jansvoboda11 created this revision.
jansvoboda11 added reviewers: Bigcheese, dexonsmith, arphaman, kousikk.
jansvoboda11 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

After [[libclang][deps] Accept only driver invocations, don't modify 
them](https://github.com/apple/llvm-project/pull/3168) landed downstream, the 
libclang dependency scanner stopped deducing the resource directory based on 
the compiler executable path (in `Driver::Driver` called by 
`createInvocationFromCommandLine` called by `getFileDependencies`) and started 
using the current executable path (injected in `ClangTool::run`). However, the 
current executable is potentially a build system located outside the compiler 
toolchain that loaded the libclang shared library.

This patch adds an option to `ClangTool` to disable the deduction of the 
resource directory. This means the dependency scanner (both `clang-scan-deps` 
and libclang) now base the deduction on the compiler executable provided as 
part of the compilation command-line (in `Driver::Driver` called by 
`ToolInvocation::run` called by `ClangTool::run`).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108366

Files:
  clang/include/clang/Tooling/Tooling.h
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/lib/Tooling/Tooling.cpp
  clang/test/ClangScanDeps/Inputs/resource_directory/cdb_tu.json
  clang/test/ClangScanDeps/Inputs/resource_directory/mod.h
  clang/test/ClangScanDeps/Inputs/resource_directory/module.modulemap
  clang/test/ClangScanDeps/Inputs/resource_directory/tu.c
  clang/test/ClangScanDeps/resource_directory.c

Index: clang/test/ClangScanDeps/resource_directory.c
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/resource_directory.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: cp %S/Inputs/resource_directory/* %t
+// RUN: sed -e "s|CLANG|/our/custom/bin/clang|g" -e "s|DIR|%/t|g" %S/Inputs/resource_directory/cdb_tu.json > %t/cdb.json
+
+// RUN: clang-scan-deps -compilation-database %t/cdb.json --format experimental-full | FileCheck %s
+
+// CHECK:      "-resource-dir"
+// CHECK-NEXT: "/our/custom/{{.*}}"
Index: clang/test/ClangScanDeps/Inputs/resource_directory/tu.c
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/resource_directory/tu.c
@@ -0,0 +1,3 @@
+// tu.c
+
+#include "mod.h"
Index: clang/test/ClangScanDeps/Inputs/resource_directory/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/resource_directory/module.modulemap
@@ -0,0 +1 @@
+module mod { header "mod.h" }
Index: clang/test/ClangScanDeps/Inputs/resource_directory/mod.h
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/resource_directory/mod.h
@@ -0,0 +1 @@
+// mod.h
Index: clang/test/ClangScanDeps/Inputs/resource_directory/cdb_tu.json
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/resource_directory/cdb_tu.json
@@ -0,0 +1,7 @@
+[
+  {
+    "directory": "DIR",
+    "command": "CLANG -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -c DIR/tu.c -o DIR/tu.o",
+    "file": "DIR/tu.c"
+  }
+]
Index: clang/lib/Tooling/Tooling.cpp
===================================================================
--- clang/lib/Tooling/Tooling.cpp
+++ clang/lib/Tooling/Tooling.cpp
@@ -553,15 +553,17 @@
         CommandLine = ArgsAdjuster(CommandLine, CompileCommand.Filename);
       assert(!CommandLine.empty());
 
-      // Add the resource dir based on the binary of this tool. argv[0] in the
-      // compilation database may refer to a different compiler and we want to
-      // pick up the very same standard library that compiler is using. The
-      // builtin headers in the resource dir need to match the exact clang
-      // version the tool is using.
-      // 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);
+      if (InjectResourceDir) {
+        // Add the resource dir based on the binary of this tool. argv[0] in the
+        // compilation database may refer to a different compiler and we want to
+        // pick up the very same standard library that compiler is using. The
+        // builtin headers in the resource dir need to match the exact clang
+        // version the tool is using.
+        // 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);
+      }
 
       // FIXME: We need a callback mechanism for the tool writer to output a
       // customized message for each file.
@@ -625,6 +627,10 @@
   this->RestoreCWD = RestoreCWD;
 }
 
+void ClangTool::setInjectResourceDir(bool InjectResourceDir) {
+  this->InjectResourceDir = InjectResourceDir;
+}
+
 void ClangTool::setPrintErrorMessage(bool PrintErrorMessage) {
   this->PrintErrorMessage = PrintErrorMessage;
 }
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -316,6 +316,10 @@
     tooling::ClangTool Tool(CDB, Input, PCHContainerOps, RealFS, Files);
     Tool.clearArgumentsAdjusters();
     Tool.setRestoreWorkingDir(false);
+    // A resource directory deduced from the current executable path is most
+    // likely not correct (e.g. when done from inside a shared library). Let the
+    // driver deduce it from the absolute compiler path in `CDB`.
+    Tool.setInjectResourceDir(false);
     Tool.setPrintErrorMessage(false);
     Tool.setDiagnosticConsumer(&DC);
     DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS,
Index: clang/include/clang/Tooling/Tooling.h
===================================================================
--- clang/include/clang/Tooling/Tooling.h
+++ clang/include/clang/Tooling/Tooling.h
@@ -360,6 +360,10 @@
   /// turn this off when running on multiple threads to avoid the raciness.
   void setRestoreWorkingDir(bool RestoreCWD);
 
+  /// Sets whether the resource directory of the current binary should be
+  /// injected into the command lines.
+  void setInjectResourceDir(bool InjectResourceDir);
+
   /// Sets whether an error message should be printed out if an action fails. By
   /// default, if an action fails, a message is printed out to stderr.
   void setPrintErrorMessage(bool PrintErrorMessage);
@@ -390,6 +394,7 @@
   DiagnosticConsumer *DiagConsumer = nullptr;
 
   bool RestoreCWD = true;
+  bool InjectResourceDir = true;
   bool PrintErrorMessage = true;
 };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to