r364088 - [clang-scan-deps] print the dependencies to stdout
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 21 11:24:55 PDT 2019
Author: arphaman
Date: Fri Jun 21 11:24:55 2019
New Revision: 364088
URL: http://llvm.org/viewvc/llvm-project?rev=364088&view=rev
Log:
[clang-scan-deps] print the dependencies to stdout
and remove the need to use -MD options in the CDB
Differential Revision: https://reviews.llvm.org/D63579
Modified:
cfe/trunk/include/clang/Frontend/Utils.h
cfe/trunk/lib/Frontend/DependencyFile.cpp
cfe/trunk/test/ClangScanDeps/Inputs/regular_cdb.json
cfe/trunk/test/ClangScanDeps/regular_cdb.cpp
cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp
Modified: cfe/trunk/include/clang/Frontend/Utils.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Utils.h?rev=364088&r1=364087&r2=364088&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/Utils.h (original)
+++ cfe/trunk/include/clang/Frontend/Utils.h Fri Jun 21 11:24:55 2019
@@ -132,6 +132,9 @@ public:
bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem,
bool IsModuleFile, bool IsMissing) final override;
+protected:
+ void outputDependencyFile(llvm::raw_ostream &OS);
+
private:
void outputDependencyFile(DiagnosticsEngine &Diags);
Modified: cfe/trunk/lib/Frontend/DependencyFile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DependencyFile.cpp?rev=364088&r1=364087&r2=364088&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/DependencyFile.cpp (original)
+++ cfe/trunk/lib/Frontend/DependencyFile.cpp Fri Jun 21 11:24:55 2019
@@ -322,6 +322,10 @@ void DependencyFileGenerator::outputDepe
return;
}
+ outputDependencyFile(OS);
+}
+
+void DependencyFileGenerator::outputDependencyFile(llvm::raw_ostream &OS) {
// Write out the dependency targets, trying to avoid overly long
// lines when possible. We try our best to emit exactly the same
// dependency file as GCC (4.2), assuming the included files are the
Modified: cfe/trunk/test/ClangScanDeps/Inputs/regular_cdb.json
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ClangScanDeps/Inputs/regular_cdb.json?rev=364088&r1=364087&r2=364088&view=diff
==============================================================================
--- cfe/trunk/test/ClangScanDeps/Inputs/regular_cdb.json (original)
+++ cfe/trunk/test/ClangScanDeps/Inputs/regular_cdb.json Fri Jun 21 11:24:55 2019
@@ -1,12 +1,12 @@
[
{
"directory": "DIR",
- "command": "clang -E -fsyntax-only DIR/regular_cdb.cpp -IInputs -MD -MF DIR/regular_cdb.d",
- "file": "DIR/regular_cdb.cpp"
+ "command": "clang -E -fsyntax-only DIR/regular_cdb2.cpp -IInputs -D INCLUDE_HEADER2 -MD -MF DIR/regular_cdb2.d",
+ "file": "DIR/regular_cdb2.cpp"
},
{
"directory": "DIR",
- "command": "clang -E -fsyntax-only DIR/regular_cdb.cpp -IInputs -D INCLUDE_HEADER2 -MD -MF DIR/regular_cdb2.d",
+ "command": "clang -E -fsyntax-only DIR/regular_cdb.cpp -IInputs",
"file": "DIR/regular_cdb.cpp"
}
]
Modified: cfe/trunk/test/ClangScanDeps/regular_cdb.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ClangScanDeps/regular_cdb.cpp?rev=364088&r1=364087&r2=364088&view=diff
==============================================================================
--- cfe/trunk/test/ClangScanDeps/regular_cdb.cpp (original)
+++ cfe/trunk/test/ClangScanDeps/regular_cdb.cpp Fri Jun 21 11:24:55 2019
@@ -2,26 +2,35 @@
// RUN: rm -rf %t.cdb
// RUN: mkdir -p %t.dir
// RUN: cp %s %t.dir/regular_cdb.cpp
+// RUN: cp %s %t.dir/regular_cdb2.cpp
// RUN: mkdir %t.dir/Inputs
// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header.h
// RUN: cp %S/Inputs/header2.h %t.dir/Inputs/header2.h
// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/regular_cdb.json > %t.cdb
//
-// RUN: clang-scan-deps -compilation-database %t.cdb -j 1
-// RUN: cat %t.dir/regular_cdb.d | FileCheck %s
-// RUN: cat %t.dir/regular_cdb2.d | FileCheck --check-prefix=CHECK2 %s
-// RUN: rm -rf %t.dir/regular_cdb.d %t.dir/regular_cdb2.d
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 | \
+// RUN: FileCheck --check-prefixes=CHECK1,CHECK2,CHECK2NO %s
//
-// RUN: clang-scan-deps -compilation-database %t.cdb -j 2
-// RUN: cat %t.dir/regular_cdb.d | FileCheck %s
-// RUN: cat %t.dir/regular_cdb2.d | FileCheck --check-prefix=CHECK2 %s
+// Make sure we didn't produce any dependency files!
+// RUN: not cat %t.dir/regular_cdb.d
+// RUN: not cat %t.dir/regular_cdb2.d
+//
+// The output order is non-deterministic when using more than one thread,
+// so check the output using two runs. Note that the 'NOT' check is not used
+// as it might fail if the results for `regular_cdb.cpp` are reported before
+// `regular_cdb2.cpp`.
+//
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 2 | \
+// RUN: FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 2 | \
+// RUN: FileCheck --check-prefix=CHECK2 %s
#include "header.h"
-// CHECK: regular_cdb.cpp
-// CHECK-NEXT: Inputs{{/|\\}}header.h
-// CHECK-NOT: header2
+// CHECK1: regular_cdb2.cpp
+// CHECK1-NEXT: Inputs{{/|\\}}header.h
+// CHECK1-NEXT: Inputs{{/|\\}}header2.h
// CHECK2: regular_cdb.cpp
// CHECK2-NEXT: Inputs{{/|\\}}header.h
-// CHECK2-NEXT: Inputs{{/|\\}}header2.h
+// CHECK2NO-NOT: header2
Modified: cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp?rev=364088&r1=364087&r2=364088&view=diff
==============================================================================
--- cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp (original)
+++ cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp Fri Jun 21 11:24:55 2019
@@ -29,12 +29,43 @@ using namespace clang;
namespace {
+class SharedStream {
+public:
+ SharedStream(raw_ostream &OS) : OS(OS) {}
+ void applyLocked(llvm::function_ref<void(raw_ostream &OS)> Fn) {
+ std::unique_lock<std::mutex> LockGuard(Lock);
+ Fn(OS);
+ OS.flush();
+ }
+
+private:
+ std::mutex Lock;
+ raw_ostream &OS;
+};
+
+/// Prints out all of the gathered dependencies into one output stream instead
+/// of using the output dependency file.
+class DependencyPrinter : public DependencyFileGenerator {
+public:
+ DependencyPrinter(std::unique_ptr<DependencyOutputOptions> Opts,
+ SharedStream &OS)
+ : DependencyFileGenerator(*Opts), Opts(std::move(Opts)), OS(OS) {}
+
+ void finishedMainFile(DiagnosticsEngine &Diags) override {
+ OS.applyLocked([this](raw_ostream &OS) { outputDependencyFile(OS); });
+ }
+
+private:
+ std::unique_ptr<DependencyOutputOptions> Opts;
+ SharedStream &OS;
+};
+
/// A clang tool that runs the preprocessor only for the given compiler
/// invocation.
class PreprocessorOnlyTool : public tooling::ToolAction {
public:
- PreprocessorOnlyTool(StringRef WorkingDirectory)
- : WorkingDirectory(WorkingDirectory) {}
+ PreprocessorOnlyTool(StringRef WorkingDirectory, SharedStream &OS)
+ : WorkingDirectory(WorkingDirectory), OS(OS) {}
bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
FileManager *FileMgr,
@@ -53,6 +84,21 @@ public:
Compiler.createSourceManager(*FileMgr);
+ // Create the dependency collector that will collect the produced
+ // dependencies.
+ //
+ // This also moves the existing dependency output options from the
+ // invocation to the collector. The options in the invocation are reset,
+ // which ensures that the compiler won't create new dependency collectors,
+ // and thus won't write out the extra '.d' files to disk.
+ auto Opts = llvm::make_unique<DependencyOutputOptions>(
+ std::move(Compiler.getInvocation().getDependencyOutputOpts()));
+ // We need at least one -MT equivalent for the generator to work.
+ if (Opts->Targets.empty())
+ Opts->Targets = {"clang-scan-deps dependency"};
+ Compiler.addDependencyCollector(
+ std::make_shared<DependencyPrinter>(std::move(Opts), OS));
+
auto Action = llvm::make_unique<PreprocessOnlyAction>();
const bool Result = Compiler.ExecuteAction(*Action);
FileMgr->clearStatCache();
@@ -61,6 +107,7 @@ public:
private:
StringRef WorkingDirectory;
+ SharedStream &OS;
};
/// A proxy file system that doesn't call `chdir` when changing the working
@@ -93,8 +140,9 @@ public:
///
/// \param Compilations The reference to the compilation database that's
/// used by the clang tool.
- DependencyScanningTool(const tooling::CompilationDatabase &Compilations)
- : Compilations(Compilations) {
+ DependencyScanningTool(const tooling::CompilationDatabase &Compilations,
+ SharedStream &OS)
+ : Compilations(Compilations), OS(OS) {
PCHContainerOps = std::make_shared<PCHContainerOperations>();
BaseFS = new ProxyFileSystemWithoutChdir(llvm::vfs::getRealFileSystem());
}
@@ -107,12 +155,13 @@ public:
tooling::ClangTool Tool(Compilations, Input, PCHContainerOps, BaseFS);
Tool.clearArgumentsAdjusters();
Tool.setRestoreWorkingDir(false);
- PreprocessorOnlyTool Action(CWD);
+ PreprocessorOnlyTool Action(CWD, OS);
return Tool.run(&Action);
}
private:
const tooling::CompilationDatabase &Compilations;
+ SharedStream &OS;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
/// The real filesystem used as a base for all the operations performed by the
/// tool.
@@ -176,12 +225,14 @@ int main(int argc, const char **argv) {
return AdjustedArgs;
});
+ // Print out the dependency results to STDOUT by default.
+ SharedStream DependencyOS(llvm::outs());
unsigned NumWorkers =
NumThreads == 0 ? llvm::hardware_concurrency() : NumThreads;
std::vector<std::unique_ptr<DependencyScanningTool>> WorkerTools;
for (unsigned I = 0; I < NumWorkers; ++I)
- WorkerTools.push_back(
- llvm::make_unique<DependencyScanningTool>(*AdjustingCompilations));
+ WorkerTools.push_back(llvm::make_unique<DependencyScanningTool>(
+ *AdjustingCompilations, DependencyOS));
std::vector<std::thread> WorkerThreads;
std::atomic<bool> HadErrors(false);
More information about the cfe-commits
mailing list