def build_cpython( client, image, host_platform, target_triple, optimizations, dest_archive, libressl=False, version=None, ): """Build CPython in a Docker image'""" entry_name = "cpython-%s" % version entry = DOWNLOADS[entry_name] python_archive = download_entry(entry_name, DOWNLOADS_PATH) setuptools_archive = download_entry("setuptools", DOWNLOADS_PATH) pip_archive = download_entry("pip", DOWNLOADS_PATH) with (SUPPORT / ("static-modules.%s.%s" % (version, host_platform))).open("rb") as fh: static_modules_lines = [ l.rstrip() for l in fh if not l.startswith(b"#") ] with (SUPPORT / ("disabled-static-modules.%s.%s" % (version, host_platform))).open("rb") as fh: disabled_static_modules = { l.strip() for l in fh if l.strip() and not l.strip().startswith(b"#") } setup = derive_setup_local( static_modules_lines, python_archive, python_version=entry["version"], musl="musl" in target_triple, debug=optimizations == "debug", disabled=disabled_static_modules, ) config_c_in = parse_config_c(setup["config_c_in"].decode("utf-8")) setup_dist_content = setup["setup_dist"] setup_local_content = setup["setup_local"] extra_make_content = setup["make_data"] with build_environment(client, image) as build_env: build_env.install_toolchain( BUILD, host_platform, binutils=install_binutils(host_platform), clang=True, musl="musl" in target_triple, ) # TODO support bdb/gdbm toggle packages = { "bdb", "bzip2", "libedit", "libffi", "sqlite", "tcl", "tix", "tk", "uuid", "xz", "zlib", } if libressl: packages.add("libressl") else: packages.add("openssl") # We use the system ncurses on macOS for now. ncurses = host_platform != "macos" if ncurses: packages.add("ncurses") readline = host_platform != "macos" if readline: packages.add("readline") if host_platform == "linux64": packages |= {"libX11", "libXau", "libxcb", "xorgproto"} for p in sorted(packages): build_env.install_artifact_archive(BUILD, p, target_triple, optimizations) for p in ( python_archive, setuptools_archive, pip_archive, SUPPORT / "build-cpython.sh", ): build_env.copy_file(p) for f in sorted(os.listdir(ROOT)): if f.startswith("LICENSE.") and f.endswith(".txt"): build_env.copy_file(ROOT / f) with tempfile.NamedTemporaryFile("wb") as fh: # In case default file masks cause wonkiness. os.chmod(fh.name, 0o644) fh.write(setup_local_content) fh.flush() build_env.copy_file(fh.name, dest_name="Setup.local") with tempfile.NamedTemporaryFile("wb") as fh: os.chmod(fh.name, 0o644) fh.write(extra_make_content) fh.flush() build_env.copy_file(fh.name, dest_name="Makefile.extra") env = { "CC": "clang", "PIP_VERSION": DOWNLOADS["pip"]["version"], "PYTHON_VERSION": entry["version"], "PYTHON_MAJMIN_VERSION": entry["version"][:3], "SETUPTOOLS_VERSION": DOWNLOADS["setuptools"]["version"], "TOOLCHAIN": "clang-%s" % host_platform, } if "musl" in target_triple: env["CC"] = "musl-clang" if optimizations == "debug": env["CPYTHON_DEBUG"] = "1" if optimizations in ("pgo", "pgo+lto"): env["CPYTHON_OPTIMIZED"] = "1" if optimizations in ("lto", "pgo+lto"): env["CPYTHON_LTO"] = "1" add_target_env(env, host_platform, build_env) build_env.run("build-cpython.sh", environment=env) extension_module_loading = ["builtin"] crt_features = [] if host_platform == "linux64": if "musl" in target_triple: crt_features.append("static") else: extension_module_loading.append("shared-library") crt_features.append("glibc-dynamic") glibc_max_version = build_env.get_file( "glibc_version.txt").strip() if not glibc_max_version: raise Exception( "failed to retrieve glibc max symbol version") crt_features.append("glibc-max-symbol-version:%s" % glibc_max_version.decode("ascii")) python_symbol_visibility = "global-default" elif host_platform == "macos": python_symbol_visibility = "global-default" extension_module_loading.append("shared-library") crt_features.append("libSystem") else: raise ValueError("unhandled platform: %s" % host_platform) # Create PYTHON.json file describing this distribution. python_info = { "version": "6", "target_triple": target_triple, "optimizations": optimizations, "python_tag": entry["python_tag"], "python_version": entry["version"], "python_stdlib_test_packages": sorted(STDLIB_TEST_PACKAGES), "python_symbol_visibility": python_symbol_visibility, "python_extension_module_loading": extension_module_loading, "libpython_link_mode": "static" if "musl" in target_triple else "shared", "crt_features": crt_features, "run_tests": "build/run_tests.py", "build_info": python_build_info( build_env, version, host_platform, "musl" in target_triple, optimizations, config_c_in, setup_dist_content, setup_local_content, libressl=libressl, ), "licenses": entry["licenses"], "license_path": "licenses/LICENSE.cpython.txt", } python_info["tcl_library_path"] = "install/lib" python_info["tcl_library_paths"] = [ "tcl8", "tcl8.6", "thread2.8.5", "Tix8.4.3", "tk8.6", ] # Add metadata derived from built distribution. extra_metadata = build_env.get_file("metadata.json") python_info.update(json.loads(extra_metadata)) validate_python_json(python_info) with tempfile.NamedTemporaryFile("w") as fh: json.dump(python_info, fh, sort_keys=True, indent=4) fh.flush() if image: dest_path = "/build/out/python" else: dest_path = "out/python" build_env.copy_file(fh.name, dest_path, dest_name="PYTHON.json") with open(dest_archive, "wb") as fh: fh.write(build_env.get_output_archive("python"))
def build_cpython(client, image, platform, debug=False, optimized=False, musl=False, libressl=False, version=None): """Build CPython in a Docker image'""" entry_name = 'cpython-%s' % version entry = DOWNLOADS[entry_name] python_archive = download_entry(entry_name, BUILD) setuptools_archive = download_entry('setuptools', BUILD) pip_archive = download_entry('pip', BUILD) with (SUPPORT / 'static-modules').open('rb') as fh: static_modules_lines = [ l.rstrip() for l in fh if not l.startswith(b'#') ] setup = derive_setup_local(static_modules_lines, python_archive, python_version=entry['version'], musl=musl, debug=debug) config_c_in = parse_config_c(setup['config_c_in'].decode('utf-8')) setup_dist_content = setup['setup_dist'] setup_local_content = setup['setup_local'] extra_make_content = setup['make_data'] with run_container(client, image) as container: copy_toolchain(container, musl=musl) dep_platform = platform if musl: dep_platform += '-musl' # TODO support bdb/gdbm toggle install_tools_archive(container, archive_path('bdb', platform, musl=musl)) install_tools_archive(container, archive_path('bzip2', platform, musl=musl)) install_tools_archive(container, archive_path('libedit', platform, musl=musl)) install_tools_archive(container, archive_path('libffi', platform, musl=musl)) install_tools_archive(container, archive_path('libX11', platform, musl=musl)) install_tools_archive(container, archive_path('libXau', platform, musl=musl)) install_tools_archive(container, archive_path('libxcb', platform, musl=musl)) install_tools_archive(container, archive_path('ncurses', platform, musl=musl)) if libressl: install_tools_archive( container, archive_path('libressl', platform, musl=musl)) else: install_tools_archive(container, archive_path('openssl', platform, musl=musl)) install_tools_archive(container, archive_path('readline', platform, musl=musl)) install_tools_archive(container, archive_path('sqlite', platform, musl=musl)) install_tools_archive(container, archive_path('tcl', platform, musl=musl)) install_tools_archive(container, archive_path('tk', platform, musl=musl)) install_tools_archive(container, archive_path('uuid', platform, musl=musl)) install_tools_archive(container, archive_path('xorgproto', platform, musl=musl)) install_tools_archive(container, archive_path('xz', platform, musl=musl)) install_tools_archive(container, archive_path('zlib', platform, musl=musl)) #copy_rust(container) copy_file_to_container(python_archive, container, '/build') copy_file_to_container(setuptools_archive, container, '/build') copy_file_to_container(pip_archive, container, '/build') copy_file_to_container(SUPPORT / 'build-cpython.sh', container, '/build') for f in sorted(os.listdir(ROOT)): if f.startswith('LICENSE.') and f.endswith('.txt'): copy_file_to_container(ROOT / f, container, '/build') # TODO copy latest pip/setuptools. with tempfile.NamedTemporaryFile('wb') as fh: fh.write(setup_local_content) fh.flush() copy_file_to_container(fh.name, container, '/build', archive_path='Setup.local') with tempfile.NamedTemporaryFile('wb') as fh: fh.write(extra_make_content) fh.flush() copy_file_to_container(fh.name, container, '/build', archive_path='Makefile.extra') env = { 'CC': 'clang', 'PIP_VERSION': DOWNLOADS['pip']['version'], 'PYTHON_VERSION': entry['version'], 'PYTHON_MAJMIN_VERSION': entry['version'][:3], 'SETUPTOOLS_VERSION': DOWNLOADS['setuptools']['version'], } if musl: env['CC'] = 'musl-clang' if debug: env['CPYTHON_DEBUG'] = '1' if optimized: env['CPYTHON_OPTIMIZED'] = '1' container_exec(container, '/build/build-cpython.sh', environment=env) fully_qualified_name = 'python%s%sm' % (entry['version'][0:3], 'd' if debug else '') # Create PYTHON.json file describing this distribution. python_info = { 'version': '2', 'os': 'linux', 'arch': 'x86_64', 'python_flavor': 'cpython', 'python_version': entry['version'], 'python_exe': 'install/bin/%s' % fully_qualified_name, 'python_include': 'install/include/%s' % fully_qualified_name, 'python_stdlib': 'install/lib/python%s' % entry['version'][0:3], 'build_info': python_build_info(container, config_c_in, setup_dist_content, setup_local_content, libressl=libressl), 'licenses': entry['licenses'], 'license_path': 'licenses/LICENSE.cpython.txt', } with tempfile.NamedTemporaryFile('w') as fh: json.dump(python_info, fh, sort_keys=True, indent=4) fh.flush() copy_file_to_container(fh.name, container, '/build/out/python', archive_path='PYTHON.json') basename = 'cpython-%s-%s' % (entry['version'], platform) if musl: basename += '-musl' if debug: basename += '-debug' if optimized: basename += '-pgo' basename += '.tar' dest_path = BUILD / basename data = container_get_archive(container, '/build/out/python') with dest_path.open('wb') as fh: fh.write(data)
def build_cpython( client, image, platform, debug=False, optimized=False, musl=False, libressl=False, version=None, ): """Build CPython in a Docker image'""" entry_name = "cpython-%s" % version entry = DOWNLOADS[entry_name] python_archive = download_entry(entry_name, DOWNLOADS_PATH) setuptools_archive = download_entry("setuptools", DOWNLOADS_PATH) pip_archive = download_entry("pip", DOWNLOADS_PATH) with (SUPPORT / ("static-modules.%s" % platform)).open("rb") as fh: static_modules_lines = [ l.rstrip() for l in fh if not l.startswith(b"#") ] with (SUPPORT / ("disabled-static-modules.%s" % platform)).open("rb") as fh: disabled_static_modules = { l.strip() for l in fh if l.strip() and not l.strip().startswith(b"#") } setup = derive_setup_local( static_modules_lines, python_archive, python_version=entry["version"], musl=musl, debug=debug, disabled=disabled_static_modules, ) config_c_in = parse_config_c(setup["config_c_in"].decode("utf-8")) setup_dist_content = setup["setup_dist"] setup_local_content = setup["setup_local"] extra_make_content = setup["make_data"] with build_environment(client, image) as build_env: build_env.install_toolchain(BUILD, platform, binutils=install_binutils(platform), clang=True, musl=musl) dep_platform = platform if musl: dep_platform += "-musl" # TODO support bdb/gdbm toggle packages = { "bdb", "bzip2", "libedit", "libffi", "sqlite", "uuid", "xz", "zlib", } if libressl: packages.add("libressl") else: packages.add("openssl") # We use the system ncurses on macOS for now. ncurses = platform != "macos" if ncurses: packages.add("ncurses") readline = platform != "macos" if readline: packages.add("readline") if platform == "linux64": packages |= {"libX11", "libXau", "libxcb", "xorgproto"} tix = platform != "macos" if tix: packages |= {"tcl", "tix", "tk"} for p in sorted(packages): build_env.install_artifact_archive(BUILD, p, platform, musl=musl) for p in ( python_archive, setuptools_archive, pip_archive, SUPPORT / "build-cpython.sh", ): build_env.copy_file(p) for f in sorted(os.listdir(ROOT)): if f.startswith("LICENSE.") and f.endswith(".txt"): build_env.copy_file(ROOT / f) with tempfile.NamedTemporaryFile("wb") as fh: # In case default file masks cause wonkiness. os.chmod(fh.name, 0o644) fh.write(setup_local_content) fh.flush() build_env.copy_file(fh.name, dest_name="Setup.local") with tempfile.NamedTemporaryFile("wb") as fh: os.chmod(fh.name, 0o644) fh.write(extra_make_content) fh.flush() build_env.copy_file(fh.name, dest_name="Makefile.extra") env = { "CC": "clang", "PIP_VERSION": DOWNLOADS["pip"]["version"], "PYTHON_VERSION": entry["version"], "PYTHON_MAJMIN_VERSION": entry["version"][:3], "SETUPTOOLS_VERSION": DOWNLOADS["setuptools"]["version"], "TOOLCHAIN": "clang-%s" % platform, } if musl: env["CC"] = "musl-clang" if debug: env["CPYTHON_DEBUG"] = "1" if optimized: env["CPYTHON_OPTIMIZED"] = "1" add_target_env(env, platform, build_env) build_env.run("build-cpython.sh", environment=env) fully_qualified_name = "python%s%sm" % ( entry["version"][0:3], "d" if debug else "", ) if platform == "linux64": os_name = "linux" elif platform == "macos": os_name = "macos" else: raise ValueError("unhandled platform: %s" % platform) # Create PYTHON.json file describing this distribution. python_info = { "version": "4", "os": os_name, "arch": "x86_64", "python_flavor": "cpython", "python_version": entry["version"], "python_exe": "install/bin/%s" % fully_qualified_name, "python_include": "install/include/%s" % fully_qualified_name, "python_stdlib": "install/lib/python%s" % entry["version"][0:3], "python_stdlib_test_packages": sorted(STDLIB_TEST_PACKAGES), "link_mode": "static", "build_info": python_build_info( build_env, platform, config_c_in, setup_dist_content, setup_local_content, libressl=libressl, ), "licenses": entry["licenses"], "license_path": "licenses/LICENSE.cpython.txt", "tcl_library_path": "install/lib/tcl", } with tempfile.NamedTemporaryFile("w") as fh: json.dump(python_info, fh, sort_keys=True, indent=4) fh.flush() if image: dest_path = "/build/out/python" else: dest_path = "out/python" build_env.copy_file(fh.name, dest_path, dest_name="PYTHON.json") basename = "cpython-%s-%s" % (entry["version"], platform) if musl: basename += "-musl" if debug: basename += "-debug" if optimized: basename += "-pgo" basename += ".tar" dest_path = BUILD / basename with dest_path.open("wb") as fh: fh.write(build_env.get_output_archive("python"))
def build_cpython(): python_archive = download_entry('cpython-3.7', BUILD) python_version = DOWNLOADS['cpython-3.7']['version'] with (SUPPORT / 'static-modules').open('rb') as fh: static_modules_lines = [ l.rstrip() for l in fh if not l.startswith(b'#') ] setup = derive_setup_local(static_modules_lines, python_archive, disabled=DISABLED_STATIC_MODULES) config_c_in = parse_config_c(setup['config_c_in'].decode('utf-8')) setup_dist_content = setup['setup_dist'] setup_local_content = setup['setup_local'] extra_make_content = setup['make_data'] with tempfile.TemporaryDirectory() as td: td = pathlib.Path(td) extract_tar_to_directory(BUILD / 'clang-macos.tar', td) toolchain_path = td / 'clang-macos' / 'bin' deps_dir = td / 'deps' deps_dir.mkdir() extract_tar_to_directory(BUILD / 'bdb-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'bzip2-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'libedit-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'libffi-macos.tar', deps_dir) # We use the system ncurses and statically link (for now). #extract_tar_to_directory(BUILD / 'ncurses-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'openssl-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'sqlite-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'uuid-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'xz-macos.tar', deps_dir) extract_tar_to_directory(BUILD / 'zlib-macos.tar', deps_dir) extract_tar_to_directory(python_archive, td) setup_local_path = td / ('Python-%s' % python_version) / 'Modules' / 'Setup.local' with setup_local_path.open('wb') as fh: fh.write(setup_local_content) makefile_extra_path = td / 'Makefile.extra' with makefile_extra_path.open('wb') as fh: fh.write(extra_make_content) shutil.copyfile(ROOT / 'python-licenses.rst', td / 'python-licenses.rst') env = dict(os.environ) env['PYTHON_VERSION'] = python_version # We force a PATH only containing system files: we don't want # pollution from homebrew, macports, etc. env['PATH'] = '%s:/usr/bin:/bin' % toolchain_path env['MACOSX_DEPLOYMENT_TARGET'] = MACOSX_DEPLOYMENT_TARGET env['NUM_CPUS'] = '%s' % multiprocessing.cpu_count() env['CPYTHON_OPTIMIZED'] = '1' exec_and_log([SUPPORT / 'build-cpython.sh'], td, env) # Create PYTHON.json file describing this distribution. python_info = { # TODO bump version number once format is somewhat stable. 'version': '0', 'os': 'macos', 'arch': 'x86_64', 'python_flavor': 'cpython', 'python_version': python_version, 'python_exe': 'install/bin/python3', 'python_include': 'install/include/python3.7m', 'python_stdlib': 'install/lib/python3.7', 'build_info': python_build_info(td / 'out' / 'python', config_c_in, setup_dist_content, setup_local_content), } with (td / 'out' / 'python' / 'PYTHON.json').open('w') as fh: json.dump(python_info, fh, sort_keys=True, indent=4) dest_path = BUILD / 'cpython-macos.tar' with dest_path.open('wb') as fh: create_tar_from_directory(fh, td / 'out')
def build_cpython(client, image, platform, optimized=False): """Build CPythin in a Docker image'""" python_archive = download_entry('cpython-3.7', BUILD) with (SUPPORT / 'static-modules').open('rb') as fh: static_modules_lines = [ l.rstrip() for l in fh if not l.startswith(b'#') ] setup = derive_setup_local(static_modules_lines, python_archive) config_c_in = parse_config_c(setup['config_c_in'].decode('utf-8')) setup_dist_content = setup['setup_dist'] setup_local_content = setup['setup_local'] extra_make_content = setup['make_data'] with run_container(client, image) as container: copy_toolchain(container, platform=platform) # TODO support bdb/gdbm toggle install_tools_archive(container, BUILD / ('bdb-%s.tar' % platform)) install_tools_archive(container, BUILD / ('bzip2-%s.tar' % platform)) install_tools_archive(container, BUILD / ('libedit-%s.tar' % platform)) install_tools_archive(container, BUILD / ('libffi-%s.tar' % platform)) install_tools_archive(container, BUILD / ('ncurses-%s.tar' % platform)) install_tools_archive(container, BUILD / ('openssl-%s.tar' % platform)) install_tools_archive(container, BUILD / ('readline-%s.tar' % platform)) install_tools_archive(container, BUILD / ('sqlite-%s.tar' % platform)) # tk requires a bunch of X11 stuff. #install_tools_archive(container, BUILD / ('tcltk-%s.tar' % platform)) install_tools_archive(container, BUILD / ('uuid-%s.tar' % platform)) install_tools_archive(container, BUILD / ('xz-%s.tar' % platform)) install_tools_archive(container, BUILD / ('zlib-%s.tar' % platform)) #copy_rust(container) copy_file_to_container(python_archive, container, '/build') copy_file_to_container(SUPPORT / 'build-cpython.sh', container, '/build') copy_file_to_container(ROOT / 'python-licenses.rst', container, '/build') # TODO copy latest pip/setuptools. with tempfile.NamedTemporaryFile('wb') as fh: fh.write(setup_local_content) fh.flush() copy_file_to_container(fh.name, container, '/build', archive_path='Setup.local') with tempfile.NamedTemporaryFile('wb') as fh: fh.write(extra_make_content) fh.flush() copy_file_to_container(fh.name, container, '/build', archive_path='Makefile.extra') env = { 'PYTHON_VERSION': DOWNLOADS['cpython-3.7']['version'], } if optimized: env['CPYTHON_OPTIMIZED'] = '1' container_exec(container, '/build/build-cpython.sh', environment=env) # Create PYTHON.json file describing this distribution. python_info = { # TODO bump version number once format is somewhat stable. 'version': '0', 'os': 'linux', 'arch': 'x86_64', 'python_flavor': 'cpython', 'python_version': DOWNLOADS['cpython-3.7']['version'], 'python_exe': 'install/bin/python', 'python_include': 'install/include/python3.7m', 'python_stdlib': 'install/lib/python3.7', 'build_info': python_build_info(container, config_c_in, setup_dist_content, setup_local_content), } with tempfile.NamedTemporaryFile('w') as fh: json.dump(python_info, fh, sort_keys=True, indent=4) fh.flush() copy_file_to_container(fh.name, container, '/build/out/python', archive_path='PYTHON.json') basename = 'cpython-%s' % platform if optimized: basename += '-pgo' basename += '.tar' dest_path = BUILD / basename data, stat = container.get_archive('/build/out/python') with dest_path.open('wb') as fh: for chunk in data: fh.write(chunk)
def build_cpython( settings, client, image, host_platform, target_triple, optimizations, dest_archive, version=None, ): """Build CPython in a Docker image'""" entry_name = "cpython-%s" % version entry = DOWNLOADS[entry_name] python_version = entry["version"] python_archive = download_entry(entry_name, DOWNLOADS_PATH) setuptools_archive = download_entry("setuptools", DOWNLOADS_PATH) pip_archive = download_entry("pip", DOWNLOADS_PATH) with get_target_support_file(SUPPORT, "static-modules", version, host_platform, target_triple).open("rb") as fh: static_modules_lines = [ l.rstrip() for l in fh if not l.startswith(b"#") ] with get_target_support_file(SUPPORT, "disabled-static-modules", version, host_platform, target_triple).open("rb") as fh: disabled_static_modules = { l.strip() for l in fh if l.strip() and not l.strip().startswith(b"#") } setup = derive_setup_local( static_modules_lines, python_archive, python_version=python_version, musl="musl" in target_triple, debug=optimizations == "debug", disabled=disabled_static_modules, ) config_c_in = parse_config_c(setup["config_c_in"].decode("utf-8")) setup_dist_content = setup["setup_dist"] setup_local_content = setup["setup_local"] extra_make_content = setup["make_data"] with build_environment(client, image) as build_env: if settings.get("needs_toolchain"): build_env.install_toolchain( BUILD, host_platform, binutils=install_binutils(host_platform), clang=True, musl="musl" in target_triple, ) packages = target_needs(TARGETS_CONFIG, target_triple, python_version) # Toolchain packages are handled specially. packages.discard("binutils") packages.discard("musl") for p in sorted(packages): build_env.install_artifact_archive(BUILD, p, target_triple, optimizations) for p in ( python_archive, setuptools_archive, pip_archive, SUPPORT / "build-cpython.sh", ): build_env.copy_file(p) for f in sorted(os.listdir(ROOT)): if f.startswith("LICENSE.") and f.endswith(".txt"): build_env.copy_file(ROOT / f) with tempfile.NamedTemporaryFile("wb") as fh: # In case default file masks cause wonkiness. os.chmod(fh.name, 0o644) fh.write(setup_local_content) fh.flush() build_env.copy_file(fh.name, dest_name="Setup.local") with tempfile.NamedTemporaryFile("wb") as fh: os.chmod(fh.name, 0o644) fh.write(extra_make_content) fh.flush() build_env.copy_file(fh.name, dest_name="Makefile.extra") env = { "PIP_VERSION": DOWNLOADS["pip"]["version"], "PYTHON_VERSION": entry["version"], "PYTHON_MAJMIN_VERSION": ".".join(entry["version"].split(".")[0:2]), "SETUPTOOLS_VERSION": DOWNLOADS["setuptools"]["version"], "TOOLCHAIN": "clang-%s" % host_platform, } if optimizations == "debug": env["CPYTHON_DEBUG"] = "1" if optimizations in ("pgo", "pgo+lto"): env["CPYTHON_OPTIMIZED"] = "1" if optimizations in ("lto", "pgo+lto"): env["CPYTHON_LTO"] = "1" add_target_env(env, host_platform, target_triple, build_env) build_env.run("build-cpython.sh", environment=env) extension_module_loading = ["builtin"] crt_features = [] if host_platform == "linux64": if "musl" in target_triple: crt_features.append("static") else: extension_module_loading.append("shared-library") crt_features.append("glibc-dynamic") glibc_max_version = build_env.get_file( "glibc_version.txt").strip() if not glibc_max_version: raise Exception( "failed to retrieve glibc max symbol version") crt_features.append("glibc-max-symbol-version:%s" % glibc_max_version.decode("ascii")) python_symbol_visibility = "global-default" elif host_platform == "macos": python_symbol_visibility = "global-default" extension_module_loading.append("shared-library") crt_features.append("libSystem") else: raise ValueError("unhandled platform: %s" % host_platform) extra_metadata = json.loads(build_env.get_file("metadata.json")) # Create PYTHON.json file describing this distribution. python_info = { "version": "7", "target_triple": target_triple, "optimizations": optimizations, "python_tag": entry["python_tag"], "python_version": entry["version"], "python_stdlib_test_packages": sorted(STDLIB_TEST_PACKAGES), "python_symbol_visibility": python_symbol_visibility, "python_extension_module_loading": extension_module_loading, "libpython_link_mode": "static" if "musl" in target_triple else "shared", "crt_features": crt_features, "run_tests": "build/run_tests.py", "build_info": python_build_info( build_env, version, host_platform, target_triple, "musl" in target_triple, optimizations, config_c_in, setup_dist_content, setup_local_content, extra_metadata, ), "licenses": entry["licenses"], "license_path": "licenses/LICENSE.cpython.txt", } python_info["tcl_library_path"] = "install/lib" python_info["tcl_library_paths"] = [ "itcl4.2.2", "tcl8", "tcl8.6", "thread2.8.7", "tk8.6", ] if "-apple" not in target_triple: python_info["tcl_library_paths"].append("Tix8.4.3") if "-apple" in target_triple: python_info["apple_sdk_platform"] = env["APPLE_SDK_PLATFORM"] python_info["apple_sdk_version"] = env["APPLE_SDK_VERSION"] python_info["apple_sdk_canonical_name"] = env[ "APPLE_SDK_CANONICAL_NAME"] python_info["apple_sdk_deployment_target"] = env[ "APPLE_MIN_DEPLOYMENT_TARGET"] # Add metadata derived from built distribution. python_info.update(extra_metadata) validate_python_json(python_info) with tempfile.NamedTemporaryFile("w") as fh: json.dump(python_info, fh, sort_keys=True, indent=4) fh.flush() if image: dest_path = "/build/out/python" else: dest_path = "out/python" build_env.copy_file(fh.name, dest_path, dest_name="PYTHON.json") with open(dest_archive, "wb") as fh: fh.write(build_env.get_output_archive("python"))