Skip to content

Commit 90e33e2

Browse files
authored
[clang-scan-deps] Expand response files before the argument adjuster (#89950)
Previously, since response (.rsp) files weren't expanded at the very beginning of clang-scan-deps, we only parsed the command-line as provided in the Clang .cdb file. Unfortunately, when using Unreal Engine, arguments are always generated in a .rsp file (ie. `/path/to/clang-cl.exe @/path/to/filename_args.rsp`). After this patch, `/Fo` can be parsed and added to the final command-line. Without this option, the make targets that are emitted are made up from the input file name alone. We have some cases where the same input in the project generates several output files, so we end up with duplicate make targets in the scan-deps emitted dependency file.
1 parent 56c5ca8 commit 90e33e2

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
10301030

10311031
// If user provided -o, that is the dependency target, except
10321032
// when we are only generating a dependency file.
1033-
Arg *OutputOpt = Args.getLastArg(options::OPT_o);
1033+
Arg *OutputOpt = Args.getLastArg(options::OPT_o, options::OPT__SLASH_Fo);
10341034
if (OutputOpt && Output.getType() != types::TY_Dependencies) {
10351035
DepTarget = OutputOpt->getValue();
10361036
} else {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Check that the scanner can adjust arguments by reading .rsp files in advance.
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
6+
// First run the tests with a .cdb
7+
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
8+
// RUN: sed -e "s|DIR|%/t|g" %t/args_nested.template > %t/args_nested.rsp
9+
10+
// RUN: cp %t/args_compilation.rsp %t/args.rsp
11+
// RUN: clang-scan-deps --compilation-database %t/cdb.json > %t/deps.json
12+
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
13+
14+
// RUN: cp %t/args_preprocess.rsp %t/args.rsp
15+
// RUN: clang-scan-deps --compilation-database %t/cdb.json > %t/deps.json
16+
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
17+
18+
19+
// Now run the tests again with a in-place compilation database
20+
// RUN: cd %t
21+
22+
// RUN: cp args_compilation.rsp args.rsp
23+
// RUN: clang-scan-deps -o deps.json -- %clang_cl @args.rsp
24+
// RUN: cat deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
25+
26+
// RUN: cp args_preprocess.rsp args.rsp
27+
// RUN: clang-scan-deps -o deps.json -- %clang_cl @args.rsp
28+
// RUN: cat deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
29+
30+
// Here we ensure that we got a qualified .obj with its full path, since that's what we're passing with /Fo
31+
// CHECK: [[PREFIX]]/tu.obj:
32+
33+
//--- cdb.json.template
34+
[{
35+
"file": "DIR/tu.cpp",
36+
"directory": "DIR",
37+
"command": "clang-cl @DIR/args.rsp"
38+
}]
39+
40+
//--- args_compilation.rsp
41+
@args_nested.rsp
42+
/c
43+
44+
//--- args_preprocess.rsp
45+
@args_nested.rsp
46+
/E
47+
48+
//--- args_nested.template
49+
/I include
50+
tu.cpp
51+
/FoDIR/tu.obj
52+
53+
//--- include/header.h
54+
55+
//--- tu.cpp
56+
#include "header.h"

clang/test/Driver/cl-options.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,9 +740,10 @@
740740
// NOCLANG-SAME: "-vectorize-slp"
741741
// NOCLANG-NOT: "--dependent-lib=msvcrt"
742742

743-
// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s
743+
// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep /c /Fo%/t/cl-options.obj -### -- %s 2>&1 | FileCheck -DPREFIX=%/t -check-prefix=CLANG %s
744744
// CLANG: "--dependent-lib=msvcrt"
745745
// CLANG-SAME: "-dependency-file" "my_dependency_file.dep"
746+
// CLANG-SAME: "-MT" "[[PREFIX]]/cl-options.obj"
746747
// CLANG-NOT: "--dependent-lib=libcmt"
747748
// CLANG-NOT: "-vectorize-slp"
748749

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ static bool DeprecatedDriverCommand;
8686
static ResourceDirRecipeKind ResourceDirRecipe;
8787
static bool Verbose;
8888
static bool PrintTiming;
89+
static llvm::BumpPtrAllocator Alloc;
90+
static llvm::StringSaver Saver{Alloc};
8991
static std::vector<const char *> CommandLine;
9092

9193
#ifndef NDEBUG
@@ -99,8 +101,6 @@ static bool RoundTripArgs = DoRoundTripDefault;
99101
static void ParseArgs(int argc, char **argv) {
100102
ScanDepsOptTable Tbl;
101103
llvm::StringRef ToolName = argv[0];
102-
llvm::BumpPtrAllocator Alloc;
103-
llvm::StringSaver Saver{Alloc};
104104
llvm::opt::InputArgList Args =
105105
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
106106
llvm::errs() << Msg << '\n';
@@ -792,6 +792,11 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
792792

793793
llvm::cl::PrintOptionValues();
794794

795+
// Expand response files in advance, so that we can "see" all the arguments
796+
// when adjusting below.
797+
Compilations = expandResponseFiles(std::move(Compilations),
798+
llvm::vfs::getRealFileSystem());
799+
795800
// The command options are rewritten to run Clang in preprocessor only mode.
796801
auto AdjustingCompilations =
797802
std::make_unique<tooling::ArgumentsAdjustingCompilations>(

0 commit comments

Comments
 (0)