/
rebuild.py
executable file
·124 lines (111 loc) · 3.42 KB
/
rebuild.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env python3
import subprocess
import os
import os.path
import sys
import collections
import shutil
Builder = collections.namedtuple('Builder', ['ext', 'cmd', 'gcov'])
BUILDERS = {
'.gcc7': Builder(
ext='.cpp',
cmd=['g++-7', '--std=c++14', '--coverage'],
gcov='gcov-7'
),
'.clang': Builder(
ext='.cpp',
cmd=['clang++', '--std=c++14', '--coverage'],
gcov='gcov'
),
'.rustc': Builder(
ext='.rs',
cmd=['rustc', '-g', '-Zprofile'],
gcov='gcov'
),
}
def build():
for directory in os.listdir('.'):
(base, ext) = os.path.splitext(directory)
builder = BUILDERS.get(ext) # type: Builder
if not builder:
continue
out_dir = os.path.join(directory, 'build')
if os.path.isdir(out_dir):
print('Fresh', directory)
continue
print('Rebuilding', directory)
os.mkdir(out_dir)
src_path = os.path.join('src', base + builder.ext)
dst_path = os.path.join(out_dir, 'x' + builder.ext)
os.link(src_path, dst_path)
subprocess.run(builder.cmd + [
'-o', 'x',
'x' + builder.ext,
], cwd=out_dir, check=True)
subprocess.run([
'lcov',
'--base-directory', '.',
'--directory', '.',
'-zerocounters',
'-q',
], cwd=out_dir, check=True)
subprocess.run(['./x'], cwd=out_dir, check=True, stdout=subprocess.DEVNULL)
subprocess.run([
'lcov',
'--base-directory', '.',
'--directory', '.',
'--gcov-tool', builder.gcov,
'--capture',
'--rc', 'geninfo_checksum=1',
'--rc', 'geninfo_gcov_all_blocks=1',
'--rc', 'lcov_branch_coverage=1',
'-o', 'x.info',
'-q',
], cwd=out_dir, check=True)
subprocess.run([
'genhtml',
'-o', '.',
'--function-coverage',
'--branch-coverage',
'x.info',
], cwd=out_dir, check=True, stdout=subprocess.DEVNULL)
subprocess.run([
'gcovr',
'--gcov-executable=' + builder.gcov,
'-r', '.',
'-b',
'--html',
'--html-details',
'-o', 'x.html',
], cwd=out_dir, check=True)
subprocess.run([
builder.gcov,
'-a', '-b', '-c', '-f', '-p', '-u',
'x' + builder.ext,
], cwd=out_dir, check=True, stdout=subprocess.DEVNULL)
for filename in ('x.gcda', 'x.gcno'):
src_path = os.path.join(out_dir, filename)
dst_path = os.path.join(directory, filename)
os.link(src_path, dst_path)
def clean():
for filename in os.listdir('.'):
if os.path.isdir(filename):
try:
os.remove(os.path.join(filename, 'x.gcno'))
except FileNotFoundError:
pass
try:
os.remove(os.path.join(filename, 'x.gcda'))
except FileNotFoundError:
pass
try:
shutil.rmtree(os.path.join(filename, 'build'))
except FileNotFoundError:
pass
for directory in os.listdir('.'):
(base, ext) = os.path.splitext(directory)
if __name__ == '__main__':
if len(sys.argv) > 1 and sys.argv[1] == 'clean':
clean()
else:
build()