diff options
Diffstat (limited to 'config/create_rc.py')
-rw-r--r-- | config/create_rc.py | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/config/create_rc.py b/config/create_rc.py new file mode 100644 index 0000000000..d75959d4e0 --- /dev/null +++ b/config/create_rc.py @@ -0,0 +1,202 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import io +import os +import sys +from datetime import datetime + +import buildconfig +from mozbuild.preprocessor import Preprocessor + +TEMPLATE = """ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include<winuser.h> +#include<winver.h> + +// Note: if you contain versioning information in an included +// RC script, it will be discarded +// Use module.ver to explicitly set these values + +// Do not edit this file. Changes won't affect the build. + +{include} + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +1 VERSIONINFO + FILEVERSION {fileversion} + PRODUCTVERSION {productversion} + FILEFLAGSMASK 0x3fL + FILEFLAGS {fileflags} + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "{comment}" + VALUE "LegalCopyright", "{copyright}" + VALUE "CompanyName", "{company}" + VALUE "FileDescription", "{description}" + VALUE "FileVersion", "{mfversion}" + VALUE "ProductVersion", "{mpversion}" + VALUE "InternalName", "{module}" + VALUE "LegalTrademarks", "{trademarks}" + VALUE "OriginalFilename", "{binary}" + VALUE "ProductName", "{productname}" + VALUE "BuildID", "{buildid}" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +""" + + +def preprocess(path, defines): + pp = Preprocessor(defines=defines, marker="%") + pp.context.update(defines) + pp.out = io.StringIO() + pp.do_filter("substitution") + pp.do_include(io.open(path, "r", encoding="latin1")) + pp.out.seek(0) + return pp.out + + +def parse_module_ver(path, defines): + result = {} + for line in preprocess(path, defines): + content, *comment = line.split("#", 1) + if not content.strip(): + continue + entry, value = content.split("=", 1) + result[entry.strip()] = value.strip() + return result + + +def get_buildid(): + path = os.path.join(buildconfig.topobjdir, "buildid.h") + define, MOZ_BUILDID, buildid = io.open(path, "r", encoding="utf-8").read().split() + return buildid + + +def days_from_2000_to_buildid(buildid): + start = datetime(2000, 1, 1, 0, 0, 0) + buildid_time = datetime.strptime(buildid, "%Y%m%d%H%M%S") + return (buildid_time - start).days + + +def digits_only(s): + for l in range(len(s), 0, -1): + if s[:l].isdigit(): + return s[:l] + return "0" + + +def split_and_normalize_version(version, len): + return ([digits_only(x) for x in version.split(".")] + ["0"] * len)[:len] + + +def has_manifest(module_rc, manifest_id): + for line in module_rc.splitlines(): + line = line.split(None, 2) + if len(line) < 2: + continue + id, what, *rest = line + if id == manifest_id and what in ("24", "RT_MANIFEST"): + return True + return False + + +def generate_module_rc(binary="", rcinclude=None): + deps = set() + buildid = get_buildid() + milestone = buildconfig.substs["GRE_MILESTONE"] + app_version = buildconfig.substs.get("MOZ_APP_VERSION") or milestone + app_winversion = ",".join(split_and_normalize_version(app_version, 4)) + milestone_winversion = ",".join( + split_and_normalize_version(milestone, 3) + + [str(days_from_2000_to_buildid(buildid))] + ) + display_name = buildconfig.substs.get("MOZ_APP_DISPLAYNAME", "Mozilla") + + milestone_string = milestone + + flags = ["0"] + if buildconfig.substs.get("MOZ_DEBUG"): + flags.append("VS_FF_DEBUG") + milestone_string += " Debug" + if not buildconfig.substs.get("MOZILLA_OFFICIAL"): + flags.append("VS_FF_PRIVATEBUILD") + if buildconfig.substs.get("NIGHTLY_BUILD"): + flags.append("VS_FF_PRERELEASE") + + defines = { + "MOZ_APP_DISPLAYNAME": display_name, + "MOZ_APP_VERSION": app_version, + "MOZ_APP_WINVERSION": app_winversion, + } + + relobjdir = os.path.relpath(".", buildconfig.topobjdir) + srcdir = os.path.join(buildconfig.topsrcdir, relobjdir) + module_ver = os.path.join(srcdir, "module.ver") + if os.path.exists(module_ver): + deps.add(module_ver) + overrides = parse_module_ver(module_ver, defines) + else: + overrides = {} + + if rcinclude: + include = "// From included resource {}\n{}".format( + rcinclude, preprocess(rcinclude, defines).read() + ) + else: + include = "" + + data = TEMPLATE.format( + include=include, + fileversion=overrides.get("WIN32_MODULE_FILEVERSION", milestone_winversion), + productversion=overrides.get( + "WIN32_MODULE_PRODUCTVERSION", milestone_winversion + ), + fileflags=" | ".join(flags), + comment=overrides.get("WIN32_MODULE_COMMENT", ""), + copyright=overrides.get("WIN32_MODULE_COPYRIGHT", "License: MPL 2"), + company=overrides.get("WIN32_MODULE_COMPANYNAME", "Mozilla Foundation"), + description=overrides.get("WIN32_MODULE_DESCRIPTION", ""), + mfversion=overrides.get("WIN32_MODULE_FILEVERSION_STRING", milestone_string), + mpversion=overrides.get("WIN32_MODULE_PRODUCTVERSION_STRING", milestone_string), + module=overrides.get("WIN32_MODULE_NAME", ""), + trademarks=overrides.get("WIN32_MODULE_TRADEMARKS", "Mozilla"), + binary=overrides.get("WIN32_MODULE_ORIGINAL_FILENAME", binary), + productname=overrides.get("WIN32_MODULE_PRODUCTNAME", display_name), + buildid=buildid, + ) + + manifest_id = "2" if binary.lower().endswith(".dll") else "1" + if binary and not has_manifest(data, manifest_id): + manifest_path = os.path.join(srcdir, binary + ".manifest") + if os.path.exists(manifest_path): + manifest_path = manifest_path.replace("\\", "\\\\") + data += '\n{} RT_MANIFEST "{}"\n'.format(manifest_id, manifest_path) + + with io.open("{}.rc".format(binary or "module"), "w", encoding="latin1") as fh: + fh.write(data) + + +if __name__ == "__main__": + generate_module_rc(*sys.argv[1:]) |