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
|
import subprocess
import os
import sys
import re
indent = " "
def escape_special_symbols(strval):
retval = ""
for c in strval:
if c in ("\\", "\""):
retval += "\\" + c
elif ord(c) < 0x20:
retval += c.encode('unicode_escape').decode('utf-8')
else:
retval += c
return retval
def escape_line_feed(strval):
return re.sub(r'\\n', r'\\n"\\\n' + indent + '"', strval)
def escaped_define(strkey, strval):
return "#define " + strkey + " \"" + escape_line_feed(escape_special_symbols(strval)) + "\""
def get_build_info(compiler, flags):
build_info = "Build info:\n"
build_info += indent + "Compiler: " + compiler + "\n"
build_info += indent + "Compiler version: \n" + get_compiler_info(compiler) + "\n"
build_info += indent + "Compile flags: " + (flags if flags else "no flags info")
return build_info
def get_compiler_info(compiler):
compiler_binary = os.path.basename(compiler).lower()
if len(compiler.split(' ')) > 1 or compiler_binary == "ymake" or compiler_binary == "ymake.exe":
compiler_ver_out = "Build by wrapper. No useful info here."
else:
compiler_ver_cmd = [compiler]
if compiler_binary not in ("cl", "cl.exe"):
compiler_ver_cmd.append('--version')
env = os.environ.copy()
env['LOCALE'] = 'C'
compiler_ver_out = (
subprocess.Popen(compiler_ver_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
.stdout.read()
.decode('utf-8')
)
return "\n".join(
# fmt: off
f'{indent * 2}{line.strip()}'
for line in compiler_ver_out.splitlines()
if line.strip()
# fmt: on
)
def filterflags(flags_str):
badflgs = {
'-fdebug-prefix-map',
'-DARCADIA_ROOT',
'-DARCADIA_BUILD_ROOT',
'/DARCADIA_ROOT',
'/DARCADIA_BUILD_ROOT',
}
def flags_iter():
for flag in flags_str.split():
if not flag:
continue
if flag.split('=', 1)[0] in badflgs:
continue
yield flag
return ' '.join(flags_iter())
def main():
if len(sys.argv) != 4:
print("Usage: build_info_gen.py <output file> <CXX compiler> <CXX flags>", file=sys.stderr)
sys.exit(1)
cxx_compiler = sys.argv[2]
cxx_flags = filterflags(sys.argv[3])
with open(sys.argv[1], 'w') as result:
print("#pragma once\n", file=result)
print(escaped_define("BUILD_INFO", get_build_info(cxx_compiler, cxx_flags)), file=result)
print(escaped_define("BUILD_COMPILER", cxx_compiler), file=result)
print(escaped_define("BUILD_COMPILER_VERSION", get_compiler_info(cxx_compiler)), file=result)
print(escaped_define("BUILD_COMPILER_FLAGS", cxx_flags), file=result)
if __name__ == "__main__":
main()
|