##// END OF EJS Templates
pyoxidizer: default to a meaningless release instead of hardcoding 5.8...
Raphaël Gomès -
r49062:7f23a472 default
parent child Browse files
Show More
@@ -1,335 +1,335 b''
1 # The following variables can be passed in as parameters:
1 # The following variables can be passed in as parameters:
2 #
2 #
3 # VERSION
3 # VERSION
4 # Version string of program being produced.
4 # Version string of program being produced.
5 #
5 #
6 # MSI_NAME
6 # MSI_NAME
7 # Root name of MSI installer.
7 # Root name of MSI installer.
8 #
8 #
9 # EXTRA_MSI_FEATURES
9 # EXTRA_MSI_FEATURES
10 # ; delimited string of extra features to advertise in the built MSA.
10 # ; delimited string of extra features to advertise in the built MSA.
11 #
11 #
12 # SIGNING_PFX_PATH
12 # SIGNING_PFX_PATH
13 # Path to code signing certificate to use.
13 # Path to code signing certificate to use.
14 #
14 #
15 # SIGNING_PFX_PASSWORD
15 # SIGNING_PFX_PASSWORD
16 # Password to code signing PFX file defined by SIGNING_PFX_PATH.
16 # Password to code signing PFX file defined by SIGNING_PFX_PATH.
17 #
17 #
18 # SIGNING_SUBJECT_NAME
18 # SIGNING_SUBJECT_NAME
19 # String fragment in code signing certificate subject name used to find
19 # String fragment in code signing certificate subject name used to find
20 # code signing certificate in Windows certificate store.
20 # code signing certificate in Windows certificate store.
21 #
21 #
22 # TIME_STAMP_SERVER_URL
22 # TIME_STAMP_SERVER_URL
23 # URL of time-stamp token authority (RFC 3161) servers to stamp code signatures.
23 # URL of time-stamp token authority (RFC 3161) servers to stamp code signatures.
24
24
25 ROOT = CWD + "/../.."
25 ROOT = CWD + "/../.."
26
26
27 VERSION = VARS.get("VERSION", "5.8")
27 VERSION = VARS.get("VERSION", "0.0")
28 MSI_NAME = VARS.get("MSI_NAME", "mercurial")
28 MSI_NAME = VARS.get("MSI_NAME", "mercurial")
29 EXTRA_MSI_FEATURES = VARS.get("EXTRA_MSI_FEATURES")
29 EXTRA_MSI_FEATURES = VARS.get("EXTRA_MSI_FEATURES")
30 SIGNING_PFX_PATH = VARS.get("SIGNING_PFX_PATH")
30 SIGNING_PFX_PATH = VARS.get("SIGNING_PFX_PATH")
31 SIGNING_PFX_PASSWORD = VARS.get("SIGNING_PFX_PASSWORD", "")
31 SIGNING_PFX_PASSWORD = VARS.get("SIGNING_PFX_PASSWORD", "")
32 SIGNING_SUBJECT_NAME = VARS.get("SIGNING_SUBJECT_NAME")
32 SIGNING_SUBJECT_NAME = VARS.get("SIGNING_SUBJECT_NAME")
33 TIME_STAMP_SERVER_URL = VARS.get("TIME_STAMP_SERVER_URL", "http://timestamp.digicert.com")
33 TIME_STAMP_SERVER_URL = VARS.get("TIME_STAMP_SERVER_URL", "http://timestamp.digicert.com")
34
34
35 IS_WINDOWS = "windows" in BUILD_TARGET_TRIPLE
35 IS_WINDOWS = "windows" in BUILD_TARGET_TRIPLE
36 IS_MACOS = "darwin" in BUILD_TARGET_TRIPLE
36 IS_MACOS = "darwin" in BUILD_TARGET_TRIPLE
37
37
38 # Code to run in Python interpreter.
38 # Code to run in Python interpreter.
39 RUN_CODE = """
39 RUN_CODE = """
40 import os
40 import os
41 import sys
41 import sys
42 extra_path = os.environ.get('PYTHONPATH')
42 extra_path = os.environ.get('PYTHONPATH')
43 if extra_path is not None:
43 if extra_path is not None:
44 # extensions and hooks expect a working python environment
44 # extensions and hooks expect a working python environment
45 # We do not prepend the values because the Mercurial library wants to be in
45 # We do not prepend the values because the Mercurial library wants to be in
46 # the front of the sys.path to avoid picking up other installations.
46 # the front of the sys.path to avoid picking up other installations.
47 sys.path.extend(extra_path.split(os.pathsep))
47 sys.path.extend(extra_path.split(os.pathsep))
48 # Add user site to sys.path to load extensions without the full path
48 # Add user site to sys.path to load extensions without the full path
49 if os.name == 'nt':
49 if os.name == 'nt':
50 vi = sys.version_info
50 vi = sys.version_info
51 appdata = os.environ.get('APPDATA')
51 appdata = os.environ.get('APPDATA')
52 if appdata:
52 if appdata:
53 sys.path.append(
53 sys.path.append(
54 os.path.join(
54 os.path.join(
55 appdata,
55 appdata,
56 'Python',
56 'Python',
57 'Python%d%d' % (vi[0], vi[1]),
57 'Python%d%d' % (vi[0], vi[1]),
58 'site-packages',
58 'site-packages',
59 )
59 )
60 )
60 )
61 elif sys.platform == "darwin":
61 elif sys.platform == "darwin":
62 vi = sys.version_info
62 vi = sys.version_info
63
63
64 def joinuser(*args):
64 def joinuser(*args):
65 return os.path.expanduser(os.path.join(*args))
65 return os.path.expanduser(os.path.join(*args))
66
66
67 # Note: site.py uses `sys._framework` instead of hardcoding "Python" as the
67 # Note: site.py uses `sys._framework` instead of hardcoding "Python" as the
68 # 3rd arg, but that is set to an empty string in an oxidized binary. It
68 # 3rd arg, but that is set to an empty string in an oxidized binary. It
69 # has a fallback to ~/.local when `sys._framework` isn't set, but we want
69 # has a fallback to ~/.local when `sys._framework` isn't set, but we want
70 # to match what the system python uses, so it sees pip installed stuff.
70 # to match what the system python uses, so it sees pip installed stuff.
71 usersite = joinuser("~", "Library", "Python",
71 usersite = joinuser("~", "Library", "Python",
72 "%d.%d" % vi[:2], "lib/python/site-packages")
72 "%d.%d" % vi[:2], "lib/python/site-packages")
73
73
74 sys.path.append(usersite)
74 sys.path.append(usersite)
75 import hgdemandimport;
75 import hgdemandimport;
76 hgdemandimport.enable();
76 hgdemandimport.enable();
77 from mercurial import dispatch;
77 from mercurial import dispatch;
78 dispatch.run();
78 dispatch.run();
79 """
79 """
80
80
81 set_build_path(ROOT + "/build/pyoxidizer")
81 set_build_path(ROOT + "/build/pyoxidizer")
82
82
83 def make_distribution():
83 def make_distribution():
84 return default_python_distribution(python_version = "3.9")
84 return default_python_distribution(python_version = "3.9")
85
85
86 def resource_callback(policy, resource):
86 def resource_callback(policy, resource):
87 if not (IS_WINDOWS or IS_MACOS):
87 if not (IS_WINDOWS or IS_MACOS):
88 resource.add_location = "in-memory"
88 resource.add_location = "in-memory"
89 return
89 return
90
90
91 # We use a custom resource routing policy to influence where things are loaded
91 # We use a custom resource routing policy to influence where things are loaded
92 # from.
92 # from.
93 #
93 #
94 # For Python modules and resources, we load from memory if they are in
94 # For Python modules and resources, we load from memory if they are in
95 # the standard library and from the filesystem if not. This is because
95 # the standard library and from the filesystem if not. This is because
96 # parts of Mercurial and some 3rd party packages aren't yet compatible
96 # parts of Mercurial and some 3rd party packages aren't yet compatible
97 # with memory loading.
97 # with memory loading.
98 #
98 #
99 # For Python extension modules, we load from the filesystem because
99 # For Python extension modules, we load from the filesystem because
100 # this yields greatest compatibility.
100 # this yields greatest compatibility.
101 if type(resource) in ("PythonModuleSource", "PythonPackageResource", "PythonPackageDistributionResource"):
101 if type(resource) in ("PythonModuleSource", "PythonPackageResource", "PythonPackageDistributionResource"):
102 if resource.is_stdlib:
102 if resource.is_stdlib:
103 resource.add_location = "in-memory"
103 resource.add_location = "in-memory"
104 else:
104 else:
105 resource.add_location = "filesystem-relative:lib"
105 resource.add_location = "filesystem-relative:lib"
106
106
107 elif type(resource) == "PythonExtensionModule":
107 elif type(resource) == "PythonExtensionModule":
108 resource.add_location = "filesystem-relative:lib"
108 resource.add_location = "filesystem-relative:lib"
109
109
110 def make_exe(dist):
110 def make_exe(dist):
111 """Builds a Rust-wrapped Mercurial binary."""
111 """Builds a Rust-wrapped Mercurial binary."""
112 packaging_policy = dist.make_python_packaging_policy()
112 packaging_policy = dist.make_python_packaging_policy()
113
113
114 # Extension may depend on any Python functionality. Include all
114 # Extension may depend on any Python functionality. Include all
115 # extensions.
115 # extensions.
116 packaging_policy.extension_module_filter = "all"
116 packaging_policy.extension_module_filter = "all"
117 packaging_policy.resources_location = "in-memory"
117 packaging_policy.resources_location = "in-memory"
118 if IS_WINDOWS or IS_MACOS:
118 if IS_WINDOWS or IS_MACOS:
119 packaging_policy.resources_location_fallback = "filesystem-relative:lib"
119 packaging_policy.resources_location_fallback = "filesystem-relative:lib"
120 packaging_policy.register_resource_callback(resource_callback)
120 packaging_policy.register_resource_callback(resource_callback)
121
121
122 config = dist.make_python_interpreter_config()
122 config = dist.make_python_interpreter_config()
123 config.allocator_backend = "default"
123 config.allocator_backend = "default"
124 config.run_command = RUN_CODE
124 config.run_command = RUN_CODE
125
125
126 # We want to let the user load extensions from the file system
126 # We want to let the user load extensions from the file system
127 config.filesystem_importer = True
127 config.filesystem_importer = True
128
128
129 # We need this to make resourceutil happy, since it looks for sys.frozen.
129 # We need this to make resourceutil happy, since it looks for sys.frozen.
130 config.sys_frozen = True
130 config.sys_frozen = True
131 config.legacy_windows_stdio = True
131 config.legacy_windows_stdio = True
132
132
133 exe = dist.to_python_executable(
133 exe = dist.to_python_executable(
134 name = "hg",
134 name = "hg",
135 packaging_policy = packaging_policy,
135 packaging_policy = packaging_policy,
136 config = config,
136 config = config,
137 )
137 )
138
138
139 # Add Mercurial to resources.
139 # Add Mercurial to resources.
140 exe.add_python_resources(exe.pip_install(["--verbose", ROOT]))
140 exe.add_python_resources(exe.pip_install(["--verbose", ROOT]))
141
141
142 # On Windows, we install extra packages for convenience.
142 # On Windows, we install extra packages for convenience.
143 if IS_WINDOWS:
143 if IS_WINDOWS:
144 exe.add_python_resources(
144 exe.add_python_resources(
145 exe.pip_install(["-r", ROOT + "/contrib/packaging/requirements-windows-py3.txt"]),
145 exe.pip_install(["-r", ROOT + "/contrib/packaging/requirements-windows-py3.txt"]),
146 )
146 )
147 extra_packages = VARS.get("extra_py_packages", "")
147 extra_packages = VARS.get("extra_py_packages", "")
148 if extra_packages:
148 if extra_packages:
149 for extra in extra_packages.split(","):
149 for extra in extra_packages.split(","):
150 extra_src, pkgs = extra.split("=")
150 extra_src, pkgs = extra.split("=")
151 pkgs = pkgs.split(":")
151 pkgs = pkgs.split(":")
152 exe.add_python_resources(exe.read_package_root(extra_src, pkgs))
152 exe.add_python_resources(exe.read_package_root(extra_src, pkgs))
153
153
154 return exe
154 return exe
155
155
156 def make_manifest(dist, exe):
156 def make_manifest(dist, exe):
157 m = FileManifest()
157 m = FileManifest()
158 m.add_python_resource(".", exe)
158 m.add_python_resource(".", exe)
159
159
160 return m
160 return m
161
161
162
162
163 # This adjusts the InstallManifest produced from exe generation to provide
163 # This adjusts the InstallManifest produced from exe generation to provide
164 # additional files found in a Windows install layout.
164 # additional files found in a Windows install layout.
165 def make_windows_install_layout(manifest):
165 def make_windows_install_layout(manifest):
166 # Copy various files to new install locations. This can go away once
166 # Copy various files to new install locations. This can go away once
167 # we're using the importlib resource reader.
167 # we're using the importlib resource reader.
168 RECURSIVE_COPIES = {
168 RECURSIVE_COPIES = {
169 "lib/mercurial/locale/": "locale/",
169 "lib/mercurial/locale/": "locale/",
170 "lib/mercurial/templates/": "templates/",
170 "lib/mercurial/templates/": "templates/",
171 }
171 }
172 for (search, replace) in RECURSIVE_COPIES.items():
172 for (search, replace) in RECURSIVE_COPIES.items():
173 for path in manifest.paths():
173 for path in manifest.paths():
174 if path.startswith(search):
174 if path.startswith(search):
175 new_path = path.replace(search, replace)
175 new_path = path.replace(search, replace)
176 print("copy %s to %s" % (path, new_path))
176 print("copy %s to %s" % (path, new_path))
177 file = manifest.get_file(path)
177 file = manifest.get_file(path)
178 manifest.add_file(file, path = new_path)
178 manifest.add_file(file, path = new_path)
179
179
180 # Similar to above, but with filename pattern matching.
180 # Similar to above, but with filename pattern matching.
181 # lib/mercurial/helptext/**/*.txt -> helptext/
181 # lib/mercurial/helptext/**/*.txt -> helptext/
182 # lib/mercurial/defaultrc/*.rc -> defaultrc/
182 # lib/mercurial/defaultrc/*.rc -> defaultrc/
183 for path in manifest.paths():
183 for path in manifest.paths():
184 if path.startswith("lib/mercurial/helptext/") and path.endswith(".txt"):
184 if path.startswith("lib/mercurial/helptext/") and path.endswith(".txt"):
185 new_path = path[len("lib/mercurial/"):]
185 new_path = path[len("lib/mercurial/"):]
186 elif path.startswith("lib/mercurial/defaultrc/") and path.endswith(".rc"):
186 elif path.startswith("lib/mercurial/defaultrc/") and path.endswith(".rc"):
187 new_path = path[len("lib/mercurial/"):]
187 new_path = path[len("lib/mercurial/"):]
188 else:
188 else:
189 continue
189 continue
190
190
191 print("copying %s to %s" % (path, new_path))
191 print("copying %s to %s" % (path, new_path))
192 manifest.add_file(manifest.get_file(path), path = new_path)
192 manifest.add_file(manifest.get_file(path), path = new_path)
193
193
194 extra_install_files = VARS.get("extra_install_files", "")
194 extra_install_files = VARS.get("extra_install_files", "")
195 if extra_install_files:
195 if extra_install_files:
196 for extra in extra_install_files.split(","):
196 for extra in extra_install_files.split(","):
197 print("adding extra files from %s" % extra)
197 print("adding extra files from %s" % extra)
198 # TODO: I expected a ** glob to work, but it didn't.
198 # TODO: I expected a ** glob to work, but it didn't.
199 #
199 #
200 # TODO: I know this has forward-slash paths. As far as I can tell,
200 # TODO: I know this has forward-slash paths. As far as I can tell,
201 # backslashes don't ever match glob() expansions in
201 # backslashes don't ever match glob() expansions in
202 # tugger-starlark, even on Windows.
202 # tugger-starlark, even on Windows.
203 manifest.add_manifest(glob(include=[extra + "/*/*"], strip_prefix=extra+"/"))
203 manifest.add_manifest(glob(include=[extra + "/*/*"], strip_prefix=extra+"/"))
204
204
205 # We also install a handful of additional files.
205 # We also install a handful of additional files.
206 EXTRA_CONTRIB_FILES = [
206 EXTRA_CONTRIB_FILES = [
207 "bash_completion",
207 "bash_completion",
208 "hgweb.fcgi",
208 "hgweb.fcgi",
209 "hgweb.wsgi",
209 "hgweb.wsgi",
210 "logo-droplets.svg",
210 "logo-droplets.svg",
211 "mercurial.el",
211 "mercurial.el",
212 "mq.el",
212 "mq.el",
213 "tcsh_completion",
213 "tcsh_completion",
214 "tcsh_completion_build.sh",
214 "tcsh_completion_build.sh",
215 "xml.rnc",
215 "xml.rnc",
216 "zsh_completion",
216 "zsh_completion",
217 ]
217 ]
218
218
219 for f in EXTRA_CONTRIB_FILES:
219 for f in EXTRA_CONTRIB_FILES:
220 manifest.add_file(FileContent(path = ROOT + "/contrib/" + f), directory = "contrib")
220 manifest.add_file(FileContent(path = ROOT + "/contrib/" + f), directory = "contrib")
221
221
222 # Individual files with full source to destination path mapping.
222 # Individual files with full source to destination path mapping.
223 EXTRA_FILES = {
223 EXTRA_FILES = {
224 "contrib/hgk": "contrib/hgk.tcl",
224 "contrib/hgk": "contrib/hgk.tcl",
225 "contrib/win32/postinstall.txt": "ReleaseNotes.txt",
225 "contrib/win32/postinstall.txt": "ReleaseNotes.txt",
226 "contrib/win32/ReadMe.html": "ReadMe.html",
226 "contrib/win32/ReadMe.html": "ReadMe.html",
227 "doc/style.css": "doc/style.css",
227 "doc/style.css": "doc/style.css",
228 "COPYING": "Copying.txt",
228 "COPYING": "Copying.txt",
229 }
229 }
230
230
231 for source, dest in EXTRA_FILES.items():
231 for source, dest in EXTRA_FILES.items():
232 print("adding extra file %s" % dest)
232 print("adding extra file %s" % dest)
233 manifest.add_file(FileContent(path = ROOT + "/" + source), path = dest)
233 manifest.add_file(FileContent(path = ROOT + "/" + source), path = dest)
234
234
235 # And finally some wildcard matches.
235 # And finally some wildcard matches.
236 manifest.add_manifest(glob(
236 manifest.add_manifest(glob(
237 include = [ROOT + "/contrib/vim/*"],
237 include = [ROOT + "/contrib/vim/*"],
238 strip_prefix = ROOT + "/"
238 strip_prefix = ROOT + "/"
239 ))
239 ))
240 manifest.add_manifest(glob(
240 manifest.add_manifest(glob(
241 include = [ROOT + "/doc/*.html"],
241 include = [ROOT + "/doc/*.html"],
242 strip_prefix = ROOT + "/"
242 strip_prefix = ROOT + "/"
243 ))
243 ))
244
244
245 # But we don't ship hg-ssh on Windows, so exclude its documentation.
245 # But we don't ship hg-ssh on Windows, so exclude its documentation.
246 manifest.remove("doc/hg-ssh.8.html")
246 manifest.remove("doc/hg-ssh.8.html")
247
247
248 return manifest
248 return manifest
249
249
250
250
251 def make_msi(manifest):
251 def make_msi(manifest):
252 manifest = make_windows_install_layout(manifest)
252 manifest = make_windows_install_layout(manifest)
253
253
254 if "x86_64" in BUILD_TARGET_TRIPLE:
254 if "x86_64" in BUILD_TARGET_TRIPLE:
255 platform = "x64"
255 platform = "x64"
256 else:
256 else:
257 platform = "x86"
257 platform = "x86"
258
258
259 manifest.add_file(
259 manifest.add_file(
260 FileContent(path = ROOT + "/contrib/packaging/wix/COPYING.rtf"),
260 FileContent(path = ROOT + "/contrib/packaging/wix/COPYING.rtf"),
261 path = "COPYING.rtf",
261 path = "COPYING.rtf",
262 )
262 )
263 manifest.remove("Copying.txt")
263 manifest.remove("Copying.txt")
264 manifest.add_file(
264 manifest.add_file(
265 FileContent(path = ROOT + "/contrib/win32/mercurial.ini"),
265 FileContent(path = ROOT + "/contrib/win32/mercurial.ini"),
266 path = "defaultrc/mercurial.rc",
266 path = "defaultrc/mercurial.rc",
267 )
267 )
268 manifest.add_file(
268 manifest.add_file(
269 FileContent(filename = "editor.rc", content = "[ui]\neditor = notepad\n"),
269 FileContent(filename = "editor.rc", content = "[ui]\neditor = notepad\n"),
270 path = "defaultrc/editor.rc",
270 path = "defaultrc/editor.rc",
271 )
271 )
272
272
273 wix = WiXInstaller(
273 wix = WiXInstaller(
274 "hg",
274 "hg",
275 "%s-%s-%s.msi" % (MSI_NAME, VERSION, platform),
275 "%s-%s-%s.msi" % (MSI_NAME, VERSION, platform),
276 arch = platform,
276 arch = platform,
277 )
277 )
278
278
279 # Materialize files in the manifest to the install layout.
279 # Materialize files in the manifest to the install layout.
280 wix.add_install_files(manifest)
280 wix.add_install_files(manifest)
281
281
282 # From mercurial.wxs.
282 # From mercurial.wxs.
283 wix.install_files_root_directory_id = "INSTALLDIR"
283 wix.install_files_root_directory_id = "INSTALLDIR"
284
284
285 # Pull in our custom .wxs files.
285 # Pull in our custom .wxs files.
286 defines = {
286 defines = {
287 "PyOxidizer": "1",
287 "PyOxidizer": "1",
288 "Platform": platform,
288 "Platform": platform,
289 "Version": VERSION,
289 "Version": VERSION,
290 "Comments": "Installs Mercurial version %s" % VERSION,
290 "Comments": "Installs Mercurial version %s" % VERSION,
291 "PythonVersion": "3",
291 "PythonVersion": "3",
292 "MercurialHasLib": "1",
292 "MercurialHasLib": "1",
293 }
293 }
294
294
295 if EXTRA_MSI_FEATURES:
295 if EXTRA_MSI_FEATURES:
296 defines["MercurialExtraFeatures"] = EXTRA_MSI_FEATURES
296 defines["MercurialExtraFeatures"] = EXTRA_MSI_FEATURES
297
297
298 wix.add_wxs_file(
298 wix.add_wxs_file(
299 ROOT + "/contrib/packaging/wix/mercurial.wxs",
299 ROOT + "/contrib/packaging/wix/mercurial.wxs",
300 preprocessor_parameters=defines,
300 preprocessor_parameters=defines,
301 )
301 )
302
302
303 # Our .wxs references to other files. Pull those into the build environment.
303 # Our .wxs references to other files. Pull those into the build environment.
304 for f in ("defines.wxi", "guids.wxi", "COPYING.rtf"):
304 for f in ("defines.wxi", "guids.wxi", "COPYING.rtf"):
305 wix.add_build_file(f, ROOT + "/contrib/packaging/wix/" + f)
305 wix.add_build_file(f, ROOT + "/contrib/packaging/wix/" + f)
306
306
307 wix.add_build_file("mercurial.ico", ROOT + "/contrib/win32/mercurial.ico")
307 wix.add_build_file("mercurial.ico", ROOT + "/contrib/win32/mercurial.ico")
308
308
309 return wix
309 return wix
310
310
311
311
312 def register_code_signers():
312 def register_code_signers():
313 if not IS_WINDOWS:
313 if not IS_WINDOWS:
314 return
314 return
315
315
316 if SIGNING_PFX_PATH:
316 if SIGNING_PFX_PATH:
317 signer = code_signer_from_pfx_file(SIGNING_PFX_PATH, SIGNING_PFX_PASSWORD)
317 signer = code_signer_from_pfx_file(SIGNING_PFX_PATH, SIGNING_PFX_PASSWORD)
318 elif SIGNING_SUBJECT_NAME:
318 elif SIGNING_SUBJECT_NAME:
319 signer = code_signer_from_windows_store_subject(SIGNING_SUBJECT_NAME)
319 signer = code_signer_from_windows_store_subject(SIGNING_SUBJECT_NAME)
320 else:
320 else:
321 signer = None
321 signer = None
322
322
323 if signer:
323 if signer:
324 signer.set_time_stamp_server(TIME_STAMP_SERVER_URL)
324 signer.set_time_stamp_server(TIME_STAMP_SERVER_URL)
325 signer.activate()
325 signer.activate()
326
326
327
327
328 register_code_signers()
328 register_code_signers()
329
329
330 register_target("distribution", make_distribution)
330 register_target("distribution", make_distribution)
331 register_target("exe", make_exe, depends = ["distribution"])
331 register_target("exe", make_exe, depends = ["distribution"])
332 register_target("app", make_manifest, depends = ["distribution", "exe"], default = True)
332 register_target("app", make_manifest, depends = ["distribution", "exe"], default = True)
333 register_target("msi", make_msi, depends = ["app"])
333 register_target("msi", make_msi, depends = ["app"])
334
334
335 resolve_targets()
335 resolve_targets()
General Comments 0
You need to be logged in to leave comments. Login now