Skip to content

Commit 93a0581

Browse files
committed
[clang][deps] Add argument for customizing PCM paths
Dependency scanning currently performs an implicit build. When testing that Clang can build modules with the command-lines generated by `clang-scan-deps`, the actual compilation would overwrite artifacts created during the scan, which makes debugging harder than it should be and can lead to errors in multi-step builds. To prevent this, this patch adds new flag to `clang-scan-deps` that allows developers to customize the directory to use when generating module map paths, instead of always using the module cache. Moreover, the explicit context hash in now part of the PCM path, which will be useful in D102488, where the context hash can change due to command-line pruning. Reviewed By: Bigcheese Differential Revision: https://reviews.llvm.org/D103516
1 parent cd093cb commit 93a0581

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ struct ModuleID {
4242
/// Modules with the same name but a different \c ContextHash should be
4343
/// treated as separate modules for the purpose of a build.
4444
std::string ContextHash;
45+
46+
bool operator==(const ModuleID &Other) const {
47+
return ModuleName == Other.ModuleName && ContextHash == Other.ContextHash;
48+
}
49+
};
50+
51+
struct ModuleIDHasher {
52+
std::size_t operator()(const ModuleID &MID) const {
53+
return llvm::hash_combine(MID.ModuleName, MID.ContextHash);
54+
}
4555
};
4656

4757
struct ModuleDeps {

clang/test/ClangScanDeps/modules-full.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
// RUN: -generate-modules-path-args -mode preprocess-minimized-sources >> %t.result
2121
// RUN: cat %t.result | sed 's/\\/\//g' | FileCheck --check-prefixes=CHECK,CHECK-ABS %s
2222
//
23+
// RUN: echo %t.dir > %t.result
24+
// RUN: clang-scan-deps -compilation-database %t.cdb -j 4 -format experimental-full \
25+
// RUN: -generate-modules-path-args -module-files-dir %t.dir/custom \
26+
// RUN: -mode preprocess-minimized-sources >> %t.result
27+
// RUN: cat %t.result | sed 's/\\/\//g' | FileCheck --check-prefixes=CHECK,CHECK-CUSTOM %s
28+
//
2329
// RUN: echo %t.dir > %t_clangcl.result
2430
// RUN: clang-scan-deps -compilation-database %t_clangcl.cdb -j 4 -format experimental-full \
2531
// RUN: -mode preprocess-minimized-sources >> %t_clangcl.result
@@ -45,9 +51,11 @@
4551
// CHECK-NEXT: "-cc1"
4652
// CHECK-NO-ABS-NOT: "-fmodule-map-file={{.*}}"
4753
// CHECK-ABS: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
54+
// CHECK-CUSTOM: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
4855
// CHECK: "-emit-module"
4956
// CHECK-NO-ABS-NOT: "-fmodule-file={{.*}}"
5057
// CHECK-ABS: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[CONTEXT_HASH_H1]]/header2-{{[A-Z0-9]+}}.pcm"
58+
// CHECK-CUSTOM: "-fmodule-file=[[PREFIX]]/custom/[[CONTEXT_HASH_H1]]/header2-{{[A-Z0-9]+}}.pcm"
5159
// CHECK: "-fmodule-name=header1"
5260
// CHECK: "-fno-implicit-modules"
5361
// CHECK: ],
@@ -105,8 +113,10 @@
105113
// CHECK-NEXT: "-fno-implicit-module-maps"
106114
// CHECK-NO-ABS-NOT: "-fmodule-file={{.*}}"
107115
// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[CONTEXT_HASH_H2]]/header1-{{[A-Z0-9]+}}.pcm"
116+
// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[CONTEXT_HASH_H2]]/header1-{{[A-Z0-9]+}}.pcm"
108117
// CHECK-NO-ABS-NOT: "-fmodule-map-file={{.*}}"
109118
// CHECK-ABS-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
119+
// CHECK-CUSTOM-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
110120
// CHECK-NEXT: ],
111121
// CHECK-NEXT: "file-deps": [
112122
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
@@ -126,8 +136,10 @@
126136
// CHECK-NEXT: "-fno-implicit-module-maps"
127137
// CHECK-NO-ABS-NOT: "-fmodule-file={{.*}},
128138
// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[CONTEXT_HASH_H2]]/header1-{{[A-Z0-9]+}}.pcm"
139+
// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[CONTEXT_HASH_H2]]/header1-{{[A-Z0-9]+}}.pcm"
129140
// CHECK-NO-ABS-NOT: "-fmodule-map-file={{.*}}
130141
// CHECK-ABS-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
142+
// CHECK-CUSTOM-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
131143
// CHECK-NEXT: ],
132144
// CHECK-NEXT: "file-deps": [
133145
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
@@ -147,8 +159,10 @@
147159
// CHECK-NEXT: "-fno-implicit-module-maps"
148160
// CHECK-NO-ABS-NOT: "-fmodule-file={{.*}}"
149161
// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[CONTEXT_HASH_H2]]/header1-{{[A-Z0-9]+}}.pcm"
162+
// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[CONTEXT_HASH_H2]]/header1-{{[A-Z0-9]+}}.pcm"
150163
// CHECK-NO-ABS-NOT: "-fmodule-map-file={{.*}}"
151164
// CHECK-ABS-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
165+
// CHECK-CUSTOM-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
152166
// CHECK-NEXT: ],
153167
// CHECK-NEXT: "file-deps": [
154168
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
@@ -169,9 +183,13 @@
169183
// CHECK-NO-ABS-NOT: "-fmodule-file={{.*}}"
170184
// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[CONTEXT_HASH_H1]]/header2-{{[A-Z0-9]+}}.pcm"
171185
// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[CONTEXT_HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
186+
// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[CONTEXT_HASH_H1]]/header2-{{[A-Z0-9]+}}.pcm"
187+
// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[CONTEXT_HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
172188
// CHECK-NO-ABS-NOT: "-fmodule-map-file={{.*}}"
173189
// CHECK-ABS-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
174190
// CHECK-ABS-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
191+
// CHECK-CUSTOM-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
192+
// CHECK-CUSTOM-NEXT: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap"
175193
// CHECK-NEXT: ],
176194
// CHECK-NEXT: "file-deps": [
177195
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input2.cpp"

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ static llvm::cl::opt<bool> GenerateModulesPathArgs(
163163
"'-fmodule-file=', '-o', '-fmodule-map-file='."),
164164
llvm::cl::init(false), llvm::cl::cat(DependencyScannerCategory));
165165

166+
static llvm::cl::opt<std::string> ModuleFilesDir(
167+
"module-files-dir",
168+
llvm::cl::desc("With '-generate-modules-path-args', paths to module files "
169+
"in the generated command lines will begin with the "
170+
"specified directory instead the module cache directory."),
171+
llvm::cl::cat(DependencyScannerCategory));
172+
166173
llvm::cl::opt<unsigned>
167174
NumThreads("j", llvm::cl::Optional,
168175
llvm::cl::desc("Number of worker threads to use (default: use "
@@ -357,7 +364,22 @@ class FullDeps {
357364

358365
private:
359366
StringRef lookupPCMPath(ModuleID MID) {
360-
return Modules[IndexedModuleID{MID, 0}].ImplicitModulePCMPath;
367+
auto PCMPath = PCMPaths.insert({MID, ""});
368+
if (PCMPath.second)
369+
PCMPath.first->second = constructPCMPath(lookupModuleDeps(MID));
370+
return PCMPath.first->second;
371+
}
372+
373+
/// Construct a path for the explicitly built PCM.
374+
std::string constructPCMPath(const ModuleDeps &MD) const {
375+
StringRef Filename = llvm::sys::path::filename(MD.ImplicitModulePCMPath);
376+
377+
SmallString<256> ExplicitPCMPath(
378+
!ModuleFilesDir.empty()
379+
? ModuleFilesDir
380+
: MD.Invocation.getHeaderSearchOpts().ModuleCachePath);
381+
llvm::sys::path::append(ExplicitPCMPath, MD.ID.ContextHash, Filename);
382+
return std::string(ExplicitPCMPath);
361383
}
362384

363385
const ModuleDeps &lookupModuleDeps(ModuleID MID) {
@@ -395,6 +417,7 @@ class FullDeps {
395417
std::mutex Lock;
396418
std::unordered_map<IndexedModuleID, ModuleDeps, IndexedModuleIDHasher>
397419
Modules;
420+
std::unordered_map<ModuleID, std::string, ModuleIDHasher> PCMPaths;
398421
std::vector<InputDeps> Inputs;
399422
};
400423

0 commit comments

Comments
 (0)