Skip to content

Commit 3315850

Browse files
committed
Allow cross-compiling swift-format
This should build swift-format as a fat binary containing both an x86_64 and an arm64 slice in the open source toolchains.
1 parent 4e397f4 commit 3315850

File tree

1 file changed

+69
-3
lines changed

1 file changed

+69
-3
lines changed

build-script-helper.py

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import subprocess
2121
from pathlib import Path
2222
from typing import List, Union, Optional
23+
import json
2324

2425
# -----------------------------------------------------------------------------
2526
# General utilities
@@ -68,11 +69,29 @@ def escape_cmd_arg(arg: Union[str, Path]) -> str:
6869
# SwiftPM wrappers
6970

7071

72+
def get_build_target(swift_exec: Path, cross_compile_config: Optional[Path]) -> str:
73+
"""Returns the target-triple of the current machine or for cross-compilation."""
74+
command = [swift_exec, "-print-target-info"]
75+
if cross_compile_config:
76+
cross_compile_json = json.load(open(cross_compile_config))
77+
command += ["-target", cross_compile_json["target"]]
78+
target_info_json = subprocess.check_output(
79+
command, stderr=subprocess.PIPE, universal_newlines=True
80+
).strip()
81+
target_info = json.loads(target_info_json)
82+
if "-apple-macosx" in target_info["target"]["unversionedTriple"]:
83+
return target_info["target"]["unversionedTriple"]
84+
return target_info["target"]["triple"]
85+
86+
7187
def get_swiftpm_options(
88+
swift_exec: Path,
7289
package_path: Path,
7390
build_path: Path,
7491
multiroot_data_file: Optional[Path],
7592
configuration: str,
93+
cross_compile_host: Optional[str],
94+
cross_compile_config: Optional[Path],
7695
verbose: bool,
7796
) -> List[Union[str, Path]]:
7897
args: List[Union[str, Path]] = [
@@ -87,8 +106,17 @@ def get_swiftpm_options(
87106
args += ["--multiroot-data-file", multiroot_data_file]
88107
if verbose:
89108
args += ["--verbose"]
90-
if platform.system() == "Darwin":
91-
args += ["-Xlinker", "-rpath", "-Xlinker", "/usr/lib/swift"]
109+
build_target = get_build_target(
110+
swift_exec, cross_compile_config=cross_compile_config
111+
)
112+
build_os = build_target.split("-")[2]
113+
if build_os.startswith("macosx"):
114+
args += [
115+
"-Xlinker",
116+
"-rpath",
117+
"-Xlinker",
118+
"/usr/lib/swift",
119+
]
92120
args += [
93121
"-Xlinker",
94122
"-rpath",
@@ -101,6 +129,21 @@ def get_swiftpm_options(
101129
"-Xlinker",
102130
"@executable_path/../lib/swift-5.5/macosx",
103131
]
132+
else:
133+
# Library rpath for swift, dispatch, Foundation, etc. when installing
134+
args += [
135+
"-Xlinker",
136+
"-rpath",
137+
"-Xlinker",
138+
"$ORIGIN/../lib/swift/" + build_os,
139+
]
140+
141+
if cross_compile_host:
142+
if build_os.startswith("macosx") and cross_compile_host.startswith("macosx-"):
143+
args += ["--arch", "x86_64", "--arch", "arm64"]
144+
else:
145+
fatal_error("cannot cross-compile for %s" % cross_compile_host)
146+
104147
return args
105148

106149

@@ -118,6 +161,8 @@ def invoke_swiftpm(
118161
build_path: Path,
119162
multiroot_data_file: Optional[Path],
120163
configuration: str,
164+
cross_compile_host: Optional[str],
165+
cross_compile_config: Optional[Path],
121166
env,
122167
verbose: bool,
123168
):
@@ -126,7 +171,14 @@ def invoke_swiftpm(
126171
"""
127172
args = [swift_exec, action]
128173
args += get_swiftpm_options(
129-
package_path, build_path, multiroot_data_file, configuration, verbose
174+
swift_exec=swift_exec,
175+
package_path=package_path,
176+
build_path=build_path,
177+
multiroot_data_file=multiroot_data_file,
178+
configuration=configuration,
179+
cross_compile_host=cross_compile_host,
180+
cross_compile_config=cross_compile_config,
181+
verbose=verbose,
130182
)
131183
if action == "test":
132184
args += ["--test-product", product, "--disable-testable-imports"]
@@ -151,6 +203,8 @@ def build(args: argparse.Namespace) -> None:
151203
build_path=args.build_path,
152204
multiroot_data_file=args.multiroot_data_file,
153205
configuration=args.configuration,
206+
cross_compile_host=args.cross_compile_host,
207+
cross_compile_config=args.cross_compile_config,
154208
env=env,
155209
verbose=args.verbose,
156210
)
@@ -167,6 +221,8 @@ def test(args: argparse.Namespace) -> None:
167221
build_path=args.build_path,
168222
multiroot_data_file=args.multiroot_data_file,
169223
configuration=args.configuration,
224+
cross_compile_host=args.cross_compile_host,
225+
cross_compile_config=args.cross_compile_config,
170226
env=env,
171227
verbose=args.verbose,
172228
)
@@ -179,10 +235,13 @@ def install(args: argparse.Namespace) -> None:
179235

180236
env = get_swiftpm_environment_variables()
181237
swiftpm_args = get_swiftpm_options(
238+
swift_exec=args.swift_exec,
182239
package_path=args.package_path,
183240
build_path=args.build_path,
184241
multiroot_data_file=args.multiroot_data_file,
185242
configuration=args.configuration,
243+
cross_compile_host=args.cross_compile_host,
244+
cross_compile_config=args.cross_compile_config,
186245
verbose=args.verbose,
187246
)
188247
cmd = [args.swift_exec, "build", "--show-bin-path"] + swiftpm_args
@@ -222,6 +281,13 @@ def add_common_args(parser: argparse.ArgumentParser) -> None:
222281
type=Path,
223282
help="the toolchain to use when building this package",
224283
)
284+
parser.add_argument(
285+
"--cross-compile-host", help="cross-compile for another host instead"
286+
)
287+
parser.add_argument(
288+
"--cross-compile-config",
289+
help="an SPM JSON destination file containing Swift cross-compilation flags",
290+
)
225291

226292

227293
def parse_args() -> argparse.Namespace:

0 commit comments

Comments
 (0)