##// END OF EJS Templates
packaging: extract virtualenv and py2exe to build directory...
Gregory Szorc -
r42078:d4bf73ea default
parent child Browse files
Show More
@@ -1,169 +1,171 b''
1 1 # inno.py - Inno Setup functionality.
2 2 #
3 3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 # no-check-code because Python 3 native.
9 9
10 10 import os
11 11 import pathlib
12 12 import shutil
13 13 import subprocess
14 14 import tempfile
15 15
16 16 from .downloads import (
17 17 download_entry,
18 18 )
19 19 from .util import (
20 20 extract_tar_to_directory,
21 21 extract_zip_to_directory,
22 22 find_vc_runtime_files,
23 23 )
24 24
25 25
26 26 PRINT_PYTHON_INFO = '''
27 27 import platform, sys; print("%s:%d" % (platform.architecture()[0], sys.version_info[0]))
28 28 '''.strip()
29 29
30 30
31 31 def build(source_dir: pathlib.Path, build_dir: pathlib.Path,
32 32 python_exe: pathlib.Path, iscc_exe: pathlib.Path,
33 33 version=None):
34 34 """Build the Inno installer.
35 35
36 36 Build files will be placed in ``build_dir``.
37 37
38 38 py2exe's setup.py doesn't use setuptools. It doesn't have modern logic
39 39 for finding the Python 2.7 toolchain. So, we require the environment
40 40 to already be configured with an active toolchain.
41 41 """
42 42 if not iscc_exe.exists():
43 43 raise Exception('%s does not exist' % iscc_exe)
44 44
45 45 if 'VCINSTALLDIR' not in os.environ:
46 46 raise Exception('not running from a Visual C++ build environment; '
47 47 'execute the "Visual C++ <version> Command Prompt" '
48 48 'application shortcut or a vcsvarsall.bat file')
49 49
50 50 # Identity x86/x64 and validate the environment matches the Python
51 51 # architecture.
52 52 vc_x64 = r'\x64' in os.environ['LIB']
53 53
54 54 res = subprocess.run(
55 55 [str(python_exe), '-c', PRINT_PYTHON_INFO],
56 56 capture_output=True, check=True)
57 57
58 58 py_arch, py_version = res.stdout.decode('utf-8').split(':')
59 59 py_version = int(py_version)
60 60
61 61 if vc_x64:
62 62 if py_arch != '64bit':
63 63 raise Exception('architecture mismatch: Visual C++ environment '
64 64 'is configured for 64-bit but Python is 32-bit')
65 65 else:
66 66 if py_arch != '32bit':
67 67 raise Exception('architecture mismatch: Visual C++ environment '
68 68 'is configured for 32-bit but Python is 64-bit')
69 69
70 70 if py_version != 2:
71 71 raise Exception('Only Python 2 is currently supported')
72 72
73 73 build_dir.mkdir(exist_ok=True)
74 74
75 75 gettext_pkg, gettext_entry = download_entry('gettext', build_dir)
76 76 gettext_dep_pkg = download_entry('gettext-dep', build_dir)[0]
77 77 virtualenv_pkg, virtualenv_entry = download_entry('virtualenv', build_dir)
78 78 py2exe_pkg, py2exe_entry = download_entry('py2exe', build_dir)
79 79
80 80 venv_path = build_dir / ('venv-inno-%s' % ('x64' if vc_x64 else 'x86'))
81 81
82 82 gettext_root = build_dir / (
83 83 'gettext-win-%s' % gettext_entry['version'])
84 84
85 85 if not gettext_root.exists():
86 86 extract_zip_to_directory(gettext_pkg, gettext_root)
87 87 extract_zip_to_directory(gettext_dep_pkg, gettext_root)
88 88
89 # This assumes Python 2. We don't need virtualenv on Python 3.
90 virtualenv_src_path = build_dir / (
91 'virtualenv-%s' % virtualenv_entry['version'])
92 virtualenv_py = virtualenv_src_path / 'virtualenv.py'
93
94 if not virtualenv_src_path.exists():
95 extract_tar_to_directory(virtualenv_pkg, build_dir)
96
97 py2exe_source_path = build_dir / ('py2exe-%s' % py2exe_entry['version'])
98
99 if not py2exe_source_path.exists():
100 extract_zip_to_directory(py2exe_pkg, build_dir)
101
89 102 with tempfile.TemporaryDirectory() as td:
90 103 td = pathlib.Path(td)
91 104
92 # This assumes Python 2.
93 extract_tar_to_directory(virtualenv_pkg, td)
94 extract_zip_to_directory(py2exe_pkg, td)
95
96 virtualenv_src_path = td / ('virtualenv-%s' %
97 virtualenv_entry['version'])
98 py2exe_source_path = td / ('py2exe-%s' %
99 py2exe_entry['version'])
100
101 virtualenv_py = virtualenv_src_path / 'virtualenv.py'
102
103 105 if not venv_path.exists():
104 106 print('creating virtualenv with dependencies')
105 107 subprocess.run(
106 108 [str(python_exe), str(virtualenv_py), str(venv_path)],
107 109 check=True)
108 110
109 111 venv_python = venv_path / 'Scripts' / 'python.exe'
110 112 venv_pip = venv_path / 'Scripts' / 'pip.exe'
111 113
112 114 requirements_txt = (source_dir / 'contrib' / 'packaging' /
113 115 'inno' / 'requirements.txt')
114 116 subprocess.run([str(venv_pip), 'install', '-r', str(requirements_txt)],
115 117 check=True)
116 118
117 119 # Force distutils to use VC++ settings from environment, which was
118 120 # validated above.
119 121 env = dict(os.environ)
120 122 env['DISTUTILS_USE_SDK'] = '1'
121 123 env['MSSdk'] = '1'
122 124
123 125 py2exe_py_path = venv_path / 'Lib' / 'site-packages' / 'py2exe'
124 126 if not py2exe_py_path.exists():
125 127 print('building py2exe')
126 128 subprocess.run([str(venv_python), 'setup.py', 'install'],
127 129 cwd=py2exe_source_path,
128 130 env=env,
129 131 check=True)
130 132
131 133 # Register location of msgfmt and other binaries.
132 134 env['PATH'] = '%s%s%s' % (
133 135 env['PATH'], os.pathsep, str(gettext_root / 'bin'))
134 136
135 137 print('building Mercurial')
136 138 subprocess.run(
137 139 [str(venv_python), 'setup.py',
138 140 'py2exe', '-b', '3' if vc_x64 else '2',
139 141 'build_doc', '--html'],
140 142 cwd=str(source_dir),
141 143 env=env,
142 144 check=True)
143 145
144 146 # hg.exe depends on VC9 runtime DLLs. Copy those into place.
145 147 for f in find_vc_runtime_files(vc_x64):
146 148 if f.name.endswith('.manifest'):
147 149 basename = 'Microsoft.VC90.CRT.manifest'
148 150 else:
149 151 basename = f.name
150 152
151 153 dest_path = source_dir / 'dist' / basename
152 154
153 155 print('copying %s to %s' % (f, dest_path))
154 156 shutil.copyfile(f, dest_path)
155 157
156 158 print('creating installer')
157 159
158 160 args = [str(iscc_exe)]
159 161
160 162 if vc_x64:
161 163 args.append('/dARCH=x64')
162 164
163 165 if version:
164 166 args.append('/dVERSION=%s' % version)
165 167
166 168 args.append('/Odist')
167 169 args.append('contrib/packaging/inno/mercurial.iss')
168 170
169 171 subprocess.run(args, cwd=str(source_dir), check=True)
General Comments 0
You need to be logged in to leave comments. Login now