|
7 | 7 | import os |
8 | 8 | import pathlib |
9 | 9 | import re |
| 10 | +import shutil |
10 | 11 | import subprocess |
11 | 12 | import sys |
12 | 13 | import tempfile |
@@ -768,13 +769,112 @@ def run_msbuild(msbuild: pathlib.Path, pcbuild_path: pathlib.Path, |
768 | 769 | exec_and_log(args, str(pcbuild_path), os.environ) |
769 | 770 |
|
770 | 771 |
|
| 772 | +def build_openssl_for_arch(perl_path, arch: str, openssl_archive, nasm_archive, |
| 773 | + build_root: pathlib.Path): |
| 774 | + openssl_version = DOWNLOADS['openssl']['version'] |
| 775 | + nasm_version = DOWNLOADS['nasm-windows-bin']['version'] |
| 776 | + |
| 777 | + |
| 778 | + log('extracting %s to %s' % (openssl_archive, build_root)) |
| 779 | + extract_tar_to_directory(openssl_archive, build_root) |
| 780 | + log('extracting %s to %s' % (nasm_archive, build_root)) |
| 781 | + extract_tar_to_directory(nasm_archive, build_root) |
| 782 | + |
| 783 | + nasm_path = build_root / ('cpython-bin-deps-nasm-%s' % nasm_version) |
| 784 | + |
| 785 | + env = dict(os.environ) |
| 786 | + # Add Perl and nasm paths to front of PATH. |
| 787 | + env['PATH'] = '%s;%s;%s' % ( |
| 788 | + perl_path.parent, |
| 789 | + nasm_path, |
| 790 | + env['PATH'], |
| 791 | + ) |
| 792 | + |
| 793 | + source_root = build_root / ('openssl-%s' % openssl_version) |
| 794 | + |
| 795 | + if arch == 'x86': |
| 796 | + configure = 'VC-WIN32' |
| 797 | + prefix = '32' |
| 798 | + elif arch == 'amd64': |
| 799 | + configure = 'VC-WIN64A' |
| 800 | + prefix = '64' |
| 801 | + else: |
| 802 | + print('invalid architecture: %s' % arch) |
| 803 | + sys.exit(1) |
| 804 | + |
| 805 | + # The official CPython OpenSSL builds hack ms/uplink.c to change the |
| 806 | + # ``GetModuleHandle(NULL)`` invocation to load things from _ssl.pyd |
| 807 | + # instead. But since we statically link the _ssl extension, this hackery |
| 808 | + # is not required. |
| 809 | + |
| 810 | + # Set DESTDIR to affect install location. |
| 811 | + dest_dir = build_root / 'install' |
| 812 | + env['DESTDIR'] = str(dest_dir) |
| 813 | + install_root = dest_dir / prefix |
| 814 | + |
| 815 | + exec_and_log([str(perl_path), 'Configure', configure, 'no-idea', 'no-mdc2', |
| 816 | + '--prefix=/%s' % prefix], source_root, env) |
| 817 | + exec_and_log(['nmake'], source_root, env) |
| 818 | + |
| 819 | + # We don't care about accessory files, docs, etc. So just run `install_sw` |
| 820 | + # target to get the main files. |
| 821 | + exec_and_log(['nmake', 'install_sw'], source_root, env) |
| 822 | + |
| 823 | + # Copy the _static libraries as well. |
| 824 | + for l in ('crypto', 'ssl'): |
| 825 | + basename = 'lib%s_static.lib' % l |
| 826 | + source = source_root / basename |
| 827 | + dest = install_root / 'lib' / basename |
| 828 | + log('copying %s to %s' % (source, dest)) |
| 829 | + shutil.copyfile(source, dest) |
| 830 | + |
| 831 | + |
| 832 | +def build_openssl(perl_path: pathlib.Path): |
| 833 | + """Build OpenSSL from sources using the Perl executable specified.""" |
| 834 | + |
| 835 | + # First ensure the dependencies are in place. |
| 836 | + openssl_archive = download_entry('openssl', BUILD) |
| 837 | + nasm_archive = download_entry('nasm-windows-bin', BUILD) |
| 838 | + |
| 839 | + with tempfile.TemporaryDirectory() as td: |
| 840 | + td = pathlib.Path(td) |
| 841 | + |
| 842 | + root_32 = td / 'x86' |
| 843 | + root_64 = td / 'x64' |
| 844 | + root_32.mkdir() |
| 845 | + root_64.mkdir() |
| 846 | + |
| 847 | + # Then build the 32 and 64 bit OpenSSL installs in parallel |
| 848 | + # (because nmake doesn't do parallel builds). |
| 849 | + # TODO we need to adjust the environment to pull in a x86 toolchain |
| 850 | + # in order for this to work. |
| 851 | + fs = [] |
| 852 | + with concurrent.futures.ThreadPoolExecutor(2) as e: |
| 853 | + #fs.append(e.submit(build_openssl_for_arch, perl_path, 'x86', |
| 854 | + # openssl_archive, nasm_archive, root_32)) |
| 855 | + fs.append(e.submit(build_openssl_for_arch, perl_path, 'amd64', |
| 856 | + openssl_archive, nasm_archive, root_64)) |
| 857 | + |
| 858 | + for f in fs: |
| 859 | + f.result() |
| 860 | + |
| 861 | + install = td / 'out' |
| 862 | + #shutil.copytree(root_32 / 'install' / '32', install / 'openssl' / 'win32') |
| 863 | + shutil.copytree(root_64 / 'install' / '64', install / 'openssl' / 'amd64') |
| 864 | + |
| 865 | + dest_archive = BUILD / 'openssl-windows.tar' |
| 866 | + with dest_archive.open('wb') as fh: |
| 867 | + create_tar_from_directory(fh, install) |
| 868 | + |
| 869 | + |
771 | 870 | def build_cpython(pgo=False): |
772 | 871 | msbuild = find_msbuild() |
773 | 872 | log('found MSBuild at %s' % msbuild) |
774 | 873 |
|
775 | 874 | # The python.props file keys off MSBUILD, so it needs to be set. |
776 | 875 | os.environ['MSBUILD'] = str(msbuild) |
777 | 876 |
|
| 877 | + activeperl_installer = download_entry('activeperl', BUILD) |
778 | 878 | bzip2_archive = download_entry('bzip2', BUILD) |
779 | 879 | #openssl_archive = download_entry('openssl', BUILD) |
780 | 880 | openssl_bin_archive = download_entry('openssl-windows-bin', BUILD) |
@@ -864,11 +964,17 @@ def main(): |
864 | 964 | BUILD.mkdir(exist_ok=True) |
865 | 965 |
|
866 | 966 | log_path = BUILD / 'build.log' |
867 | | - LOG_PREFIX[0] = 'cpython' |
868 | 967 |
|
869 | 968 | with log_path.open('wb') as log_fh: |
870 | 969 | LOG_FH[0] = log_fh |
871 | 970 |
|
| 971 | + # TODO need better dependency checking. |
| 972 | + openssl_out = BUILD / 'openssl-windows.tar' |
| 973 | + if not openssl_out.exists(): |
| 974 | + LOG_PREFIX[0] = 'openssl' |
| 975 | + build_openssl(pathlib.Path(os.environ['PERL'])) |
| 976 | + |
| 977 | + LOG_PREFIX[0] = 'cpython' |
872 | 978 | build_cpython() |
873 | 979 |
|
874 | 980 | if __name__ == '__main__': |
|
0 commit comments