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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits