##// END OF EJS Templates
packaging: support building WiX installers with PyOxidizer...
Gregory Szorc -
r45260:c9517d9d default draft
parent child Browse files
Show More
@@ -50,6 +50,7 b' def build_inno(pyoxidizer_target=None, p'
50
50
51 def build_wix(
51 def build_wix(
52 name=None,
52 name=None,
53 pyoxidizer_target=None,
53 python=None,
54 python=None,
54 version=None,
55 version=None,
55 sign_sn=None,
56 sign_sn=None,
@@ -60,16 +61,29 b' def build_wix('
60 extra_wxs=None,
61 extra_wxs=None,
61 extra_features=None,
62 extra_features=None,
62 ):
63 ):
64 if not pyoxidizer_target and not python:
65 raise Exception("--python required unless building with PyOxidizer")
66
67 if python and not os.path.isabs(python):
68 raise Exception("--python arg must be an absolute path")
69
63 kwargs = {
70 kwargs = {
64 "source_dir": SOURCE_DIR,
71 "source_dir": SOURCE_DIR,
65 "python_exe": pathlib.Path(python),
66 "version": version,
72 "version": version,
67 }
73 }
68
74
69 if not os.path.isabs(python):
75 if pyoxidizer_target:
70 raise Exception("--python arg must be an absolute path")
76 fn = wix.build_installer_pyoxidizer
77 kwargs["target_triple"] = pyoxidizer_target
78 else:
79 fn = wix.build_installer_py2exe
80 kwargs["python_exe"] = pathlib.Path(python)
71
81
72 if extra_packages_script:
82 if extra_packages_script:
83 if pyoxidizer_target:
84 raise Exception(
85 "pyoxidizer does not support --extra-packages-script"
86 )
73 kwargs["extra_packages_script"] = extra_packages_script
87 kwargs["extra_packages_script"] = extra_packages_script
74 if extra_wxs:
88 if extra_wxs:
75 kwargs["extra_wxs"] = dict(
89 kwargs["extra_wxs"] = dict(
@@ -87,7 +101,7 b' def build_wix('
87 "timestamp_url": sign_timestamp_url,
101 "timestamp_url": sign_timestamp_url,
88 }
102 }
89
103
90 wix.build_installer(**kwargs)
104 fn(**kwargs)
91
105
92
106
93 def get_parser():
107 def get_parser():
@@ -115,8 +129,11 b' def get_parser():'
115 )
129 )
116 sp.add_argument("--name", help="Application name", default="Mercurial")
130 sp.add_argument("--name", help="Application name", default="Mercurial")
117 sp.add_argument(
131 sp.add_argument(
118 "--python", help="Path to Python executable to use", required=True
132 "--pyoxidizer-target",
133 choices={"i686-pc-windows-msvc", "x86_64-pc-windows-msvc"},
134 help="Build with PyOxidizer targeting this host triple",
119 )
135 )
136 sp.add_argument("--python", help="Path to Python executable to use")
120 sp.add_argument(
137 sp.add_argument(
121 "--sign-sn",
138 "--sign-sn",
122 help="Subject name (or fragment thereof) of certificate "
139 help="Subject name (or fragment thereof) of certificate "
@@ -22,6 +22,7 b' from .py2exe import ('
22 build_py2exe,
22 build_py2exe,
23 stage_install,
23 stage_install,
24 )
24 )
25 from .pyoxidizer import run_pyoxidizer
25 from .util import (
26 from .util import (
26 extract_zip_to_directory,
27 extract_zip_to_directory,
27 normalize_windows_version,
28 normalize_windows_version,
@@ -284,7 +285,7 b' def make_files_xml(staging_dir: pathlib.'
284 return doc.toprettyxml()
285 return doc.toprettyxml()
285
286
286
287
287 def build_installer(
288 def build_installer_py2exe(
288 source_dir: pathlib.Path,
289 source_dir: pathlib.Path,
289 python_exe: pathlib.Path,
290 python_exe: pathlib.Path,
290 msi_name='mercurial',
291 msi_name='mercurial',
@@ -294,7 +295,7 b' def build_installer('
294 extra_features: typing.Optional[typing.List[str]] = None,
295 extra_features: typing.Optional[typing.List[str]] = None,
295 signing_info: typing.Optional[typing.Dict[str, str]] = None,
296 signing_info: typing.Optional[typing.Dict[str, str]] = None,
296 ):
297 ):
297 """Build a WiX MSI installer.
298 """Build a WiX MSI installer using py2exe.
298
299
299 ``source_dir`` is the path to the Mercurial source tree to use.
300 ``source_dir`` is the path to the Mercurial source tree to use.
300 ``arch`` is the target architecture. either ``x86`` or ``x64``.
301 ``arch`` is the target architecture. either ``x86`` or ``x64``.
@@ -355,6 +356,50 b' def build_installer('
355 staging_dir,
356 staging_dir,
356 arch,
357 arch,
357 version=version,
358 version=version,
359 python2=True,
360 msi_name=msi_name,
361 extra_wxs=extra_wxs,
362 extra_features=extra_features,
363 signing_info=signing_info,
364 )
365
366
367 def build_installer_pyoxidizer(
368 source_dir: pathlib.Path,
369 target_triple: str,
370 msi_name='mercurial',
371 version=None,
372 extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
373 extra_features: typing.Optional[typing.List[str]] = None,
374 signing_info: typing.Optional[typing.Dict[str, str]] = None,
375 ):
376 """Build a WiX MSI installer using PyOxidizer."""
377 hg_build_dir = source_dir / "build"
378 build_dir = hg_build_dir / ("wix-%s" % target_triple)
379 staging_dir = build_dir / "stage"
380
381 arch = "x64" if "x86_64" in target_triple else "x86"
382
383 build_dir.mkdir(parents=True, exist_ok=True)
384 run_pyoxidizer(source_dir, build_dir, staging_dir, target_triple)
385
386 # We also install some extra files.
387 process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir)
388
389 # And remove some files we don't want.
390 for f in STAGING_REMOVE_FILES:
391 p = staging_dir / f
392 if p.exists():
393 print('removing %s' % p)
394 p.unlink()
395
396 return run_wix_packaging(
397 source_dir,
398 build_dir,
399 staging_dir,
400 arch,
401 version,
402 python2=False,
358 msi_name=msi_name,
403 msi_name=msi_name,
359 extra_wxs=extra_wxs,
404 extra_wxs=extra_wxs,
360 extra_features=extra_features,
405 extra_features=extra_features,
@@ -368,6 +413,7 b' def run_wix_packaging('
368 staging_dir: pathlib.Path,
413 staging_dir: pathlib.Path,
369 arch: str,
414 arch: str,
370 version: str,
415 version: str,
416 python2: bool,
371 msi_name: typing.Optional[str] = "mercurial",
417 msi_name: typing.Optional[str] = "mercurial",
372 extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
418 extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
373 extra_features: typing.Optional[typing.List[str]] = None,
419 extra_features: typing.Optional[typing.List[str]] = None,
@@ -406,7 +452,8 b' def run_wix_packaging('
406 if not wix_path.exists():
452 if not wix_path.exists():
407 extract_zip_to_directory(wix_pkg, wix_path)
453 extract_zip_to_directory(wix_pkg, wix_path)
408
454
409 ensure_vc90_merge_modules(build_dir)
455 if python2:
456 ensure_vc90_merge_modules(build_dir)
410
457
411 source_build_rel = pathlib.Path(os.path.relpath(source_dir, build_dir))
458 source_build_rel = pathlib.Path(os.path.relpath(source_dir, build_dir))
412
459
@@ -425,7 +472,16 b' def run_wix_packaging('
425 source = wix_dir / 'mercurial.wxs'
472 source = wix_dir / 'mercurial.wxs'
426 defines['Version'] = version
473 defines['Version'] = version
427 defines['Comments'] = 'Installs Mercurial version %s' % version
474 defines['Comments'] = 'Installs Mercurial version %s' % version
428 defines['VCRedistSrcDir'] = str(build_dir)
475
476 if python2:
477 defines["PythonVersion"] = "2"
478 defines['VCRedistSrcDir'] = str(build_dir)
479 else:
480 defines["PythonVersion"] = "3"
481
482 if (staging_dir / "lib").exists():
483 defines["MercurialHasLib"] = "1"
484
429 if extra_features:
485 if extra_features:
430 assert all(';' not in f for f in extra_features)
486 assert all(';' not in f for f in extra_features)
431 defines['MercurialExtraFeatures'] = ';'.join(extra_features)
487 defines['MercurialExtraFeatures'] = ';'.join(extra_features)
@@ -79,16 +79,21 b''
79 </Directory>
79 </Directory>
80 </Directory>
80 </Directory>
81
81
82 <?if $(var.Platform) = "x86" ?>
82 <!-- Install VCRedist merge modules on Python 2. On Python 3,
83 <Merge Id='VCRuntime' DiskId='1' Language='1033'
83 vcruntimeXXX.dll is part of the install layout and gets picked up
84 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x86_msm.msm' />
84 as a regular file. -->
85 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
85 <?if $(var.PythonVersion) = "2" ?>
86 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x86_msm.msm' />
86 <?if $(var.Platform) = "x86" ?>
87 <?else?>
87 <Merge Id='VCRuntime' DiskId='1' Language='1033'
88 <Merge Id='VCRuntime' DiskId='1' Language='1033'
88 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x86_msm.msm' />
89 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x64_msm.msm' />
89 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
90 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
90 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x86_msm.msm' />
91 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x64_msm.msm' />
91 <?else?>
92 <Merge Id='VCRuntime' DiskId='1' Language='1033'
93 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x64_msm.msm' />
94 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
95 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x64_msm.msm' />
96 <?endif?>
92 <?endif?>
97 <?endif?>
93 </Directory>
98 </Directory>
94
99
@@ -101,10 +106,14 b''
101 <ComponentGroupRef Id="hg.group.ROOT" />
106 <ComponentGroupRef Id="hg.group.ROOT" />
102 <ComponentGroupRef Id="hg.group.defaultrc" />
107 <ComponentGroupRef Id="hg.group.defaultrc" />
103 <ComponentGroupRef Id="hg.group.helptext" />
108 <ComponentGroupRef Id="hg.group.helptext" />
104 <ComponentGroupRef Id="hg.group.lib" />
109 <?ifdef MercurialHasLib?>
110 <ComponentGroupRef Id="hg.group.lib" />
111 <?endif?>
105 <ComponentGroupRef Id="hg.group.templates" />
112 <ComponentGroupRef Id="hg.group.templates" />
106 <MergeRef Id='VCRuntime' />
113 <?if $(var.PythonVersion) = "2" ?>
107 <MergeRef Id='VCRuntimePolicy' />
114 <MergeRef Id='VCRuntime' />
115 <MergeRef Id='VCRuntimePolicy' />
116 <?endif?>
108 </Feature>
117 </Feature>
109 <?ifdef MercurialExtraFeatures?>
118 <?ifdef MercurialExtraFeatures?>
110 <?foreach EXTRAFEAT in $(var.MercurialExtraFeatures)?>
119 <?foreach EXTRAFEAT in $(var.MercurialExtraFeatures)?>
General Comments 0
You need to be logged in to leave comments. Login now