##// END OF EJS Templates
wix: autogenerate wxs file for library files...
Gregory Szorc -
r42123:131d0b7c default
parent child Browse files
Show More
@@ -11,6 +11,8 b' import os'
11 import pathlib
11 import pathlib
12 import re
12 import re
13 import subprocess
13 import subprocess
14 import tempfile
15 import xml.dom.minidom
14
16
15 from .downloads import (
17 from .downloads import (
16 download_entry,
18 download_entry,
@@ -128,6 +130,52 b' def make_post_build_signing_fn(name, sub'
128 return post_build_sign
130 return post_build_sign
129
131
130
132
133 LIBRARIES_XML = '''
134 <?xml version="1.0" encoding="utf-8"?>
135 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
136
137 <?include {wix_dir}/guids.wxi ?>
138 <?include {wix_dir}/defines.wxi ?>
139
140 <Fragment>
141 <DirectoryRef Id="INSTALLDIR" FileSource="$(var.SourceDir)">
142 <Directory Id="libdir" Name="lib" FileSource="$(var.SourceDir)/lib">
143 <Component Id="libOutput" Guid="$(var.lib.guid)" Win64='$(var.IsX64)'>
144 </Component>
145 </Directory>
146 </DirectoryRef>
147 </Fragment>
148 </Wix>
149 '''.lstrip()
150
151
152 def make_libraries_xml(wix_dir: pathlib.Path, dist_dir: pathlib.Path):
153 """Make XML data for library components WXS."""
154 # We can't use ElementTree because it doesn't handle the
155 # <?include ?> directives.
156 doc = xml.dom.minidom.parseString(
157 LIBRARIES_XML.format(wix_dir=str(wix_dir)))
158
159 component = doc.getElementsByTagName('Component')[0]
160
161 f = doc.createElement('File')
162 f.setAttribute('Name', 'library.zip')
163 f.setAttribute('KeyPath', 'yes')
164 component.appendChild(f)
165
166 lib_dir = dist_dir / 'lib'
167
168 for p in sorted(lib_dir.iterdir()):
169 if not p.name.endswith(('.dll', '.pyd')):
170 continue
171
172 f = doc.createElement('File')
173 f.setAttribute('Name', p.name)
174 component.appendChild(f)
175
176 return doc.toprettyxml()
177
178
131 def build_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
179 def build_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
132 msi_name='mercurial', version=None, post_build_fn=None):
180 msi_name='mercurial', version=None, post_build_fn=None):
133 """Build a WiX MSI installer.
181 """Build a WiX MSI installer.
@@ -181,6 +229,17 b' def build_installer(source_dir: pathlib.'
181 wxs_source_dir = source_dir / rel_path
229 wxs_source_dir = source_dir / rel_path
182 run_candle(wix_path, build_dir, wxs, wxs_source_dir, defines=defines)
230 run_candle(wix_path, build_dir, wxs, wxs_source_dir, defines=defines)
183
231
232 # candle.exe doesn't like when we have an open handle on the file.
233 # So use TemporaryDirectory() instead of NamedTemporaryFile().
234 with tempfile.TemporaryDirectory() as td:
235 td = pathlib.Path(td)
236
237 tf = td / 'library.wxs'
238 with tf.open('w') as fh:
239 fh.write(make_libraries_xml(wix_dir, dist_dir))
240
241 run_candle(wix_path, build_dir, tf, dist_dir, defines=defines)
242
184 source = wix_dir / 'mercurial.wxs'
243 source = wix_dir / 'mercurial.wxs'
185 defines['Version'] = version
244 defines['Version'] = version
186 defines['Comments'] = 'Installs Mercurial version %s' % version
245 defines['Comments'] = 'Installs Mercurial version %s' % version
@@ -204,7 +263,10 b' def build_installer(source_dir: pathlib.'
204 assert source.endswith('.wxs')
263 assert source.endswith('.wxs')
205 args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
264 args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
206
265
207 args.append(str(build_dir / 'mercurial.wixobj'))
266 args.extend([
267 str(build_dir / 'library.wixobj'),
268 str(build_dir / 'mercurial.wixobj'),
269 ])
208
270
209 subprocess.run(args, cwd=str(source_dir), check=True)
271 subprocess.run(args, cwd=str(source_dir), check=True)
210
272
@@ -9,35 +9,6 b''
9 <Component Id="distOutput" Guid="$(var.dist.guid)" Win64='$(var.IsX64)'>
9 <Component Id="distOutput" Guid="$(var.dist.guid)" Win64='$(var.IsX64)'>
10 <File Name="python27.dll" KeyPath="yes" />
10 <File Name="python27.dll" KeyPath="yes" />
11 </Component>
11 </Component>
12 <Directory Id="libdir" Name="lib" FileSource="$(var.SourceDir)/lib">
13 <Component Id="libOutput" Guid="$(var.lib.guid)" Win64='$(var.IsX64)'>
14 <File Name="library.zip" KeyPath="yes" />
15 <File Name="mercurial.cext.base85.pyd" />
16 <File Name="mercurial.cext.bdiff.pyd" />
17 <File Name="mercurial.cext.mpatch.pyd" />
18 <File Name="mercurial.cext.osutil.pyd" />
19 <File Name="mercurial.cext.parsers.pyd" />
20 <File Name="mercurial.thirdparty.zope.interface._zope_interface_coptimizations.pyd" />
21 <File Name="mercurial.zstd.pyd" />
22 <File Name="hgext.fsmonitor.pywatchman.bser.pyd" />
23 <File Name="pyexpat.pyd" />
24 <File Name="bz2.pyd" />
25 <File Name="select.pyd" />
26 <File Name="sqlite3.dll" />
27 <File Name="tcl85.dll" />
28 <File Name="tk85.dll" />
29 <File Name="unicodedata.pyd" />
30 <File Name="_ctypes.pyd" />
31 <File Name="_elementtree.pyd" />
32 <File Name="_testcapi.pyd" />
33 <File Name="_hashlib.pyd" />
34 <File Name="_multiprocessing.pyd" />
35 <File Name="_socket.pyd" />
36 <File Name="_sqlite3.pyd" />
37 <File Name="_ssl.pyd" />
38 <File Name="_tkinter.pyd" />
39 </Component>
40 </Directory>
41 </DirectoryRef>
12 </DirectoryRef>
42 </Fragment>
13 </Fragment>
43
14
General Comments 0
You need to be logged in to leave comments. Login now