@@ -36,6 +36,8 @@
help='Version string to use')
parser.add_argument('--extra-prebuild-script',
help='Extra script to run after creating virtualenv.')
+ parser.add_argument('--extra-wxs',
+ help='CSV of path_to_wxs_file=working_dir_for_wxs_file')
args = parser.parse_args()
@@ -58,6 +60,9 @@
if args.extra_prebuild_script:
kwargs['extra_prebuild_script'] = args.extra_prebuild_script
+ if args.extra_wxs:
+ kwargs['extra_wxs'] = dict(
+ thing.split("=") for thing in args.extra_wxs.split(','))
if args.sign_sn or args.sign_cert:
fn = build_signed_installer
@@ -12,6 +12,7 @@
import re
import subprocess
import tempfile
+import typing
import xml.dom.minidom
from .downloads import (
@@ -178,7 +179,8 @@
def build_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
msi_name='mercurial', version=None, post_build_fn=None,
- extra_prebuild_script=None):
+ extra_prebuild_script=None,
+ extra_wxs:typing.Optional[typing.Dict[str,str]]=None):
"""Build a WiX MSI installer.
``source_dir`` is the path to the Mercurial source tree to use.
@@ -190,6 +192,7 @@
Mercurial but before invoking WiX. It can be used to e.g. facilitate
signing. It is passed the paths to the Mercurial source, build, and
dist directories and the resolved Mercurial version.
+ ``extra_wxs`` is a dict of {wxs_name: working_dir_for_wxs_build}.
"""
arch = 'x64' if r'\x64' in os.environ.get('LIB', '') else 'x86'
@@ -231,6 +234,9 @@
wxs_source_dir = source_dir / rel_path
run_candle(wix_path, build_dir, wxs, wxs_source_dir, defines=defines)
+ for source, rel_path in sorted((extra_wxs or {}).items()):
+ run_candle(wix_path, build_dir, source, rel_path, defines=defines)
+
# candle.exe doesn't like when we have an open handle on the file.
# So use TemporaryDirectory() instead of NamedTemporaryFile().
with tempfile.TemporaryDirectory() as td:
@@ -265,6 +271,11 @@
assert source.endswith('.wxs')
args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
+ for source, rel_path in sorted((extra_wxs or {}).items()):
+ assert source.endswith('.wxs')
+ source = os.path.basename(source)
+ args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
+
args.extend([
str(build_dir / 'library.wixobj'),
str(build_dir / 'mercurial.wixobj'),
@@ -282,7 +293,8 @@
def build_signed_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
name: str, version=None, subject_name=None,
cert_path=None, cert_password=None,
- timestamp_url=None, extra_prebuild_script=None):
+ timestamp_url=None, extra_prebuild_script=None,
+ extra_wxs=None):
"""Build an installer with signed executables."""
post_build_fn = make_post_build_signing_fn(
@@ -295,7 +307,8 @@
info = build_installer(source_dir, python_exe=python_exe,
msi_name=name.lower(), version=version,
post_build_fn=post_build_fn,
- extra_prebuild_script=extra_prebuild_script)
+ extra_prebuild_script=extra_prebuild_script,
+ extra_wxs=extra_wxs)
description = '%s %s' % (name, version)