Skip to content

Commit 0c8dd88

Browse files
committed
[utils/build-parser-lib] Add capability for cross-compiling the parser library for embedded platforms
1 parent a59f438 commit 0c8dd88

File tree

1 file changed

+140
-29
lines changed

1 file changed

+140
-29
lines changed

utils/build-parser-lib

Lines changed: 140 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
from __future__ import print_function
2626

27+
import copy
2728
import multiprocessing
2829
import os
2930
import platform
@@ -32,6 +33,7 @@ import sys
3233
from build_swift import argparse, defaults
3334
from swift_build_support.swift_build_support import (
3435
shell,
36+
xcrun,
3537
)
3638
from swift_build_support.swift_build_support.SwiftBuildSupport import (
3739
HOME,
@@ -43,7 +45,7 @@ from swift_build_support.swift_build_support.toolchain import host_toolchain
4345
isDarwin = platform.system() == 'Darwin'
4446

4547
class Builder(object):
46-
def __init__(self, toolchain, args, profile_data=None, arch=None, native_build_dir=None):
48+
def __init__(self, toolchain, args, host, arch, profile_data=None, native_build_dir=None):
4749
self.toolchain = toolchain
4850
self.ninja_path = args.ninja_path
4951
self.build_release = args.release
@@ -59,6 +61,7 @@ class Builder(object):
5961
self.install_destdir = args.install_destdir
6062
self.install_prefix = args.install_prefix
6163
self.version = args.version
64+
self.host = host
6265
self.arch = arch
6366
self.native_build_dir = native_build_dir
6467

@@ -71,16 +74,84 @@ class Builder(object):
7174
def configure(self, enable_debuginfo, instrumentation=None, profile_data=None):
7275
cmake_args = [self.toolchain.cmake, '-G', 'Ninja']
7376
cmake_args += ['-DCMAKE_MAKE_PROGRAM='+self.ninja_path]
77+
78+
isEmbeddedHost = isDarwin and self.host != 'macosx'
79+
host_triple = None
80+
host_sdk = None
81+
llvm_c_flags = "-arch "+self.arch
82+
83+
if self.host == 'macosx':
84+
deployment_version = '10.12'
85+
host_triple = '%s-apple-macosx%s' % (self.arch, deployment_version)
86+
host_sdk = 'OSX'
87+
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET='+deployment_version, '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX='+deployment_version]
88+
89+
elif self.host == 'linux':
90+
host_triple = '%s-unknown-linux' % (self.arch)
91+
host_sdk = 'LINUX'
92+
93+
elif self.host == 'iphonesimulator':
94+
deployment_version = '10.0'
95+
host_triple = '%s-apple-ios%s-simulator' % (self.arch, deployment_version)
96+
host_sdk = 'IOS_SIMULATOR'
97+
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET='+deployment_version, '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_IOS='+deployment_version]
98+
llvm_c_flags += ' -mios-simulator-version-min='+deployment_version
99+
100+
elif self.host == 'iphoneos':
101+
deployment_version = '10.0'
102+
host_triple = '%s-apple-ios%s' % (self.arch, deployment_version)
103+
host_sdk = 'IOS'
104+
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET='+deployment_version, '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_IOS='+deployment_version]
105+
llvm_c_flags += ' -miphoneos-version-min=='+deployment_version
106+
107+
elif self.host == 'appletvsimulator':
108+
deployment_version = '10.0'
109+
host_triple = '%s-apple-tvos%s-simulator' % (self.arch, deployment_version)
110+
host_sdk = 'TVOS_SIMULATOR'
111+
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET='+deployment_version, '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS='+deployment_version]
112+
llvm_c_flags += ' -mtvos-simulator-version-min='+deployment_version
113+
114+
elif self.host == 'appletvos':
115+
deployment_version = '10.0'
116+
host_triple = '%s-apple-tvos%s' % (self.arch, deployment_version)
117+
host_sdk = 'TVOS'
118+
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET='+deployment_version, '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS='+deployment_version]
119+
llvm_c_flags += ' -mtvos-version-min='+deployment_version
120+
121+
elif self.host == 'watchsimulator':
122+
deployment_version = '3.0'
123+
host_triple = '%s-apple-watchos%s-simulator' % (self.arch, deployment_version)
124+
host_sdk = 'WATCHOS_SIMULATOR'
125+
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET='+deployment_version, '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS='+deployment_version]
126+
llvm_c_flags += ' -mwatchos-simulator-version-min='+deployment_version
127+
128+
elif self.host == 'watchos':
129+
deployment_version = '3.0'
130+
host_triple = '%s-apple-watchos%s' % (self.arch, deployment_version)
131+
host_sdk = 'WATCHOS'
132+
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET='+deployment_version, '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS='+deployment_version]
133+
llvm_c_flags += ' -mwatchos-version-min='+deployment_version
134+
135+
assert host_triple
136+
assert host_sdk
137+
cmake_args += [
138+
'-DLLVM_HOST_TRIPLE:STRING='+host_triple,
139+
'-DLLVM_TARGET_ARCH='+self.arch,
140+
'-DSWIFT_HOST_VARIANT='+self.host,
141+
'-DSWIFT_HOST_VARIANT_SDK='+host_sdk,
142+
'-DSWIFT_HOST_VARIANT_ARCH='+self.arch,
143+
'-DCMAKE_C_FLAGS='+llvm_c_flags,
144+
'-DCMAKE_CXX_FLAGS='+llvm_c_flags,
145+
]
146+
if isEmbeddedHost:
147+
cmake_args += [
148+
'-DCMAKE_OSX_SYSROOT:PATH='+xcrun.sdk_path(self.host),
149+
# For embedded hosts CMake runs the checks and triggers crashes because the test binary was built for embedded host.
150+
'-DHAVE_POSIX_REGEX:BOOL=TRUE',
151+
'-DHAVE_STEADY_CLOCK:BOOL=TRUE',
152+
]
153+
74154
if isDarwin:
75-
cmake_args += ['-DCMAKE_OSX_DEPLOYMENT_TARGET=10.12', '-DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX=10.12']
76-
if self.arch is not None:
77-
cmake_args += [
78-
'-DLLVM_HOST_TRIPLE:STRING='+self.arch+'-apple-darwin16.0',
79-
'-DSWIFT_HOST_TRIPLE:STRING='+self.arch+'-apple-darwin16.0',
80-
'-DCMAKE_C_FLAGS=-arch '+self.arch,
81-
'-DCMAKE_CXX_FLAGS=-arch '+self.arch,
82-
'-DSWIFT_HOST_VARIANT_ARCH='+self.arch,
83-
]
84155
if self.native_build_dir is not None:
85156
cmake_args += [
86157
'-DLLVM_TABLEGEN='+os.path.join(self.native_build_dir, 'bin', 'llvm-tblgen'),
@@ -92,7 +163,7 @@ class Builder(object):
92163
]
93164
else:
94165
dispatch_source_path = os.path.join(SWIFT_SOURCE_ROOT, 'swift-corelibs-libdispatch')
95-
cmake_args += ['-DSWIFT_HOST_VARIANT=linux', '-DSWIFT_HOST_VARIANT_SDK=LINUX', '-DSWIFT_HOST_VARIANT_ARCH=x86_64',
166+
cmake_args += [
96167
'-DSWIFT_PATH_TO_LIBDISPATCH_SOURCE:PATH='+dispatch_source_path,
97168
'-DLLVM_ENABLE_LLD=ON']
98169
cmake_args += ['-DLLVM_TARGETS_TO_BUILD=X86']
@@ -190,6 +261,7 @@ def main():
190261
store_path = optbuilder.actions.store_path
191262

192263
toolchain = host_toolchain(xcrun_toolchain='default')
264+
default_host = 'macosx' if isDarwin else 'linux'
193265
default_architectures = platform.machine()
194266

195267
default_profile_input = os.path.join(SWIFT_SOURCE_ROOT, "swift", "utils", "parser-lib", "profile-input.swift")
@@ -229,6 +301,10 @@ def main():
229301
option('--build-dir', store_path,
230302
default=default_build_dir,
231303
help='the path where the build products will be placed. (default = %s)' % default_build_dir)
304+
option('--host', store,
305+
choices=['macosx', 'linux', 'iphonesimulator', 'iphoneos', 'appletvsimulator', 'appletvos', 'watchsimulator', 'watchos'],
306+
default=default_host,
307+
help='host platform to build for (default = %s)' % default_host)
232308
option('--architectures', store,
233309
default=default_architectures,
234310
help='space-separated list of architectures to build for. (default = %s)' % default_architectures)
@@ -251,47 +327,82 @@ def main():
251327
if not args.install_destdir:
252328
args.install_destdir = os.path.join(args.build_dir, 'install')
253329

254-
if isDarwin:
255-
architectures = args.architectures.split(" ")
256-
architectures = [arch for arch in architectures if arch != platform.machine() and arch != ""]
257-
if platform.machine() in architectures: architectures = [platform.machine()] + architectures
330+
architectures = args.architectures.split(" ")
331+
architectures = [arch for arch in architectures if arch != ""]
332+
if platform.machine() in architectures:
333+
# Make sure the machine architecture is at the front.
334+
architectures.remove(platform.machine())
258335
architectures = [platform.machine()] + architectures
259336

337+
if isDarwin:
260338
objroot = args.build_dir
261339
dstroot = args.install_destdir
262340
symroot = args.install_symroot
263341
prefix = args.install_prefix
264342

265-
for arch in architectures:
266-
native = platform.machine() == arch
343+
native_build_dir = None
344+
profile_data = None
345+
dst_dirs = []
267346

268-
args.build_dir = os.path.join(objroot, arch, "obj")
269-
args.install_destdir = os.path.join(objroot, arch, "dst")
270-
args.install_prefix = "/"
347+
if args.host == 'macosx' and architectures[0] == platform.machine():
348+
# Build for the native machine.
349+
arch = architectures.pop(0)
350+
tmpargs = copy.copy(args)
351+
tmpargs.build_dir = os.path.join(objroot, arch, "obj")
352+
tmpargs.install_destdir = os.path.join(objroot, arch, "dst")
353+
tmpargs.install_prefix = "/"
271354

272-
native_build_dir = None if native else os.path.join(objroot, platform.machine(), "obj")
355+
native_build_dir = tmpargs.build_dir
356+
dst_dirs.append(tmpargs.install_destdir)
273357

274-
profile_data = None
275-
if args.pgo_type:
358+
if tmpargs.pgo_type:
276359
profile_dir = os.path.join(objroot, platform.machine()+'-profiling')
277-
if native:
278-
builder = Builder(toolchain, args)
279-
builder.get_profile_data(profile_dir)
360+
builder = Builder(toolchain, tmpargs, tmpargs.host, arch)
361+
builder.get_profile_data(profile_dir)
280362
profile_data = os.path.join(profile_dir, "profdata.prof")
281363

282-
builder = Builder(toolchain, args, profile_data=profile_data, arch=arch, native_build_dir=native_build_dir)
364+
builder = Builder(toolchain, tmpargs, tmpargs.host, arch, profile_data=profile_data)
365+
builder.run()
366+
367+
else:
368+
tmpargs = copy.copy(args)
369+
if tmpargs.pgo_type:
370+
# Build for the machine and get profile data.
371+
native_build_dir = os.path.join(objroot, platform.machine()+'-profiling')
372+
builder = Builder(toolchain, tmpargs, 'macosx', platform.machine())
373+
builder.get_profile_data(native_build_dir)
374+
profile_data = os.path.join(native_build_dir, "profdata.prof")
375+
else:
376+
# Build the tablegen binaries so we can use them for the cross-compile build.
377+
native_build_dir = os.path.join(objroot, platform.machine()+'-tblgen')
378+
tmpargs.lto_type = None
379+
builder = Builder(toolchain, tmpargs, 'macosx', platform.machine())
380+
shell.makedirs(native_build_dir, dry_run=tmpargs.dry_run)
381+
with shell.pushd(native_build_dir, dry_run=tmpargs.dry_run):
382+
builder.configure(enable_debuginfo=False)
383+
builder.build_target(native_build_dir, 'llvm-tblgen')
384+
builder.build_target(native_build_dir, 'clang-tblgen')
385+
386+
for arch in architectures:
387+
args.build_dir = os.path.join(objroot, arch, "obj")
388+
args.install_destdir = os.path.join(objroot, arch, "dst")
389+
args.install_prefix = "/"
390+
391+
dst_dirs.append(args.install_destdir)
392+
393+
builder = Builder(toolchain, args, args.host, arch, profile_data=profile_data, native_build_dir=native_build_dir)
283394
builder.run()
284395

285396
lipo = os.path.join(SWIFT_SOURCE_ROOT, "swift", "utils", "recursive-lipo")
286-
dst_dirs = [os.path.join(objroot, arch, "dst") for arch in architectures]
287397
shell.call([lipo, "-v", "--destination", os.path.join(dstroot, "./"+prefix)] + dst_dirs)
288398

289399
if args.install_symroot:
290400
extract_symbols(dstroot, prefix, symroot, args.build_jobs)
291401

292402
return 0
293403

294-
builder = Builder(toolchain, args)
404+
assert args.architectures == platform.machine(), "building for non-machine architecture is not supported for non-darwin host"
405+
builder = Builder(toolchain, args, args.host, args.architectures)
295406
builder.run()
296407
return 0
297408

0 commit comments

Comments
 (0)