2018-03-17 23:23:55 +01:00
|
|
|
"""Functions used to generate source files during build time
|
|
|
|
|
|
|
|
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
|
|
|
|
"""
|
2020-02-06 17:28:32 +01:00
|
|
|
|
2018-03-17 23:23:55 +01:00
|
|
|
from platform_methods import subprocess_main
|
2018-09-14 16:02:04 +02:00
|
|
|
from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
|
|
|
|
|
|
|
|
|
|
|
|
def make_certs_header(target, source, env):
|
|
|
|
|
|
|
|
src = source[0]
|
|
|
|
dst = target[0]
|
|
|
|
f = open(src, "rb")
|
|
|
|
g = open_utf8(dst, "w")
|
|
|
|
buf = f.read()
|
|
|
|
decomp_size = len(buf)
|
|
|
|
import zlib
|
2020-03-30 08:28:32 +02:00
|
|
|
|
2018-09-14 16:02:04 +02:00
|
|
|
buf = zlib.compress(buf)
|
|
|
|
|
|
|
|
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
|
|
|
g.write("#ifndef _CERTS_RAW_H\n")
|
|
|
|
g.write("#define _CERTS_RAW_H\n")
|
2018-09-15 14:45:54 +02:00
|
|
|
|
|
|
|
# System certs path. Editor will use them if defined. (for package maintainers)
|
2020-03-30 08:28:32 +02:00
|
|
|
path = env["system_certs_path"]
|
|
|
|
g.write('#define _SYSTEM_CERTS_PATH "%s"\n' % str(path))
|
|
|
|
if env["builtin_certs"]:
|
2018-09-14 16:02:04 +02:00
|
|
|
# Defined here and not in env so changing it does not trigger a full rebuild.
|
|
|
|
g.write("#define BUILTIN_CERTS_ENABLED\n")
|
|
|
|
g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
|
|
|
|
g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
|
|
|
|
g.write("static const unsigned char _certs_compressed[] = {\n")
|
|
|
|
for i in range(len(buf)):
|
|
|
|
g.write("\t" + byte_to_str(buf[i]) + ",\n")
|
|
|
|
g.write("};\n")
|
|
|
|
g.write("#endif")
|
|
|
|
|
|
|
|
g.close()
|
|
|
|
f.close()
|
2018-03-17 23:23:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
def make_authors_header(target, source, env):
|
|
|
|
sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"]
|
|
|
|
sections_id = ["AUTHORS_FOUNDERS", "AUTHORS_LEAD_DEVELOPERS", "AUTHORS_PROJECT_MANAGERS", "AUTHORS_DEVELOPERS"]
|
|
|
|
|
|
|
|
src = source[0]
|
|
|
|
dst = target[0]
|
|
|
|
f = open_utf8(src, "r")
|
|
|
|
g = open_utf8(dst, "w")
|
|
|
|
|
|
|
|
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
|
|
|
g.write("#ifndef _EDITOR_AUTHORS_H\n")
|
|
|
|
g.write("#define _EDITOR_AUTHORS_H\n")
|
|
|
|
|
|
|
|
reading = False
|
|
|
|
|
|
|
|
def close_section():
|
|
|
|
g.write("\t0\n")
|
|
|
|
g.write("};\n")
|
|
|
|
|
|
|
|
for line in f:
|
|
|
|
if reading:
|
|
|
|
if line.startswith(" "):
|
2020-03-30 08:28:32 +02:00
|
|
|
g.write('\t"' + escape_string(line.strip()) + '",\n')
|
2018-03-17 23:23:55 +01:00
|
|
|
continue
|
|
|
|
if line.startswith("## "):
|
|
|
|
if reading:
|
|
|
|
close_section()
|
|
|
|
reading = False
|
|
|
|
for section, section_id in zip(sections, sections_id):
|
|
|
|
if line.strip().endswith(section):
|
|
|
|
current_section = escape_string(section_id)
|
|
|
|
reading = True
|
|
|
|
g.write("const char *const " + current_section + "[] = {\n")
|
|
|
|
break
|
|
|
|
|
|
|
|
if reading:
|
|
|
|
close_section()
|
|
|
|
|
|
|
|
g.write("#endif\n")
|
|
|
|
|
|
|
|
g.close()
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
def make_donors_header(target, source, env):
|
2020-08-13 23:54:30 +02:00
|
|
|
sections = [
|
2023-11-14 14:34:06 +01:00
|
|
|
"Patrons",
|
2020-08-13 23:54:30 +02:00
|
|
|
"Platinum sponsors",
|
|
|
|
"Gold sponsors",
|
|
|
|
"Silver sponsors",
|
2023-11-14 14:34:06 +01:00
|
|
|
"Diamond members",
|
|
|
|
"Titanium members",
|
|
|
|
"Platinum members",
|
|
|
|
"Gold members",
|
2020-08-13 23:54:30 +02:00
|
|
|
]
|
2020-03-30 08:28:32 +02:00
|
|
|
sections_id = [
|
2023-11-14 14:34:06 +01:00
|
|
|
"DONORS_PATRONS",
|
|
|
|
"DONORS_SPONSORS_PLATINUM",
|
|
|
|
"DONORS_SPONSORS_GOLD",
|
|
|
|
"DONORS_SPONSORS_SILVER",
|
|
|
|
"DONORS_MEMBERS_DIAMOND",
|
|
|
|
"DONORS_MEMBERS_TITANIUM",
|
|
|
|
"DONORS_MEMBERS_PLATINUM",
|
|
|
|
"DONORS_MEMBERS_GOLD",
|
2020-03-30 08:28:32 +02:00
|
|
|
]
|
2018-03-17 23:23:55 +01:00
|
|
|
|
|
|
|
src = source[0]
|
|
|
|
dst = target[0]
|
|
|
|
f = open_utf8(src, "r")
|
|
|
|
g = open_utf8(dst, "w")
|
|
|
|
|
|
|
|
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
|
|
|
g.write("#ifndef _EDITOR_DONORS_H\n")
|
|
|
|
g.write("#define _EDITOR_DONORS_H\n")
|
|
|
|
|
|
|
|
reading = False
|
|
|
|
|
|
|
|
def close_section():
|
|
|
|
g.write("\t0\n")
|
|
|
|
g.write("};\n")
|
|
|
|
|
|
|
|
for line in f:
|
|
|
|
if reading >= 0:
|
|
|
|
if line.startswith(" "):
|
2020-03-30 08:28:32 +02:00
|
|
|
g.write('\t"' + escape_string(line.strip()) + '",\n')
|
2018-03-17 23:23:55 +01:00
|
|
|
continue
|
|
|
|
if line.startswith("## "):
|
|
|
|
if reading:
|
|
|
|
close_section()
|
|
|
|
reading = False
|
|
|
|
for section, section_id in zip(sections, sections_id):
|
|
|
|
if line.strip().endswith(section):
|
|
|
|
current_section = escape_string(section_id)
|
|
|
|
reading = True
|
|
|
|
g.write("const char *const " + current_section + "[] = {\n")
|
|
|
|
break
|
|
|
|
|
|
|
|
if reading:
|
|
|
|
close_section()
|
|
|
|
|
|
|
|
g.write("#endif\n")
|
|
|
|
|
|
|
|
g.close()
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
def make_license_header(target, source, env):
|
|
|
|
src_copyright = source[0]
|
|
|
|
src_license = source[1]
|
|
|
|
dst = target[0]
|
|
|
|
|
|
|
|
class LicenseReader:
|
|
|
|
def __init__(self, license_file):
|
|
|
|
self._license_file = license_file
|
|
|
|
self.line_num = 0
|
|
|
|
self.current = self.next_line()
|
|
|
|
|
|
|
|
def next_line(self):
|
|
|
|
line = self._license_file.readline()
|
|
|
|
self.line_num += 1
|
|
|
|
while line.startswith("#"):
|
|
|
|
line = self._license_file.readline()
|
|
|
|
self.line_num += 1
|
|
|
|
self.current = line
|
|
|
|
return line
|
|
|
|
|
|
|
|
def next_tag(self):
|
2020-03-30 08:28:32 +02:00
|
|
|
if not ":" in self.current:
|
|
|
|
return ("", [])
|
2018-03-17 23:23:55 +01:00
|
|
|
tag, line = self.current.split(":", 1)
|
|
|
|
lines = [line.strip()]
|
|
|
|
while self.next_line() and self.current.startswith(" "):
|
|
|
|
lines.append(self.current.strip())
|
|
|
|
return (tag, lines)
|
|
|
|
|
|
|
|
from collections import OrderedDict
|
2020-03-30 08:28:32 +02:00
|
|
|
|
2018-03-17 23:23:55 +01:00
|
|
|
projects = OrderedDict()
|
|
|
|
license_list = []
|
|
|
|
|
|
|
|
with open_utf8(src_copyright, "r") as copyright_file:
|
|
|
|
reader = LicenseReader(copyright_file)
|
|
|
|
part = {}
|
|
|
|
while reader.current:
|
|
|
|
tag, content = reader.next_tag()
|
|
|
|
if tag in ("Files", "Copyright", "License"):
|
|
|
|
part[tag] = content[:]
|
|
|
|
elif tag == "Comment":
|
|
|
|
# attach part to named project
|
|
|
|
projects[content[0]] = projects.get(content[0], []) + [part]
|
|
|
|
|
|
|
|
if not tag or not reader.current:
|
|
|
|
# end of a paragraph start a new part
|
|
|
|
if "License" in part and not "Files" in part:
|
|
|
|
# no Files tag in this one, so assume standalone license
|
|
|
|
license_list.append(part["License"])
|
|
|
|
part = {}
|
|
|
|
reader.next_line()
|
|
|
|
|
|
|
|
data_list = []
|
|
|
|
for project in itervalues(projects):
|
|
|
|
for part in project:
|
|
|
|
part["file_index"] = len(data_list)
|
|
|
|
data_list += part["Files"]
|
|
|
|
part["copyright_index"] = len(data_list)
|
|
|
|
data_list += part["Copyright"]
|
|
|
|
|
|
|
|
with open_utf8(dst, "w") as f:
|
|
|
|
|
|
|
|
f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
|
|
|
f.write("#ifndef _EDITOR_LICENSE_H\n")
|
|
|
|
f.write("#define _EDITOR_LICENSE_H\n")
|
|
|
|
f.write("const char *const GODOT_LICENSE_TEXT =")
|
|
|
|
|
|
|
|
with open_utf8(src_license, "r") as license_file:
|
|
|
|
for line in license_file:
|
|
|
|
escaped_string = escape_string(line.strip())
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write('\n\t\t"' + escaped_string + '\\n"')
|
2018-03-17 23:23:55 +01:00
|
|
|
f.write(";\n\n")
|
|
|
|
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write(
|
|
|
|
"struct ComponentCopyrightPart {\n"
|
|
|
|
"\tconst char *license;\n"
|
|
|
|
"\tconst char *const *files;\n"
|
|
|
|
"\tconst char *const *copyright_statements;\n"
|
|
|
|
"\tint file_count;\n"
|
|
|
|
"\tint copyright_count;\n"
|
|
|
|
"};\n\n"
|
|
|
|
)
|
|
|
|
|
|
|
|
f.write(
|
|
|
|
"struct ComponentCopyright {\n"
|
|
|
|
"\tconst char *name;\n"
|
|
|
|
"\tconst ComponentCopyrightPart *parts;\n"
|
|
|
|
"\tint part_count;\n"
|
|
|
|
"};\n\n"
|
|
|
|
)
|
2018-03-17 23:23:55 +01:00
|
|
|
|
|
|
|
f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n")
|
|
|
|
for line in data_list:
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write('\t"' + escape_string(line) + '",\n')
|
2018-03-17 23:23:55 +01:00
|
|
|
f.write("};\n\n")
|
|
|
|
|
|
|
|
f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n")
|
|
|
|
part_index = 0
|
|
|
|
part_indexes = {}
|
|
|
|
for project_name, project in iteritems(projects):
|
|
|
|
part_indexes[project_name] = part_index
|
|
|
|
for part in project:
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write(
|
|
|
|
'\t{ "'
|
|
|
|
+ escape_string(part["License"][0])
|
|
|
|
+ '", '
|
|
|
|
+ "©RIGHT_INFO_DATA["
|
|
|
|
+ str(part["file_index"])
|
|
|
|
+ "], "
|
|
|
|
+ "©RIGHT_INFO_DATA["
|
|
|
|
+ str(part["copyright_index"])
|
|
|
|
+ "], "
|
|
|
|
+ str(len(part["Files"]))
|
|
|
|
+ ", "
|
|
|
|
+ str(len(part["Copyright"]))
|
|
|
|
+ " },\n"
|
|
|
|
)
|
2018-03-17 23:23:55 +01:00
|
|
|
part_index += 1
|
|
|
|
f.write("};\n\n")
|
|
|
|
|
|
|
|
f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n")
|
|
|
|
|
|
|
|
f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n")
|
|
|
|
for project_name, project in iteritems(projects):
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write(
|
|
|
|
'\t{ "'
|
|
|
|
+ escape_string(project_name)
|
|
|
|
+ '", '
|
|
|
|
+ "©RIGHT_PROJECT_PARTS["
|
|
|
|
+ str(part_indexes[project_name])
|
|
|
|
+ "], "
|
|
|
|
+ str(len(project))
|
|
|
|
+ " },\n"
|
|
|
|
)
|
2018-03-17 23:23:55 +01:00
|
|
|
f.write("};\n\n")
|
|
|
|
|
|
|
|
f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n")
|
|
|
|
|
|
|
|
f.write("const char *const LICENSE_NAMES[] = {\n")
|
|
|
|
for l in license_list:
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write('\t"' + escape_string(l[0]) + '",\n')
|
2018-03-17 23:23:55 +01:00
|
|
|
f.write("};\n\n")
|
|
|
|
|
|
|
|
f.write("const char *const LICENSE_BODIES[] = {\n\n")
|
|
|
|
for l in license_list:
|
|
|
|
for line in l[1:]:
|
|
|
|
if line == ".":
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write('\t"\\n"\n')
|
2018-03-17 23:23:55 +01:00
|
|
|
else:
|
2020-03-30 08:28:32 +02:00
|
|
|
f.write('\t"' + escape_string(line) + '\\n"\n')
|
|
|
|
f.write('\t"",\n\n')
|
2018-03-17 23:23:55 +01:00
|
|
|
f.write("};\n\n")
|
|
|
|
|
|
|
|
f.write("#endif\n")
|
|
|
|
|
|
|
|
|
2020-03-30 08:28:32 +02:00
|
|
|
if __name__ == "__main__":
|
2018-03-17 23:23:55 +01:00
|
|
|
subprocess_main(globals())
|