Skip to content

Commit 6029b46

Browse files
committed
[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
1 parent 4289356 commit 6029b46

File tree

7 files changed

+57
-1
lines changed

7 files changed

+57
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"directory": "DIR",
4+
"command": "CLANG -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -c DIR/tu.c -o DIR/tu.o",
5+
"file": "DIR/tu.c"
6+
}
7+
]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
echo "/custom/compiler/resources"

clang/test/ClangScanDeps/Inputs/resource_directory/mod.h

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module mod { header "mod.h" }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "mod.h"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// REQUIRES: shell
2+
3+
// RUN: rm -rf %t && mkdir %t
4+
// RUN: cp %S/Inputs/resource_directory/* %t
5+
6+
// Deduce the resource directory from the compiler path.
7+
//
8+
// RUN: sed -e "s|CLANG|/our/custom/bin/clang|g" -e "s|DIR|%/t|g" \
9+
// RUN: %S/Inputs/resource_directory/cdb.json.template > %t/cdb_path.json
10+
// RUN: clang-scan-deps -compilation-database %t/cdb_path.json --format experimental-full \
11+
// RUN: --resource-dir-recipe modify-compiler-path > %t/result_path.json
12+
// RUN: cat %t/result_path.json | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-PATH
13+
// CHECK-PATH: "-resource-dir"
14+
// CHECK-PATH-NEXT: "/our/custom/lib{{.*}}"
15+
16+
// Run the compiler and ask it for the resource directory.
17+
//
18+
// RUN: chmod +x %t/compiler
19+
// RUN: sed -e "s|CLANG|%/t/compiler|g" -e "s|DIR|%/t|g" \
20+
// RUN: %S/Inputs/resource_directory/cdb.json.template > %t/cdb_invocation.json
21+
// RUN: clang-scan-deps -compilation-database %t/cdb_invocation.json --format experimental-full \
22+
// RUN: --resource-dir-recipe invoke-compiler > %t/result_invocation.json
23+
// RUN: cat %t/result_invocation.json | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-INVOCATION
24+
// CHECK-INVOCATION: "-resource-dir"
25+
// CHECK-INVOCATION-NEXT: "/custom/compiler/resources"

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,25 @@ llvm::cl::opt<std::string> ModuleName(
204204
llvm::cl::desc("the module of which the dependencies are to be computed"),
205205
llvm::cl::cat(DependencyScannerCategory));
206206

207+
enum ResourceDirRecipeKind {
208+
RDRK_ModifyCompilerPath,
209+
RDRK_InvokeCompiler,
210+
};
211+
212+
static llvm::cl::opt<ResourceDirRecipeKind> ResourceDirRecipe(
213+
"resource-dir-recipe",
214+
llvm::cl::desc("How to produce missing '-resource-dir' argument"),
215+
llvm::cl::values(
216+
clEnumValN(RDRK_ModifyCompilerPath, "modify-compiler-path",
217+
"Construct the resource directory from the compiler path in "
218+
"the compilation database. This assumes it's part of the "
219+
"same toolchain as this clang-scan-deps. (default)"),
220+
clEnumValN(RDRK_InvokeCompiler, "invoke-compiler",
221+
"Invoke the compiler with '-print-resource-dir' and use the "
222+
"reported path as the resource directory. (deprecated)")),
223+
llvm::cl::init(RDRK_ModifyCompilerPath),
224+
llvm::cl::cat(DependencyScannerCategory));
225+
207226
llvm::cl::opt<bool> Verbose("v", llvm::cl::Optional,
208227
llvm::cl::desc("Use verbose output."),
209228
llvm::cl::init(false),
@@ -495,7 +514,7 @@ int main(int argc, const char **argv) {
495514
AdjustedArgs.push_back("/clang:" + LastO);
496515
}
497516

498-
if (!HasResourceDir) {
517+
if (!HasResourceDir && ResourceDirRecipe == RDRK_InvokeCompiler) {
499518
StringRef ResourceDir =
500519
ResourceDirCache.findResourceDir(Args, ClangCLMode);
501520
if (!ResourceDir.empty()) {

0 commit comments

Comments
 (0)