Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/editor/editor_builders.py
21023 views
1
"""Functions used to generate source files during build time"""
2
3
import os
4
import os.path
5
import subprocess
6
import tempfile
7
import uuid
8
9
import methods
10
11
12
def doc_data_class_path_builder(target, source, env):
13
paths = dict(sorted(source[0].read().items()))
14
data = "\n".join([f'\t{{"{key}", "{value}"}},' for key, value in paths.items()])
15
with methods.generated_wrapper(str(target[0])) as file:
16
file.write(
17
f"""\
18
struct _DocDataClassPath {{
19
const char *name;
20
const char *path;
21
}};
22
23
inline constexpr int _doc_data_class_path_count = {len(paths)};
24
inline constexpr _DocDataClassPath _doc_data_class_paths[{len(paths) + 1}] = {{
25
{data}
26
{{nullptr, nullptr}},
27
}};
28
"""
29
)
30
31
32
def register_exporters_builder(target, source, env):
33
platforms = source[0].read()
34
exp_inc = "\n".join([f'#include "platform/{p}/export/export.h"' for p in platforms])
35
exp_reg = "\n\t".join([f"register_{p}_exporter();" for p in platforms])
36
exp_type = "\n\t".join([f"register_{p}_exporter_types();" for p in platforms])
37
with methods.generated_wrapper(str(target[0])) as file:
38
file.write(
39
f"""\
40
#include "register_exporters.h"
41
42
{exp_inc}
43
44
void register_exporters() {{
45
{exp_reg}
46
}}
47
48
void register_exporter_types() {{
49
{exp_type}
50
}}
51
"""
52
)
53
54
55
def make_doc_header(target, source, env):
56
buffer = b"".join([methods.get_buffer(src) for src in map(str, source)])
57
decomp_size = len(buffer)
58
buffer = methods.compress_buffer(buffer)
59
60
with methods.generated_wrapper(str(target[0])) as file:
61
file.write(f"""\
62
inline constexpr const char *_doc_data_hash = "{hash(buffer)}";
63
inline constexpr int _doc_data_compressed_size = {len(buffer)};
64
inline constexpr int _doc_data_uncompressed_size = {decomp_size};
65
inline constexpr const unsigned char _doc_data_compressed[] = {{
66
{methods.format_buffer(buffer, 1)}
67
}};
68
""")
69
70
71
def make_translations(target, source, env):
72
target_h, target_cpp = str(target[0]), str(target[1])
73
74
category = os.path.basename(target_h).split("_")[0]
75
sorted_paths = sorted([src.abspath for src in source], key=lambda path: os.path.splitext(os.path.basename(path))[0])
76
77
xl_names = []
78
msgfmt = env.Detect("msgfmt")
79
if not msgfmt:
80
methods.print_warning("msgfmt not found, using .po files instead of .mo")
81
82
with methods.generated_wrapper(target_cpp) as file:
83
for path in sorted_paths:
84
name = os.path.splitext(os.path.basename(path))[0]
85
# msgfmt erases non-translated messages, so avoid using it if exporting the POT.
86
if msgfmt and name != category:
87
mo_path = os.path.join(tempfile.gettempdir(), uuid.uuid4().hex + ".mo")
88
cmd = f'{msgfmt} "{path}" --no-hash -o "{mo_path}"'
89
try:
90
subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE).communicate()
91
buffer = methods.get_buffer(mo_path)
92
except OSError as e:
93
methods.print_warning(
94
"msgfmt execution failed, using .po file instead of .mo: path=%r; [%s] %s"
95
% (path, e.__class__.__name__, e)
96
)
97
buffer = methods.get_buffer(path)
98
finally:
99
try:
100
if os.path.exists(mo_path):
101
os.remove(mo_path)
102
except OSError as e:
103
# Do not fail the entire build if it cannot delete a temporary file.
104
methods.print_warning(
105
"Could not delete temporary .mo file: path=%r; [%s] %s" % (mo_path, e.__class__.__name__, e)
106
)
107
else:
108
buffer = methods.get_buffer(path)
109
if name == category:
110
name = "source"
111
112
decomp_size = len(buffer)
113
buffer = methods.compress_buffer(buffer)
114
115
file.write(f"""\
116
inline constexpr const unsigned char _{category}_translation_{name}_compressed[] = {{
117
{methods.format_buffer(buffer, 1)}
118
}};
119
120
""")
121
122
xl_names.append([name, len(buffer), decomp_size])
123
124
file.write(f"""\
125
#include "{target_h}"
126
127
const EditorTranslationList _{category}_translations[] = {{
128
""")
129
130
for x in xl_names:
131
file.write(f'\t{{ "{x[0]}", {x[1]}, {x[2]}, _{category}_translation_{x[0]}_compressed }},\n')
132
133
file.write("""\
134
{ nullptr, 0, 0, nullptr },
135
};
136
""")
137
138
with methods.generated_wrapper(target_h) as file:
139
file.write(f"""\
140
141
#ifndef EDITOR_TRANSLATION_LIST
142
#define EDITOR_TRANSLATION_LIST
143
144
struct EditorTranslationList {{
145
const char* lang;
146
int comp_size;
147
int uncomp_size;
148
const unsigned char* data;
149
}};
150
151
#endif // EDITOR_TRANSLATION_LIST
152
153
extern const EditorTranslationList _{category}_translations[];
154
""")
155
156