-
Notifications
You must be signed in to change notification settings - Fork 3
/
build_info.py
129 lines (101 loc) · 3.32 KB
/
build_info.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
125
126
127
128
129
#!/usr/bin/env python3
# Copyright (c) 2021 Alethea Katherine Flowers.
# Published under the standard MIT License.
# Full text available at: https://opensource.org/licenses/MIT
import argparse
import datetime
import os
import os.path
import platform
import pwd
import subprocess
import tempfile
import textwrap
def username():
return pwd.getpwuid(os.getuid())[0]
def extract_compiled_build_info(o_path):
with tempfile.TemporaryDirectory() as dstdir:
dst = os.path.join(dstdir, "output.txt")
subprocess.run(
[
"arm-none-eabi-objcopy",
"-O",
"binary",
"--only-section=.rodata.build_info",
o_path,
dst,
],
check=True,
)
with open(dst, "r", encoding="utf-8") as fh:
return fh.read().strip("\x00")
def generate_build_info_c(configuration):
gcc_version = subprocess.run(
["arm-none-eabi-gcc", "-dumpversion"],
capture_output=True,
check=True,
text=True,
).stdout.strip()
try:
release = subprocess.run(
["git", "describe", "--always", "--tags", "--abbrev=0"],
capture_output=True,
check=True,
text=True,
).stdout.strip()
except subprocess.CalledProcessError:
release = "None"
if "." in release:
year, month, day = [x.lstrip("0") for x in release.split(".", 3)]
else:
year, month, day = 0, 0, 0
try:
revision = subprocess.run(
["git", "describe", "--always", "--tags", "--dirty"],
capture_output=True,
check=True,
text=True,
).stdout.strip()
except subprocess.CalledProcessError:
revision = "None"
compiler = f"gcc {gcc_version}"
date = datetime.datetime.utcnow().strftime("%m/%d/%Y %H:%M UTC")
machine = f"{username()}@{platform.node()}"
build_info_string = (
f"{revision} ({configuration}) on {date} with {compiler} by {machine}"
)
return build_info_string, textwrap.dedent(
f"""
/* This file is generated by generate_build_info.py - don't edit it directly!! */
#include "wntr_build_info.h"
static const char compiler[] = "{compiler}";
static const char revision[] = "{revision}";
static const char date[] = "{date}";
static const char machine[] = "{machine}";
static const char release[] = "{release}";
static const char build_info[] = "{build_info_string}";
struct WntrBuildInfo wntr_build_info() {{
return (struct WntrBuildInfo){{
.revision = revision,
.date = date,
.compiler = compiler,
.machine = machine,
.release = release,
.release_year = {year},
.release_month = {month},
.release_day = {day},
}};
}}
const char* wntr_build_info_string() {{ return build_info; }}
"""
)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--config", "--configuration", default="Unknown")
parser.add_argument("output", type=argparse.FileType("w", encoding="utf-8"))
args = parser.parse_args()
info, output = generate_build_info_c(args.config)
args.output.write(output)
print(f"Build ID: {info}")
if __name__ == "__main__":
main()