llvm-project

Форк
0
/
prepare-code-coverage-artifact.py 
198 строк · 5.5 Кб
1
#!/usr/bin/env python
2

3
from __future__ import print_function
4

5
"""Prepare a code coverage artifact.
6

7
- Collate raw profiles into one indexed profile.
8
- Generate html reports for the given binaries.
9

10
Caution: The positional arguments to this script must be specified before any 
11
optional arguments, such as --restrict.
12
"""
13

14
import argparse
15
import glob
16
import os
17
import subprocess
18
import sys
19

20

21
def merge_raw_profiles(host_llvm_profdata, profile_data_dir, preserve_profiles):
22
    print(":: Merging raw profiles...", end="")
23
    sys.stdout.flush()
24
    raw_profiles = glob.glob(os.path.join(profile_data_dir, "*.profraw"))
25
    manifest_path = os.path.join(profile_data_dir, "profiles.manifest")
26
    profdata_path = os.path.join(profile_data_dir, "Coverage.profdata")
27
    with open(manifest_path, "w") as manifest:
28
        manifest.write("\n".join(raw_profiles))
29
    subprocess.check_call(
30
        [
31
            host_llvm_profdata,
32
            "merge",
33
            "-sparse",
34
            "-f",
35
            manifest_path,
36
            "-o",
37
            profdata_path,
38
        ]
39
    )
40
    if not preserve_profiles:
41
        for raw_profile in raw_profiles:
42
            os.remove(raw_profile)
43
    os.remove(manifest_path)
44
    print("Done!")
45
    return profdata_path
46

47

48
def prepare_html_report(
49
    host_llvm_cov, profile, report_dir, binaries, restricted_dirs, compilation_dir
50
):
51
    print(":: Preparing html report for {0}...".format(binaries), end="")
52
    sys.stdout.flush()
53
    objects = []
54
    for i, binary in enumerate(binaries):
55
        if i == 0:
56
            objects.append(binary)
57
        else:
58
            objects.extend(("-object", binary))
59
    invocation = (
60
        [host_llvm_cov, "show"]
61
        + objects
62
        + [
63
            "-format",
64
            "html",
65
            "-instr-profile",
66
            profile,
67
            "-o",
68
            report_dir,
69
            "-show-line-counts-or-regions",
70
            "-show-directory-coverage",
71
            "-Xdemangler",
72
            "c++filt",
73
            "-Xdemangler",
74
            "-n",
75
        ]
76
        + restricted_dirs
77
    )
78
    if compilation_dir:
79
        invocation += ["-compilation-dir=" + compilation_dir]
80
    subprocess.check_call(invocation)
81
    with open(os.path.join(report_dir, "summary.txt"), "wb") as Summary:
82
        subprocess.check_call(
83
            [host_llvm_cov, "report"]
84
            + objects
85
            + ["-instr-profile", profile]
86
            + restricted_dirs,
87
            stdout=Summary,
88
        )
89
    print("Done!")
90

91

92
def prepare_html_reports(
93
    host_llvm_cov,
94
    profdata_path,
95
    report_dir,
96
    binaries,
97
    unified_report,
98
    restricted_dirs,
99
    compilation_dir,
100
):
101
    if unified_report:
102
        prepare_html_report(
103
            host_llvm_cov,
104
            profdata_path,
105
            report_dir,
106
            binaries,
107
            restricted_dirs,
108
            compilation_dir,
109
        )
110
    else:
111
        for binary in binaries:
112
            binary_report_dir = os.path.join(report_dir, os.path.basename(binary))
113
            prepare_html_report(
114
                host_llvm_cov,
115
                profdata_path,
116
                binary_report_dir,
117
                [binary],
118
                restricted_dirs,
119
                compilation_dir,
120
            )
121

122

123
if __name__ == "__main__":
124
    parser = argparse.ArgumentParser(description=__doc__)
125
    parser.add_argument("host_llvm_profdata", help="Path to llvm-profdata")
126
    parser.add_argument("host_llvm_cov", help="Path to llvm-cov")
127
    parser.add_argument(
128
        "profile_data_dir", help="Path to the directory containing the raw profiles"
129
    )
130
    parser.add_argument(
131
        "report_dir", help="Path to the output directory for html reports"
132
    )
133
    parser.add_argument(
134
        "binaries",
135
        metavar="B",
136
        type=str,
137
        nargs="*",
138
        help="Path to an instrumented binary",
139
    )
140
    parser.add_argument(
141
        "--only-merge",
142
        action="store_true",
143
        help="Only merge raw profiles together, skip report " "generation",
144
    )
145
    parser.add_argument(
146
        "--preserve-profiles", help="Do not delete raw profiles", action="store_true"
147
    )
148
    parser.add_argument(
149
        "--use-existing-profdata", help="Specify an existing indexed profile to use"
150
    )
151
    parser.add_argument(
152
        "--unified-report",
153
        action="store_true",
154
        help="Emit a unified report for all binaries",
155
    )
156
    parser.add_argument(
157
        "--restrict",
158
        metavar="R",
159
        type=str,
160
        nargs="*",
161
        default=[],
162
        help="Restrict the reporting to the given source paths"
163
        " (must be specified after all other positional arguments)",
164
    )
165
    parser.add_argument(
166
        "-C",
167
        "--compilation-dir",
168
        type=str,
169
        default="",
170
        help="The compilation directory of the binary",
171
    )
172
    args = parser.parse_args()
173

174
    if args.use_existing_profdata and args.only_merge:
175
        print("--use-existing-profdata and --only-merge are incompatible")
176
        exit(1)
177

178
    if args.use_existing_profdata:
179
        profdata_path = args.use_existing_profdata
180
    else:
181
        profdata_path = merge_raw_profiles(
182
            args.host_llvm_profdata, args.profile_data_dir, args.preserve_profiles
183
        )
184

185
    if not len(args.binaries):
186
        print("No binaries specified, no work to do!")
187
        exit(1)
188

189
    if not args.only_merge:
190
        prepare_html_reports(
191
            args.host_llvm_cov,
192
            profdata_path,
193
            args.report_dir,
194
            args.binaries,
195
            args.unified_report,
196
            args.restrict,
197
            args.compilation_dir,
198
        )
199

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.