contrib/packaging/hgpackaging/inno.py
changeset 41920 a2e191a937a9
parent 41919 7d1211168863
child 41921 260305e8ddbd
equal deleted inserted replaced
41919:7d1211168863 41920:a2e191a937a9
    10 import os
    10 import os
    11 import pathlib
    11 import pathlib
    12 import shutil
    12 import shutil
    13 import subprocess
    13 import subprocess
    14 
    14 
    15 from .downloads import (
    15 from .py2exe import (
    16     download_entry,
    16     build_py2exe,
    17 )
    17 )
    18 from .util import (
    18 from .util import (
    19     extract_tar_to_directory,
       
    20     extract_zip_to_directory,
       
    21     find_vc_runtime_files,
    19     find_vc_runtime_files,
    22     python_exe_info,
       
    23 )
    20 )
    24 
    21 
    25 
    22 
    26 def build(source_dir: pathlib.Path, build_dir: pathlib.Path,
    23 def build(source_dir: pathlib.Path, build_dir: pathlib.Path,
    27           python_exe: pathlib.Path, iscc_exe: pathlib.Path,
    24           python_exe: pathlib.Path, iscc_exe: pathlib.Path,
    35     to already be configured with an active toolchain.
    32     to already be configured with an active toolchain.
    36     """
    33     """
    37     if not iscc_exe.exists():
    34     if not iscc_exe.exists():
    38         raise Exception('%s does not exist' % iscc_exe)
    35         raise Exception('%s does not exist' % iscc_exe)
    39 
    36 
    40     if 'VCINSTALLDIR' not in os.environ:
    37     vc_x64 = r'\x64' in os.environ.get('LIB', '')
    41         raise Exception('not running from a Visual C++ build environment; '
       
    42                         'execute the "Visual C++ <version> Command Prompt" '
       
    43                         'application shortcut or a vcsvarsall.bat file')
       
    44 
       
    45     # Identity x86/x64 and validate the environment matches the Python
       
    46     # architecture.
       
    47     vc_x64 = r'\x64' in os.environ['LIB']
       
    48 
       
    49     py_info = python_exe_info(python_exe)
       
    50 
       
    51     if vc_x64:
       
    52         if py_info['arch'] != '64bit':
       
    53             raise Exception('architecture mismatch: Visual C++ environment '
       
    54                             'is configured for 64-bit but Python is 32-bit')
       
    55     else:
       
    56         if py_info['arch'] != '32bit':
       
    57             raise Exception('architecture mismatch: Visual C++ environment '
       
    58                             'is configured for 32-bit but Python is 64-bit')
       
    59 
       
    60     if py_info['py3']:
       
    61         raise Exception('Only Python 2 is currently supported')
       
    62 
       
    63     build_dir.mkdir(exist_ok=True)
       
    64 
       
    65     gettext_pkg, gettext_entry = download_entry('gettext', build_dir)
       
    66     gettext_dep_pkg = download_entry('gettext-dep', build_dir)[0]
       
    67     virtualenv_pkg, virtualenv_entry = download_entry('virtualenv', build_dir)
       
    68     py2exe_pkg, py2exe_entry = download_entry('py2exe', build_dir)
       
    69 
       
    70     venv_path = build_dir / ('venv-inno-%s' % ('x64' if vc_x64 else 'x86'))
       
    71 
       
    72     gettext_root = build_dir / (
       
    73         'gettext-win-%s' % gettext_entry['version'])
       
    74 
       
    75     if not gettext_root.exists():
       
    76         extract_zip_to_directory(gettext_pkg, gettext_root)
       
    77         extract_zip_to_directory(gettext_dep_pkg, gettext_root)
       
    78 
       
    79     # This assumes Python 2. We don't need virtualenv on Python 3.
       
    80     virtualenv_src_path = build_dir / (
       
    81         'virtualenv-%s' % virtualenv_entry['version'])
       
    82     virtualenv_py = virtualenv_src_path / 'virtualenv.py'
       
    83 
       
    84     if not virtualenv_src_path.exists():
       
    85         extract_tar_to_directory(virtualenv_pkg, build_dir)
       
    86 
       
    87     py2exe_source_path = build_dir / ('py2exe-%s' % py2exe_entry['version'])
       
    88 
       
    89     if not py2exe_source_path.exists():
       
    90         extract_zip_to_directory(py2exe_pkg, build_dir)
       
    91 
       
    92     if not venv_path.exists():
       
    93         print('creating virtualenv with dependencies')
       
    94         subprocess.run(
       
    95             [str(python_exe), str(virtualenv_py), str(venv_path)],
       
    96             check=True)
       
    97 
       
    98     venv_python = venv_path / 'Scripts' / 'python.exe'
       
    99     venv_pip = venv_path / 'Scripts' / 'pip.exe'
       
   100 
    38 
   101     requirements_txt = (source_dir / 'contrib' / 'packaging' /
    39     requirements_txt = (source_dir / 'contrib' / 'packaging' /
   102                         'inno' / 'requirements.txt')
    40                         'inno' / 'requirements.txt')
   103     subprocess.run([str(venv_pip), 'install', '-r', str(requirements_txt)],
       
   104                    check=True)
       
   105 
    41 
   106     # Force distutils to use VC++ settings from environment, which was
    42     build_py2exe(source_dir, build_dir, python_exe, 'inno',
   107     # validated above.
    43                  requirements_txt)
   108     env = dict(os.environ)
       
   109     env['DISTUTILS_USE_SDK'] = '1'
       
   110     env['MSSdk'] = '1'
       
   111 
       
   112     py2exe_py_path = venv_path / 'Lib' / 'site-packages' / 'py2exe'
       
   113     if not py2exe_py_path.exists():
       
   114         print('building py2exe')
       
   115         subprocess.run([str(venv_python), 'setup.py', 'install'],
       
   116                        cwd=py2exe_source_path,
       
   117                        env=env,
       
   118                        check=True)
       
   119 
       
   120     # Register location of msgfmt and other binaries.
       
   121     env['PATH'] = '%s%s%s' % (
       
   122         env['PATH'], os.pathsep, str(gettext_root / 'bin'))
       
   123 
       
   124     print('building Mercurial')
       
   125     subprocess.run(
       
   126         [str(venv_python), 'setup.py',
       
   127          'py2exe', '-b', '3' if vc_x64 else '2',
       
   128          'build_doc', '--html'],
       
   129         cwd=str(source_dir),
       
   130         env=env,
       
   131         check=True)
       
   132 
    44 
   133     # hg.exe depends on VC9 runtime DLLs. Copy those into place.
    45     # hg.exe depends on VC9 runtime DLLs. Copy those into place.
   134     for f in find_vc_runtime_files(vc_x64):
    46     for f in find_vc_runtime_files(vc_x64):
   135         if f.name.endswith('.manifest'):
    47         if f.name.endswith('.manifest'):
   136             basename = 'Microsoft.VC90.CRT.manifest'
    48             basename = 'Microsoft.VC90.CRT.manifest'