##// END OF EJS Templates
pyoxidizer: support producing MSI installers...
Gregory Szorc -
r47976:603efb38 default
parent child Browse files
Show More
@@ -1,153 +1,157 b''
1 1 <?xml version='1.0' encoding='windows-1252'?>
2 2 <Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
3 3
4 4 <!-- Copyright 2010 Steve Borho <steve@borho.org>
5 5
6 6 This software may be used and distributed according to the terms of the
7 7 GNU General Public License version 2 or any later version. -->
8 8
9 9 <?include guids.wxi ?>
10 10 <?include defines.wxi ?>
11 11
12 12 <?if $(var.Platform) = "x64" ?>
13 13 <?define PFolder = ProgramFiles64Folder ?>
14 14 <?else?>
15 15 <?define PFolder = ProgramFilesFolder ?>
16 16 <?endif?>
17 17
18 18 <Product Id='*'
19 19 Name='Mercurial $(var.Version) ($(var.Platform))'
20 20 UpgradeCode='$(var.ProductUpgradeCode)'
21 21 Language='1033' Codepage='1252' Version='$(var.Version)'
22 22 Manufacturer='Olivia Mackall and others'>
23 23
24 24 <Package Id='*'
25 25 Keywords='Installer'
26 26 Description="Mercurial distributed SCM (version $(var.Version))"
27 27 Comments='$(var.Comments)'
28 28 Platform='$(var.Platform)'
29 29 Manufacturer='Olivia Mackall and others'
30 30 InstallerVersion='300' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
31 31
32 32 <Media Id='1' Cabinet='mercurial.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'
33 33 CompressionLevel='high' />
34 34 <Property Id='DiskPrompt' Value="Mercurial $(var.Version) Installation [1]" />
35 35
36 36 <Condition Message='Mercurial MSI installers require Windows XP or higher'>
37 37 VersionNT >= 501
38 38 </Condition>
39 39
40 40 <Property Id="INSTALLDIR">
41 41 <ComponentSearch Id='SearchForMainExecutableComponent'
42 42 Guid='$(var.ComponentMainExecutableGUID)'
43 43 Type='directory' />
44 44 </Property>
45 45
46 46 <!--Property Id='ARPCOMMENTS'>any comments</Property-->
47 47 <Property Id='ARPCONTACT'>mercurial@mercurial-scm.org</Property>
48 48 <Property Id='ARPHELPLINK'>https://mercurial-scm.org/wiki/</Property>
49 49 <Property Id='ARPURLINFOABOUT'>https://mercurial-scm.org/about/</Property>
50 50 <Property Id='ARPURLUPDATEINFO'>https://mercurial-scm.org/downloads/</Property>
51 51 <Property Id='ARPHELPTELEPHONE'>https://mercurial-scm.org/wiki/Support</Property>
52 52 <Property Id='ARPPRODUCTICON'>hgIcon.ico</Property>
53 53
54 54 <Property Id='INSTALLEDMERCURIALPRODUCTS' Secure='yes'></Property>
55 55 <Property Id='REINSTALLMODE'>amus</Property>
56 56
57 57 <!--Auto-accept the license page-->
58 58 <Property Id='LicenseAccepted'>1</Property>
59 59
60 60 <Directory Id='TARGETDIR' Name='SourceDir'>
61 61 <Directory Id='$(var.PFolder)' Name='PFiles'>
62 62 <Directory Id='INSTALLDIR' Name='Mercurial'>
63 63 <Component Id='MainExecutable' Guid='$(var.ComponentMainExecutableGUID)' Win64='$(var.IsX64)'>
64 64 <CreateFolder />
65 65 <Environment Id="Environment" Name="PATH" Part="last" System="yes"
66 66 Permanent="no" Value="[INSTALLDIR]" Action="set" />
67 67 </Component>
68 68 </Directory>
69 69 </Directory>
70 70
71 71 <Directory Id="ProgramMenuFolder" Name="Programs">
72 72 <Directory Id="ProgramMenuDir" Name="Mercurial $(var.Version)">
73 73 <Component Id="ProgramMenuDir" Guid="$(var.ProgramMenuDir.guid)" Win64='$(var.IsX64)'>
74 74 <RemoveFolder Id='ProgramMenuDir' On='uninstall' />
75 75 <RegistryValue Root='HKCU' Key='Software\Mercurial\InstallDir' Type='string'
76 76 Value='[INSTALLDIR]' KeyPath='yes' />
77 77 <Shortcut Id='UrlShortcut' Directory='ProgramMenuDir' Name='Mercurial Web Site'
78 78 Target='[ARPHELPLINK]' Icon="hgIcon.ico" IconIndex='0' />
79 79 </Component>
80 80 </Directory>
81 81 </Directory>
82 82
83 83 <!-- Install VCRedist merge modules on Python 2. On Python 3,
84 84 vcruntimeXXX.dll is part of the install layout and gets picked up
85 85 as a regular file. -->
86 86 <?if $(var.PythonVersion) = "2" ?>
87 87 <?if $(var.Platform) = "x86" ?>
88 88 <Merge Id='VCRuntime' DiskId='1' Language='1033'
89 89 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x86_msm.msm' />
90 90 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
91 91 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x86_msm.msm' />
92 92 <?else?>
93 93 <Merge Id='VCRuntime' DiskId='1' Language='1033'
94 94 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x64_msm.msm' />
95 95 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
96 96 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x64_msm.msm' />
97 97 <?endif?>
98 98 <?endif?>
99 99 </Directory>
100 100
101 101 <Feature Id='Complete' Title='Mercurial' Description='The complete package'
102 102 Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR' >
103 103 <Feature Id='MainProgram' Title='Program' Description='Mercurial command line app'
104 104 Level='1' Absent='disallow' >
105 105 <ComponentRef Id='MainExecutable' />
106 106 <ComponentRef Id='ProgramMenuDir' />
107 107 <ComponentGroupRef Id="hg.group.ROOT" />
108 108 <ComponentGroupRef Id="hg.group.defaultrc" />
109 109 <ComponentGroupRef Id="hg.group.helptext" />
110 110 <?ifdef MercurialHasLib?>
111 111 <ComponentGroupRef Id="hg.group.lib" />
112 112 <?endif?>
113 113 <ComponentGroupRef Id="hg.group.templates" />
114 114 <?if $(var.PythonVersion) = "2" ?>
115 115 <MergeRef Id='VCRuntime' />
116 116 <MergeRef Id='VCRuntimePolicy' />
117 117 <?endif?>
118 118 </Feature>
119 119 <?ifdef MercurialExtraFeatures?>
120 120 <?foreach EXTRAFEAT in $(var.MercurialExtraFeatures)?>
121 121 <FeatureRef Id="$(var.EXTRAFEAT)" />
122 122 <?endforeach?>
123 123 <?endif?>
124 124 <Feature Id='Locales' Title='Translations' Description='Translations' Level='1'>
125 125 <ComponentGroupRef Id="hg.group.locale" />
126 126 </Feature>
127 127 <Feature Id='Documentation' Title='Documentation' Description='HTML man pages' Level='1'>
128 128 <ComponentGroupRef Id="hg.group.doc" />
129 129 </Feature>
130 130 <Feature Id='Misc' Title='Miscellaneous' Description='Contributed scripts' Level='1'>
131 131 <ComponentGroupRef Id="hg.group.contrib" />
132 132 </Feature>
133 133 </Feature>
134 134
135 135 <UIRef Id="WixUI_FeatureTree" />
136 136 <UIRef Id="WixUI_ErrorProgressText" />
137 137
138 <?ifdef PyOxidizer?>
139 <WixVariable Id="WixUILicenseRtf" Value="COPYING.rtf" />
140 <Icon Id="hgIcon.ico" SourceFile="mercurial.ico" />
141 <?else?>
138 142 <WixVariable Id="WixUILicenseRtf" Value="contrib\packaging\wix\COPYING.rtf" />
139
140 143 <Icon Id="hgIcon.ico" SourceFile="contrib/win32/mercurial.ico" />
144 <?endif?>
141 145
142 146 <Upgrade Id='$(var.ProductUpgradeCode)'>
143 147 <UpgradeVersion
144 148 IncludeMinimum='yes' Minimum='0.0.0' IncludeMaximum='no' OnlyDetect='no'
145 149 Property='INSTALLEDMERCURIALPRODUCTS' />
146 150 </Upgrade>
147 151
148 152 <InstallExecuteSequence>
149 153 <RemoveExistingProducts After='InstallInitialize'/>
150 154 </InstallExecuteSequence>
151 155
152 156 </Product>
153 157 </Wix>
@@ -1,87 +1,238 b''
1 # The following variables can be passed in as parameters:
2 #
3 # VERSION
4 # Version string of program being produced.
5 #
6 # MSI_NAME
7 # Root name of MSI installer.
8 #
9 # EXTRA_MSI_FEATURES
10 # ; delimited string of extra features to advertise in the built MSA.
11
1 12 ROOT = CWD + "/../.."
2 13
14 VERSION = VARS.get("VERSION", "5.8")
15 MSI_NAME = VARS.get("MSI_NAME", "mercurial")
16 EXTRA_MSI_FEATURES = VARS.get("EXTRA_MSI_FEATURES")
17
3 18 IS_WINDOWS = "windows" in BUILD_TARGET_TRIPLE
4 19
5 20 # Code to run in Python interpreter.
6 21 RUN_CODE = "import hgdemandimport; hgdemandimport.enable(); from mercurial import dispatch; dispatch.run()"
7 22
8 23 set_build_path(ROOT + "/build/pyoxidizer")
9 24
10 25 def make_distribution():
11 26 return default_python_distribution(python_version = "3.8")
12 27
13 28 def resource_callback(policy, resource):
14 29 if not IS_WINDOWS:
15 30 resource.add_location = "in-memory"
16 31 return
17 32
18 33 # We use a custom resource routing policy to influence where things are loaded
19 34 # from.
20 35 #
21 36 # For Python modules and resources, we load from memory if they are in
22 37 # the standard library and from the filesystem if not. This is because
23 38 # parts of Mercurial and some 3rd party packages aren't yet compatible
24 39 # with memory loading.
25 40 #
26 41 # For Python extension modules, we load from the filesystem because
27 42 # this yields greatest compatibility.
28 43 if type(resource) in ("PythonModuleSource", "PythonPackageResource", "PythonPackageDistributionResource"):
29 44 if resource.is_stdlib:
30 45 resource.add_location = "in-memory"
31 46 else:
32 47 resource.add_location = "filesystem-relative:lib"
33 48
34 49 elif type(resource) == "PythonExtensionModule":
35 50 resource.add_location = "filesystem-relative:lib"
36 51
37 52 def make_exe(dist):
38 53 """Builds a Rust-wrapped Mercurial binary."""
39 54 packaging_policy = dist.make_python_packaging_policy()
40 55
41 56 # Extension may depend on any Python functionality. Include all
42 57 # extensions.
43 58 packaging_policy.extension_module_filter = "all"
44 59 packaging_policy.resources_location = "in-memory"
45 60 if IS_WINDOWS:
46 61 packaging_policy.resources_location_fallback = "filesystem-relative:lib"
47 62 packaging_policy.register_resource_callback(resource_callback)
48 63
49 64 config = dist.make_python_interpreter_config()
50 65 config.allocator_backend = "default"
51 66 config.run_command = RUN_CODE
52 67
53 68 # We want to let the user load extensions from the file system
54 69 config.filesystem_importer = True
55 70
56 71 # We need this to make resourceutil happy, since it looks for sys.frozen.
57 72 config.sys_frozen = True
58 73 config.legacy_windows_stdio = True
59 74
60 75 exe = dist.to_python_executable(
61 76 name = "hg",
62 77 packaging_policy = packaging_policy,
63 78 config = config,
64 79 )
65 80
66 81 # Add Mercurial to resources.
67 82 exe.add_python_resources(exe.pip_install(["--verbose", ROOT]))
68 83
69 84 # On Windows, we install extra packages for convenience.
70 85 if IS_WINDOWS:
71 86 exe.add_python_resources(
72 87 exe.pip_install(["-r", ROOT + "/contrib/packaging/requirements-windows-py3.txt"]),
73 88 )
74 89
75 90 return exe
76 91
77 92 def make_manifest(dist, exe):
78 93 m = FileManifest()
79 94 m.add_python_resource(".", exe)
80 95
81 96 return m
82 97
98
99 # This adjusts the InstallManifest produced from exe generation to provide
100 # additional files found in a Windows install layout.
101 def make_windows_install_layout(manifest):
102 # Copy various files to new install locations. This can go away once
103 # we're using the importlib resource reader.
104 RECURSIVE_COPIES = {
105 "lib/mercurial/locale/": "locale/",
106 "lib/mercurial/templates/": "templates/",
107 }
108 for (search, replace) in RECURSIVE_COPIES.items():
109 for path in manifest.paths():
110 if path.startswith(search):
111 new_path = path.replace(search, replace)
112 print("copy %s to %s" % (path, new_path))
113 file = manifest.get_file(path)
114 manifest.add_file(file, path = new_path)
115
116 # Similar to above, but with filename pattern matching.
117 # lib/mercurial/helptext/**/*.txt -> helptext/
118 # lib/mercurial/defaultrc/*.rc -> defaultrc/
119 for path in manifest.paths():
120 if path.startswith("lib/mercurial/helptext/") and path.endswith(".txt"):
121 new_path = path[len("lib/mercurial/"):]
122 elif path.startswith("lib/mercurial/defaultrc/") and path.endswith(".rc"):
123 new_path = path[len("lib/mercurial/"):]
124 else:
125 continue
126
127 print("copying %s to %s" % (path, new_path))
128 manifest.add_file(manifest.get_file(path), path = new_path)
129
130 # We also install a handful of additional files.
131 EXTRA_CONTRIB_FILES = [
132 "bash_completion",
133 "hgweb.fcgi",
134 "hgweb.wsgi",
135 "logo-droplets.svg",
136 "mercurial.el",
137 "mq.el",
138 "tcsh_completion",
139 "tcsh_completion_build.sh",
140 "xml.rnc",
141 "zsh_completion",
142 ]
143
144 for f in EXTRA_CONTRIB_FILES:
145 manifest.add_file(FileContent(path = ROOT + "/contrib/" + f), directory = "contrib")
146
147 # Individual files with full source to destination path mapping.
148 EXTRA_FILES = {
149 "contrib/hgk": "contrib/hgk.tcl",
150 "contrib/win32/postinstall.txt": "ReleaseNotes.txt",
151 "contrib/win32/ReadMe.html": "ReadMe.html",
152 "doc/style.css": "doc/style.css",
153 "COPYING": "Copying.txt",
154 }
155
156 for source, dest in EXTRA_FILES.items():
157 print("adding extra file %s" % dest)
158 manifest.add_file(FileContent(path = ROOT + "/" + source), path = dest)
159
160 # And finally some wildcard matches.
161 manifest.add_manifest(glob(
162 include = [ROOT + "/contrib/vim/*"],
163 strip_prefix = ROOT + "/"
164 ))
165 manifest.add_manifest(glob(
166 include = [ROOT + "/doc/*.html"],
167 strip_prefix = ROOT + "/"
168 ))
169
170 # But we don't ship hg-ssh on Windows, so exclude its documentation.
171 manifest.remove("doc/hg-ssh.8.html")
172
173 return manifest
174
175
176 def make_msi(manifest):
177 manifest = make_windows_install_layout(manifest)
178
179 if "x86_64" in BUILD_TARGET_TRIPLE:
180 platform = "x64"
181 else:
182 platform = "x86"
183
184 manifest.add_file(
185 FileContent(path = ROOT + "/contrib/packaging/wix/COPYING.rtf"),
186 path = "COPYING.rtf",
187 )
188 manifest.remove("Copying.txt")
189 manifest.add_file(
190 FileContent(path = ROOT + "/contrib/win32/mercurial.ini"),
191 path = "defaultrc/mercurial.rc",
192 )
193 manifest.add_file(
194 FileContent(filename = "editor.rc", content = "[ui]\neditor = notepad\n"),
195 path = "defaultrc/editor.rc",
196 )
197
198 wix = WiXInstaller("hg", "%s-%s.msi" % (MSI_NAME, VERSION))
199
200 # Materialize files in the manifest to the install layout.
201 wix.add_install_files(manifest)
202
203 # From mercurial.wxs.
204 wix.install_files_root_directory_id = "INSTALLDIR"
205
206 # Pull in our custom .wxs files.
207 defines = {
208 "PyOxidizer": "1",
209 "Platform": platform,
210 "Version": VERSION,
211 "Comments": "Installs Mercurial version %s" % VERSION,
212 "PythonVersion": "3",
213 "MercurialHasLib": "1",
214 }
215
216 if EXTRA_MSI_FEATURES:
217 defines["MercurialExtraFeatures"] = EXTRA_MSI_FEATURES
218
219 wix.add_wxs_file(
220 ROOT + "/contrib/packaging/wix/mercurial.wxs",
221 preprocessor_parameters=defines,
222 )
223
224 # Our .wxs references to other files. Pull those into the build environment.
225 for f in ("defines.wxi", "guids.wxi", "COPYING.rtf"):
226 wix.add_build_file(f, ROOT + "/contrib/packaging/wix/" + f)
227
228 wix.add_build_file("mercurial.ico", ROOT + "/contrib/win32/mercurial.ico")
229
230 return wix
231
232
83 233 register_target("distribution", make_distribution)
84 234 register_target("exe", make_exe, depends = ["distribution"])
85 235 register_target("app", make_manifest, depends = ["distribution", "exe"], default = True)
236 register_target("msi", make_msi, depends = ["app"])
86 237
87 238 resolve_targets()
General Comments 0
You need to be logged in to leave comments. Login now