[clang] b8b14b6 - [clang][deps] Make resource directory deduction configurable

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 21 05:06:57 PDT 2021


Author: Jan Svoboda
Date: 2021-10-21T14:06:52+02:00
New Revision: b8b14b682c339c9ab85360d24ba9b888d52fdfbb

URL: https://github.com/llvm/llvm-project/commit/b8b14b682c339c9ab85360d24ba9b888d52fdfbb
DIFF: https://github.com/llvm/llvm-project/commit/b8b14b682c339c9ab85360d24ba9b888d52fdfbb.diff

LOG: [clang][deps] Make resource directory deduction configurable

The `clang-scan-deps` CLI tool invokes the compiler with `-print-resource-dir` in case the `-resource-dir` argument is missing from the compilation command line. This is to enable running the tool on compilation databases that use compiler from a different toolchain than `clang-scan-deps` itself. While this doesn't make sense when scanning modular builds (due to the `-cc1` arguments the tool generates), the tool can can be used to efficiently scan for file dependencies of non-modular builds too.

This patch stops deducing the resource directory by invoking the compiler by default. This mode can still be enabled by invoking `clang-scan-deps` with `--resource-dir-recipe invoke-compiler`. The new default is `--resource-dir-recipe modify-compiler-path` which relies on the resource directory deduction taking place in `Driver::Driver` which is based on the compiler path. This makes the default more aligned with the intended usage of the tool while still allowing it to serve other use-cases.

Note that this functionality was also influenced by D108979, where the dependency scanner stopped going through `ClangTool::run`. The function tried to deduce the resource directory based on the current executable path, which might not be what the users expect when invoked from within a shared library.

Depends on D108979.

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D108366

Added: 
    clang/test/ClangScanDeps/Inputs/resource_directory/cdb.json.template
    clang/test/ClangScanDeps/Inputs/resource_directory/compiler
    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

Modified: 
    clang/tools/clang-scan-deps/ClangScanDeps.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/ClangScanDeps/Inputs/resource_directory/cdb.json.template b/clang/test/ClangScanDeps/Inputs/resource_directory/cdb.json.template
new file mode 100644
index 0000000000000..b9f413db96af5
--- /dev/null
+++ b/clang/test/ClangScanDeps/Inputs/resource_directory/cdb.json.template
@@ -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"
+  }
+]

diff  --git a/clang/test/ClangScanDeps/Inputs/resource_directory/compiler b/clang/test/ClangScanDeps/Inputs/resource_directory/compiler
new file mode 100755
index 0000000000000..edeb2a2fd0009
--- /dev/null
+++ b/clang/test/ClangScanDeps/Inputs/resource_directory/compiler
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "/custom/compiler/resources"

diff  --git a/clang/test/ClangScanDeps/Inputs/resource_directory/mod.h b/clang/test/ClangScanDeps/Inputs/resource_directory/mod.h
new file mode 100644
index 0000000000000..e69de29bb2d1d

diff  --git a/clang/test/ClangScanDeps/Inputs/resource_directory/module.modulemap b/clang/test/ClangScanDeps/Inputs/resource_directory/module.modulemap
new file mode 100644
index 0000000000000..03cbffaeb1fb5
--- /dev/null
+++ b/clang/test/ClangScanDeps/Inputs/resource_directory/module.modulemap
@@ -0,0 +1 @@
+module mod { header "mod.h" }

diff  --git a/clang/test/ClangScanDeps/Inputs/resource_directory/tu.c b/clang/test/ClangScanDeps/Inputs/resource_directory/tu.c
new file mode 100644
index 0000000000000..01f145835c765
--- /dev/null
+++ b/clang/test/ClangScanDeps/Inputs/resource_directory/tu.c
@@ -0,0 +1 @@
+#include "mod.h"

diff  --git a/clang/test/ClangScanDeps/resource_directory.c b/clang/test/ClangScanDeps/resource_directory.c
new file mode 100644
index 0000000000000..6912aa9a19952
--- /dev/null
+++ b/clang/test/ClangScanDeps/resource_directory.c
@@ -0,0 +1,25 @@
+// REQUIRES: shell
+
+// RUN: rm -rf %t && mkdir %t
+// RUN: cp %S/Inputs/resource_directory/* %t
+
+// Deduce the resource directory from the compiler path.
+//
+// RUN: sed -e "s|CLANG|/our/custom/bin/clang|g" -e "s|DIR|%/t|g" \
+// RUN:   %S/Inputs/resource_directory/cdb.json.template > %t/cdb_path.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_path.json --format experimental-full \
+// RUN:   --resource-dir-recipe modify-compiler-path > %t/result_path.json
+// RUN: cat %t/result_path.json | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-PATH
+// CHECK-PATH:      "-resource-dir"
+// CHECK-PATH-NEXT: "/our/custom/lib{{.*}}"
+
+// Run the compiler and ask it for the resource directory.
+//
+// RUN: chmod +x %t/compiler
+// RUN: sed -e "s|CLANG|%/t/compiler|g" -e "s|DIR|%/t|g" \
+// RUN:   %S/Inputs/resource_directory/cdb.json.template > %t/cdb_invocation.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_invocation.json --format experimental-full \
+// RUN:   --resource-dir-recipe invoke-compiler > %t/result_invocation.json
+// RUN: cat %t/result_invocation.json | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-INVOCATION
+// CHECK-INVOCATION:      "-resource-dir"
+// CHECK-INVOCATION-NEXT: "/custom/compiler/resources"

diff  --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 450a4efead099..86e95a75e429f 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -204,6 +204,25 @@ llvm::cl::opt<std::string> ModuleName(
     llvm::cl::desc("the module of which the dependencies are to be computed"),
     llvm::cl::cat(DependencyScannerCategory));
 
+enum ResourceDirRecipeKind {
+  RDRK_ModifyCompilerPath,
+  RDRK_InvokeCompiler,
+};
+
+static llvm::cl::opt<ResourceDirRecipeKind> ResourceDirRecipe(
+    "resource-dir-recipe",
+    llvm::cl::desc("How to produce missing '-resource-dir' argument"),
+    llvm::cl::values(
+        clEnumValN(RDRK_ModifyCompilerPath, "modify-compiler-path",
+                   "Construct the resource directory from the compiler path in "
+                   "the compilation database. This assumes it's part of the "
+                   "same toolchain as this clang-scan-deps. (default)"),
+        clEnumValN(RDRK_InvokeCompiler, "invoke-compiler",
+                   "Invoke the compiler with '-print-resource-dir' and use the "
+                   "reported path as the resource directory. (deprecated)")),
+    llvm::cl::init(RDRK_ModifyCompilerPath),
+    llvm::cl::cat(DependencyScannerCategory));
+
 llvm::cl::opt<bool> Verbose("v", llvm::cl::Optional,
                             llvm::cl::desc("Use verbose output."),
                             llvm::cl::init(false),
@@ -495,7 +514,7 @@ int main(int argc, const char **argv) {
           AdjustedArgs.push_back("/clang:" + LastO);
         }
 
-        if (!HasResourceDir) {
+        if (!HasResourceDir && ResourceDirRecipe == RDRK_InvokeCompiler) {
           StringRef ResourceDir =
               ResourceDirCache.findResourceDir(Args, ClangCLMode);
           if (!ResourceDir.empty()) {


        


More information about the cfe-commits mailing list