The patch adds support for --hash-filenames to llvm-cov. This option adds md5
hash of the source path to the name of the generated .gcov file. The option is
crucial for cases where you have multiple files with the same name but can't
use --preserve-paths as resulting filenames exceed the limit.
from gcov(1):
```
-x
--hash-filenames
By default, gcov uses the full pathname of the source files to to
create an output filename. This can lead to long filenames that
can overflow filesystem limits. This option creates names of the
form source-file##md5.gcov, where the source-file component is
the final filename part and the md5 component is calculated from
the full mangled name that would have been used otherwise.
```
Patch by Igor Ignatev!
Differential Revision: https://reviews.llvm.org/D58370
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354379
91177308-0d34-0410-b5e6-
96231b3b80d8
Display the version of llvm-cov.
+.. option:: -x, --hash-filenames
+
+ Use md5 hash of file name when naming the coverage output files. The source
+ file name will be suffixed by ``##`` followed by MD5 hash calculated for it.
+
EXIT STATUS
^^^^^^^^^^^
/// A struct for passing gcov options between functions.
struct Options {
- Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N)
+ Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N, bool X)
: AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
- PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N) {}
+ PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N),
+ HashFilenames(X) {}
bool AllBlocks;
bool BranchInfo;
bool UncondBranch;
bool LongFileNames;
bool NoOutput;
+ bool HashFilenames;
};
} // end namespace GCOV
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/MD5.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <system_error>
if (Options.LongFileNames && !Filename.equals(MainFilename))
CoveragePath =
mangleCoveragePath(MainFilename, Options.PreservePaths) + "##";
- CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov";
+ CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths);
+ if (Options.HashFilenames) {
+ MD5 Hasher;
+ MD5::MD5Result Result;
+ Hasher.update(Filename.str());
+ Hasher.final(Result);
+ CoveragePath += "##" + Result.digest().str().str();
+ }
+ CoveragePath += ".gcov";
return CoveragePath;
}
--- /dev/null
+File 'srcdir/./nested_dir/../test.cpp'
+Lines executed:84.21% of 38
+srcdir/./nested_dir/../test.cpp:creating 'test.cpp##a806e5b3093cd6f683da88c0da150daf.gcov'
+
+File 'srcdir/./nested_dir/../test.h'
+Lines executed:100.00% of 1
+srcdir/./nested_dir/../test.h:creating 'test.h##0cbee7e2421fa4517420ac4f935620ca.gcov'
+
RUN: diff -aub test_paths.cpp.gcov srcdir#^#test_paths.cpp##srcdir#nested_dir#^#test.cpp.gcov
RUN: diff -aub test_paths.h.gcov srcdir#^#test_paths.cpp##srcdir#nested_dir#^#test.h.gcov
+# Hash pathnames.
+RUN: llvm-cov gcov -x -gcno test_paths.gcno -gcda test_paths.gcda srcdir/../test_paths.cpp | diff -u test_hash.output -
+RUN: diff -aub test_paths.cpp.gcov test.cpp##a806e5b3093cd6f683da88c0da150daf.gcov
+RUN: diff -aub test_paths.h.gcov test.h##0cbee7e2421fa4517420ac4f935620ca.gcov
+
# Function summaries. This changes stdout, but not the gcov files.
RUN: llvm-cov gcov test.c -f | diff -u test_-f.output -
RUN: diff -aub test_no_options.cpp.gcov test.cpp.gcov
"(requires -b)"));
cl::alias UncondBranchA("unconditional-branches", cl::aliasopt(UncondBranch));
+ cl::opt<bool> HashFilenames("x", cl::Grouping, cl::init(false),
+ cl::desc("Hash long pathnames"));
+ cl::alias HashFilenamesA("hash-filenames", cl::aliasopt(HashFilenames));
+
+
cl::OptionCategory DebugCat("Internal and debugging options");
cl::opt<bool> DumpGCOV("dump", cl::init(false), cl::cat(DebugCat),
cl::desc("Dump the gcov file to stderr"));
cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
- PreservePaths, UncondBranch, LongNames, NoOutput);
+ PreservePaths, UncondBranch, LongNames, NoOutput,
+ HashFilenames);
for (const auto &SourceFile : SourceFiles)
reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,