|
25 | 25 | meets_python_minimum_version, |
26 | 26 | parse_setup_line, |
27 | 27 | ) |
28 | | -from pythonbuild.docker import build_docker_image, get_image, write_dockerfiles |
| 28 | +from pythonbuild.docker import ( |
| 29 | + build_docker_image, |
| 30 | + docker_platform_from_host_platform, |
| 31 | + get_image, |
| 32 | + write_dockerfiles, |
| 33 | +) |
29 | 34 | from pythonbuild.downloads import DOWNLOADS |
30 | 35 | from pythonbuild.logging import log, set_logger |
31 | 36 | from pythonbuild.utils import ( |
32 | 37 | add_env_common, |
33 | 38 | add_licenses_to_extension_entry, |
34 | 39 | clang_toolchain, |
35 | 40 | create_tar_from_directory, |
| 41 | + current_host_platform, |
36 | 42 | download_entry, |
37 | 43 | get_target_settings, |
38 | 44 | get_targets, |
@@ -98,21 +104,33 @@ def add_target_env(env, build_platform, target_triple, build_env, build_options) |
98 | 104 | extra_target_ldflags.append("--rtlib=compiler-rt") |
99 | 105 |
|
100 | 106 | if build_platform.startswith("linux_"): |
101 | | - machine = platform.machine() |
| 107 | + # autoconf is not aware of microarch triples. Normalize those out: |
| 108 | + # we force targeting via -march CFLAG. |
| 109 | + env["TARGET_TRIPLE"] = ( |
| 110 | + target_triple.replace("x86_64_v2-", "x86_64-") |
| 111 | + .replace("x86_64_v3-", "x86_64-") |
| 112 | + .replace("x86_64_v4-", "x86_64-") |
| 113 | + ) |
102 | 114 |
|
103 | | - # arm64 allows building for Linux on a macOS host using Docker |
104 | | - if machine == "aarch64" or machine == "arm64": |
105 | | - env["BUILD_TRIPLE"] = "aarch64-unknown-linux-gnu" |
106 | | - env["TARGET_TRIPLE"] = target_triple |
107 | | - elif machine == "x86_64": |
108 | | - env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu" |
109 | | - env["TARGET_TRIPLE"] = ( |
110 | | - target_triple.replace("x86_64_v2-", "x86_64-") |
111 | | - .replace("x86_64_v3-", "x86_64-") |
112 | | - .replace("x86_64_v4-", "x86_64-") |
113 | | - ) |
| 115 | + # On macOS, we support building Linux in a virtualized container that |
| 116 | + # always matches the target platform. Set build/host triple to whatever |
| 117 | + # we're building. |
| 118 | + # |
| 119 | + # Note: we always use the *-gnu triple otherwise autoconf can have |
| 120 | + # trouble reasoning about cross-compiling since its detected triple from |
| 121 | + # our build environment is always GNU based. |
| 122 | + if current_host_platform().startswith("macos_"): |
| 123 | + env["BUILD_TRIPLE"] = env["TARGET_TRIPLE"].replace("-musl", "-gnu") |
114 | 124 | else: |
115 | | - raise Exception("unhandled Linux machine value: %s" % machine) |
| 125 | + # Otherwise assume the container environment matches the machine |
| 126 | + # type of the current process. |
| 127 | + host_machine = platform.machine() |
| 128 | + if host_machine == "aarch64" or host_machine == "arm64": |
| 129 | + env["BUILD_TRIPLE"] = "aarch64-unknown-linux-gnu" |
| 130 | + elif host_machine == "x86_64": |
| 131 | + env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu" |
| 132 | + else: |
| 133 | + raise Exception("unhandled Linux machine value: %s" % host_machine) |
116 | 134 |
|
117 | 135 | # This will make x86_64_v2, etc count as cross-compiling. This is |
118 | 136 | # semantically correct, since the current machine may not support |
@@ -960,16 +978,6 @@ def main(): |
960 | 978 | DOWNLOADS_PATH.mkdir(exist_ok=True) |
961 | 979 | (BUILD / "logs").mkdir(exist_ok=True) |
962 | 980 |
|
963 | | - if os.environ.get("PYBUILD_NO_DOCKER"): |
964 | | - client = None |
965 | | - else: |
966 | | - try: |
967 | | - client = docker.from_env(timeout=600) |
968 | | - client.ping() |
969 | | - except Exception as e: |
970 | | - print("unable to connect to Docker: %s" % e, file=sys.stderr) |
971 | | - return 1 |
972 | | - |
973 | 981 | # Note these arguments must be synced with `build-main.py` |
974 | 982 | parser = argparse.ArgumentParser() |
975 | 983 | parser.add_argument( |
@@ -1031,6 +1039,17 @@ def main(): |
1031 | 1039 |
|
1032 | 1040 | settings = get_target_settings(TARGETS_CONFIG, target_triple) |
1033 | 1041 |
|
| 1042 | + if os.environ.get("PYBUILD_NO_DOCKER"): |
| 1043 | + client = None |
| 1044 | + else: |
| 1045 | + try: |
| 1046 | + client = docker.from_env(timeout=600) |
| 1047 | + client.ping() |
| 1048 | + client._pbs_platform = docker_platform_from_host_platform(host_platform) |
| 1049 | + except Exception as e: |
| 1050 | + print("unable to connect to Docker: %s" % e, file=sys.stderr) |
| 1051 | + return 1 |
| 1052 | + |
1034 | 1053 | if args.action == "dockerfiles": |
1035 | 1054 | log_name = "dockerfiles" |
1036 | 1055 | elif args.action == "makefiles": |
|
0 commit comments