1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 from datetime
import datetime
11 from mozbuild
.preprocessor
import Preprocessor
14 // This Source Code Form is subject to the terms of the Mozilla Public
15 // License, v. 2.0. If a copy of the MPL was not distributed with this
16 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
21 // Note: if you contain versioning information in an included
22 // RC script, it will be discarded
23 // Use module.ver to explicitly set these values
25 // Do not edit this file. Changes won't affect the build.
30 /////////////////////////////////////////////////////////////////////////////
36 FILEVERSION {fileversion}
37 PRODUCTVERSION {productversion}
44 BLOCK "StringFileInfo"
48 VALUE "Comments", "{comment}"
49 VALUE "LegalCopyright", "{copyright}"
50 VALUE "CompanyName", "{company}"
51 VALUE "FileDescription", "{description}"
52 VALUE "FileVersion", "{mfversion}"
53 VALUE "ProductVersion", "{mpversion}"
54 VALUE "InternalName", "{module}"
55 VALUE "LegalTrademarks", "{trademarks}"
56 VALUE "OriginalFilename", "{binary}"
57 VALUE "ProductName", "{productname}"
58 VALUE "BuildID", "{buildid}"
63 VALUE "Translation", 0x0, 1200
70 def preprocess(path
, defines
):
71 pp
= Preprocessor(defines
=defines
, marker
="%")
72 pp
.context
.update(defines
)
73 pp
.out
= io
.StringIO()
74 pp
.do_filter("substitution")
75 pp
.do_include(io
.open(path
, "r", encoding
="latin1"))
80 def parse_module_ver(path
, defines
):
82 for line
in preprocess(path
, defines
):
83 content
, *comment
= line
.split("#", 1)
84 if not content
.strip():
86 entry
, value
= content
.split("=", 1)
87 result
[entry
.strip()] = value
.strip()
92 path
= os
.path
.join(buildconfig
.topobjdir
, "buildid.h")
93 define
, MOZ_BUILDID
, buildid
= io
.open(path
, "r", encoding
="utf-8").read().split()
97 def days_from_2000_to_buildid(buildid
):
98 start
= datetime(2000, 1, 1, 0, 0, 0)
99 buildid_time
= datetime
.strptime(buildid
, "%Y%m%d%H%M%S")
100 return (buildid_time
- start
).days
104 for l
in range(len(s
), 0, -1):
110 def split_and_normalize_version(version
, len):
111 return ([digits_only(x
) for x
in version
.split(".")] + ["0"] * len)[:len]
114 def has_manifest(module_rc
, manifest_id
):
115 for line
in module_rc
.splitlines():
116 line
= line
.split(None, 2)
119 id, what
, *rest
= line
120 if id == manifest_id
and what
in ("24", "RT_MANIFEST"):
125 def generate_module_rc(binary
="", rcinclude
=None):
127 buildid
= get_buildid()
128 milestone
= buildconfig
.substs
["GRE_MILESTONE"]
129 app_version
= buildconfig
.substs
.get("MOZ_APP_VERSION") or milestone
130 app_winversion
= ",".join(split_and_normalize_version(app_version
, 4))
131 milestone_winversion
= ",".join(
132 split_and_normalize_version(milestone
, 3)
133 + [str(days_from_2000_to_buildid(buildid
))]
135 display_name
= buildconfig
.substs
.get("MOZ_APP_DISPLAYNAME", "Mozilla")
137 milestone_string
= milestone
140 if buildconfig
.substs
.get("MOZ_DEBUG"):
141 flags
.append("VS_FF_DEBUG")
142 milestone_string
+= " Debug"
143 if not buildconfig
.substs
.get("MOZILLA_OFFICIAL"):
144 flags
.append("VS_FF_PRIVATEBUILD")
145 if buildconfig
.substs
.get("NIGHTLY_BUILD"):
146 flags
.append("VS_FF_PRERELEASE")
149 "MOZ_APP_DISPLAYNAME": display_name
,
150 "MOZ_APP_VERSION": app_version
,
151 "MOZ_APP_WINVERSION": app_winversion
,
154 relobjdir
= os
.path
.relpath(".", buildconfig
.topobjdir
)
155 srcdir
= os
.path
.join(buildconfig
.topsrcdir
, relobjdir
)
156 module_ver
= os
.path
.join(srcdir
, "module.ver")
157 if os
.path
.exists(module_ver
):
159 overrides
= parse_module_ver(module_ver
, defines
)
164 include
= "// From included resource {}\n{}".format(
165 rcinclude
, preprocess(rcinclude
, defines
).read()
170 data
= TEMPLATE
.format(
172 fileversion
=overrides
.get("WIN32_MODULE_FILEVERSION", milestone_winversion
),
173 productversion
=overrides
.get(
174 "WIN32_MODULE_PRODUCTVERSION", milestone_winversion
176 fileflags
=" | ".join(flags
),
177 comment
=overrides
.get("WIN32_MODULE_COMMENT", ""),
178 copyright
=overrides
.get("WIN32_MODULE_COPYRIGHT", "License: MPL 2"),
179 company
=overrides
.get("WIN32_MODULE_COMPANYNAME", "Mozilla Foundation"),
180 description
=overrides
.get("WIN32_MODULE_DESCRIPTION", ""),
181 mfversion
=overrides
.get("WIN32_MODULE_FILEVERSION_STRING", milestone_string
),
182 mpversion
=overrides
.get("WIN32_MODULE_PRODUCTVERSION_STRING", milestone_string
),
183 module
=overrides
.get("WIN32_MODULE_NAME", ""),
184 trademarks
=overrides
.get("WIN32_MODULE_TRADEMARKS", "Mozilla"),
185 binary
=overrides
.get("WIN32_MODULE_ORIGINAL_FILENAME", binary
),
186 productname
=overrides
.get("WIN32_MODULE_PRODUCTNAME", display_name
),
190 manifest_id
= "2" if binary
.lower().endswith(".dll") else "1"
191 if binary
and not has_manifest(data
, manifest_id
):
192 manifest_path
= os
.path
.join(srcdir
, binary
+ ".manifest")
193 if os
.path
.exists(manifest_path
):
194 manifest_path
= manifest_path
.replace("\\", "\\\\")
195 data
+= '\n{} RT_MANIFEST "{}"\n'.format(manifest_id
, manifest_path
)
197 with io
.open("{}.rc".format(binary
or "module"), "w", encoding
="latin1") as fh
:
201 if __name__
== "__main__":
202 generate_module_rc(*sys
.argv
[1:])