Skip to content

Commit d348a40

Browse files
[WASM] Implement build-script for WebAssembly/WASI
1 parent 44a6475 commit d348a40

File tree

10 files changed

+188
-7
lines changed

10 files changed

+188
-7
lines changed

CMakeLists.txt

+13-3
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,11 @@ set(SWIFT_ANDROID_DEPLOY_DEVICE_PATH "" CACHE STRING
260260
"Path on an Android device where build products will be pushed. These are used when running the test suite against the device")
261261

262262
#
263-
# User-configurable ICU specific options for Android, FreeBSD, Linux and Haiku.
263+
# User-configurable ICU specific options for Android, FreeBSD, Linux, Haiku, and WebAssembly/WASI.
264264
#
265265

266-
foreach(sdk ANDROID;FREEBSD;LINUX;WINDOWS;HAIKU)
267-
foreach(arch aarch64;armv6;armv7;i686;powerpc64;powerpc64le;s390x;x86_64)
266+
foreach(sdk ANDROID;FREEBSD;LINUX;WINDOWS;HAIKU;WASI)
267+
foreach(arch aarch64;armv6;armv7;i686;powerpc64;powerpc64le;s390x;wasm32;x86_64)
268268
set(SWIFT_${sdk}_${arch}_ICU_UC "" CACHE STRING
269269
"Path to a directory containing the icuuc library for ${sdk}")
270270
set(SWIFT_${sdk}_${arch}_ICU_UC_INCLUDE "" CACHE STRING
@@ -595,6 +595,8 @@ else()
595595
set(SWIFT_HOST_VARIANT_ARCH_default "powerpc64le")
596596
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x")
597597
set(SWIFT_HOST_VARIANT_ARCH_default "s390x")
598+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "wasm32")
599+
set(SWIFT_HOST_VARIANT_ARCH_default "wasm32")
598600
# FIXME: Only matches v6l/v7l - by far the most common variants
599601
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l")
600602
set(SWIFT_HOST_VARIANT_ARCH_default "armv6")
@@ -779,6 +781,14 @@ if(swift_build_windows AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
779781
configure_sdk_windows("Windows" "msvc" "${SWIFT_SDK_WINDOWS_ARCHITECTURES}")
780782
endif()
781783

784+
is_sdk_requested(WASI swift_build_wasi)
785+
if(swift_build_wasi AND NOT "${SWIFT_HOST_VARIANT_SDK}" STREQUAL "WASI")
786+
if("${SWIFT_SDK_WASI_ARCHITECTURES}" STREQUAL "")
787+
set(SWIFT_SDK_WASI_ARCHITECTURES wasm32)
788+
endif()
789+
configure_sdk_unix("WASI" "${SWIFT_SDK_WASI_ARCHITECTURES}")
790+
endif()
791+
782792
if("${SWIFT_SDKS}" STREQUAL "")
783793
set(SWIFT_SDKS "${SWIFT_CONFIGURED_SDKS}")
784794
endif()

cmake/modules/SwiftConfigureSDK.cmake

+10
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ macro(configure_sdk_unix name architectures)
217217
set(SWIFT_SDK_${prefix}_ARCHITECTURES "${architectures}")
218218
if("${prefix}" STREQUAL "CYGWIN")
219219
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "COFF")
220+
elseif("${prefix}" STREQUAL "WASI")
221+
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "WASM")
220222
else()
221223
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "ELF")
222224
endif()
@@ -333,6 +335,14 @@ macro(configure_sdk_unix name architectures)
333335
message(FATAL_ERROR "unsupported arch for Haiku: ${arch}")
334336
endif()
335337
set(SWIFT_SDK_HAIKU_ARCH_x86_64_TRIPLE "x86_64-unknown-haiku")
338+
elseif("${prefix}" STREQUAL "WASI")
339+
if(NOT arch STREQUAL wasm32)
340+
message(FATAL_ERROR "unsupported arch for WASI: ${arch}")
341+
endif()
342+
set(SWIFT_SDK_WASI_ARCH_wasm32_PATH "${SWIFT_WASI_SYSROOT}")
343+
set(SWIFT_SDK_WASI_ARCH_wasm32_TRIPLE "wasm32-unknown-wasi")
344+
set(SWIFT_SDK_WASI_ARCH_wasm32_LIBC_INCLUDE_DIRECTORY "${SWIFT_WASI_SYSROOT}/include")
345+
set(SWIFT_SDK_WASI_ARCH_wasm32_LIBC_ARCHITECTURE_INCLUDE_DIRECTORY "${SWIFT_WASI_SYSROOT}/include")
336346
else()
337347
message(FATAL_ERROR "unknown Unix OS: ${prefix}")
338348
endif()

cmake/modules/SwiftSetIfArchBitness.cmake

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ function(set_if_arch_bitness var_name)
1212
"${SIA_ARCH}" STREQUAL "armv6" OR
1313
"${SIA_ARCH}" STREQUAL "armv7" OR
1414
"${SIA_ARCH}" STREQUAL "armv7k" OR
15-
"${SIA_ARCH}" STREQUAL "armv7s")
15+
"${SIA_ARCH}" STREQUAL "armv7s" OR
16+
"${SIA_ARCH}" STREQUAL "wasm32")
1617
set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE)
1718
elseif("${SIA_ARCH}" STREQUAL "x86_64" OR
1819
"${SIA_ARCH}" STREQUAL "arm64" OR

test/CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ function(get_test_dependencies SDK result_var_name)
7575
("${SDK}" STREQUAL "FREEBSD") OR
7676
("${SDK}" STREQUAL "ANDROID") OR
7777
("${SDK}" STREQUAL "WINDOWS") OR
78-
("${SDK}" STREQUAL "HAIKU"))
78+
("${SDK}" STREQUAL "HAIKU") OR
79+
("${SDK}" STREQUAL "WASI"))
7980
# No extra dependencies.
8081
else()
8182
message(FATAL_ERROR "Unknown SDK: ${SDK}")

utils/build-script

+34
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,20 @@ def validate_arguments(toolchain, args):
200200
"--android-icu-i18n-include, and --android-icu-data "
201201
"must be specified")
202202

203+
if args.wasi:
204+
if args.wasi_sysroot is None or \
205+
args.wasi_icu_uc is None or \
206+
args.wasi_icu_uc_include is None or \
207+
args.wasi_icu_i18n is None or \
208+
args.wasi_icu_i18n_include is None or \
209+
args.wasi_icu_data is None:
210+
diagnostics.fatal(
211+
"when building for WebAssembly, --wasi-sdk, "
212+
"--wasi-icu-uc, "
213+
"--wasi-icu-uc-include, --wasi-icu-i18n, "
214+
"--wasi-icu-i18n-include, and --wasi-icu-data "
215+
"must be specified")
216+
203217
targets_needing_toolchain = [
204218
'build_indexstoredb',
205219
'build_pythonkit',
@@ -296,6 +310,10 @@ def apply_default_arguments(toolchain, args):
296310
args.stdlib_deployment_targets.append(
297311
StdlibDeploymentTarget.Android.aarch64.name)
298312

313+
if args.wasi:
314+
args.stdlib_deployment_targets.append(
315+
StdlibDeploymentTarget.WASI.wasm32.name)
316+
299317
# Infer platform flags from manually-specified configure targets.
300318
# This doesn't apply to Darwin platforms, as they are
301319
# already configured. No building without the platform flag, though.
@@ -565,6 +583,8 @@ class BuildScriptInvocation(object):
565583
impl_args += ["--skip-build-watchos-simulator"]
566584
if not args.build_android:
567585
impl_args += ["--skip-build-android"]
586+
if not args.build_wasi:
587+
impl_args += ["--skip-build-wasi"]
568588
if not args.build_clang_tools_extra:
569589
impl_args += ["--skip-build-clang-tools-extra"]
570590

@@ -605,6 +625,10 @@ class BuildScriptInvocation(object):
605625
impl_args += ["--skip-test-android"]
606626
if not args.test_android_host:
607627
impl_args += ["--skip-test-android-host"]
628+
if not args.test_wasi:
629+
impl_args += ["--skip-test-wasi"]
630+
if not args.test_wasi_host:
631+
impl_args += ["--skip-test-wasi-host"]
608632
if args.build_runtime_with_host_compiler:
609633
impl_args += ["--build-runtime-with-host-compiler"]
610634
if args.validation_test:
@@ -645,6 +669,16 @@ class BuildScriptInvocation(object):
645669
args.android_deploy_device_path,
646670
]
647671

672+
if args.wasi:
673+
impl_args += [
674+
"--wasi-sysroot", args.wasi_sysroot,
675+
"--wasi-icu-uc", args.wasi_icu_uc,
676+
"--wasi-icu-uc-include", args.wasi_icu_uc_include,
677+
"--wasi-icu-i18n", args.wasi_icu_i18n,
678+
"--wasi-icu-i18n-include", args.wasi_icu_i18n_include,
679+
"--wasi-icu-data", args.wasi_icu_data,
680+
]
681+
648682
if platform.system() == 'Darwin':
649683
impl_args += [
650684
"--toolchain-prefix",

utils/build-script-impl

+29-1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ KNOWN_SETTINGS=(
115115
darwin-toolchain-version "" "Version for xctoolchain info plist and installer pkg"
116116
darwin-xcrun-toolchain "default" "the name of the toolchain to use on Darwin"
117117

118+
## WebAssembly/WASI Options
119+
wasi-sysroot "" "An absolute path to the WASI sysroot that will be used as a libc implementation for WebAssembly builds"
120+
wasi-icu-uc "" "Path to libicuuc.a"
121+
wasi-icu-uc-include "" "Path to a directory containing headers for libicuuc"
122+
wasi-icu-i18n "" "Path to libicui18n.a"
123+
wasi-icu-i18n-include "" "Path to a directory containing headers libicui18n"
124+
wasi-icu-data "" "Path to libicudata.a"
125+
118126
## Build Types for Components
119127
swift-stdlib-build-type "Debug" "the CMake build variant for Swift"
120128

@@ -135,6 +143,7 @@ KNOWN_SETTINGS=(
135143
skip-build-osx "" "set to skip building Swift stdlibs for OS X"
136144
skip-build-tvos-device "" "set to skip building Swift stdlibs for tvOS devices (i.e. build simulators only)"
137145
skip-build-tvos-simulator "" "set to skip building Swift stdlibs for tvOS simulators (i.e. build devices only)"
146+
skip-build-wasi "" "set to skip building Swift stdlibs for WebAssembly/WASI"
138147
skip-build-watchos-device "" "set to skip building Swift stdlibs for Apple watchOS devices (i.e. build simulators only)"
139148
skip-build-watchos-simulator "" "set to skip building Swift stdlibs for Apple watchOS simulators (i.e. build devices only)"
140149

@@ -152,6 +161,8 @@ KNOWN_SETTINGS=(
152161
skip-test-osx "" "set to skip testing Swift stdlibs for OS X"
153162
skip-test-tvos-host "" "set to skip testing the host parts of the tvOS toolchain"
154163
skip-test-tvos-simulator "" "set to skip testing Swift stdlibs for tvOS simulators (i.e. test devices only)"
164+
skip-test-wasi "" "set to skip testing Swift stdlibs for WebAssembly/WASI"
165+
skip-test-wasi-host "" "set to skip testing the host parts of the WebAssembly/WASI toolchain"
155166
skip-test-watchos-host "" "set to skip testing the host parts of the watchOS toolchain"
156167
skip-test-watchos-simulator "" "set to skip testing Swift stdlibs for Apple watchOS simulators (i.e. test devices only)"
157168
skip-test-benchmarks "" "set to skip running Swift Benchmark Suite"
@@ -425,7 +436,8 @@ function verify_host_is_supported() {
425436
| watchsimulator-i386 \
426437
| watchos-armv7k \
427438
| android-armv7 \
428-
| android-aarch64)
439+
| android-aarch64 \
440+
| wasi-wasm32)
429441
;;
430442
*)
431443
echo "Unknown host tools target: ${host}"
@@ -1187,6 +1199,9 @@ function common_cross_c_flags() {
11871199
watchos-*)
11881200
echo -n " -arch ${arch} -mwatchos-version-min=${DARWIN_DEPLOYMENT_VERSION_WATCHOS}"
11891201
;;
1202+
wasi-wasm32)
1203+
echo -n " -arch wasm32"
1204+
;;
11901205
esac
11911206

11921207
local build_type=$2
@@ -1569,6 +1584,19 @@ for host in "${ALL_HOSTS[@]}"; do
15691584
)
15701585
fi
15711586

1587+
if [[ ! "${SKIP_BUILD_WASM}" ]]; then
1588+
cmake_options=(
1589+
"${cmake_options[@]}"
1590+
-DSWIFT_WASI_SYSROOT_PATH:STRING="${WASI_SYSROOT}"
1591+
-DSWIFT_WASI_wasm32_ICU_UC:STRING="${WASI_ICU_UC}"
1592+
-DSWIFT_WASI_wasm32_ICU_UC_INCLUDE:STRING="${WASI_ICU_UC_INCLUDE}"
1593+
-DSWIFT_WASI_wasm32_ICU_I18N:STRING="${WASI_ICU_I18N}"
1594+
-DSWIFT_WASI_wasm32_ICU_I18N_INCLUDE:STRING="${WASI_ICU_I18N_INCLUDE}"
1595+
-DSWIFT_WASI_wasm32_ICU_DATA:STRING="${WASI_ICU_DATA}"
1596+
)
1597+
fi
1598+
1599+
15721600
if [[ "${DARWIN_OVERLAY_TARGET}" != "" ]]; then
15731601
# Split LOCAL_HOST into a pair ``arch-sdk``
15741602
# Example LOCAL_HOST: macosx-x86_64

utils/build_swift/build_swift/driver_arguments.py

+44
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ def _apply_default_arguments(args):
148148
if not args.android or not args.build_android:
149149
args.build_android = False
150150

151+
if not args.wasi or not args.build_wasi:
152+
args.build_wasi = False
153+
151154
# --test-paths implies --test and/or --validation-test
152155
# depending on what directories/files have been specified.
153156
if args.test_paths:
@@ -184,6 +187,7 @@ def _apply_default_arguments(args):
184187
args.test_tvos = False
185188
args.test_watchos = False
186189
args.test_android = False
190+
args.test_wasi = False
187191
args.test_swiftpm = False
188192
args.test_swiftsyntax = False
189193
args.test_indexstoredb = False
@@ -230,11 +234,19 @@ def _apply_default_arguments(args):
230234
if not args.test_android:
231235
args.test_android_host = False
232236

237+
if not args.build_wasi:
238+
args.test_wasi = False
239+
args.test_wasi_host = False
240+
241+
if not args.test_wasi:
242+
args.test_wasi_host = False
243+
233244
if not args.host_test:
234245
args.test_ios_host = False
235246
args.test_tvos_host = False
236247
args.test_watchos_host = False
237248
args.test_android_host = False
249+
args.test_wasi_host = False
238250

239251

240252
def create_argument_parser():
@@ -323,6 +335,9 @@ def create_argument_parser():
323335
option('--android', toggle_true,
324336
help='also build for Android')
325337

338+
option('--wasi', toggle_true,
339+
help='also build for WebAssembly/WASI')
340+
326341
option('--swift-analyze-code-coverage', store,
327342
choices=['false', 'not-merged', 'merged'],
328343
# so CMake can see the inert mode as a false value
@@ -919,6 +934,9 @@ def create_argument_parser():
919934
option('--skip-build-android', toggle_false('build_android'),
920935
help='skip building Swift stdlibs for Android')
921936

937+
option('--skip-build-wasi', toggle_false('build_wasi'),
938+
help='skip building Swift stdlibs for WebAssembly/WASI')
939+
922940
option('--skip-build-benchmarks', toggle_false('build_benchmarks'),
923941
help='skip building Swift Benchmark Suite')
924942

@@ -975,6 +993,14 @@ def create_argument_parser():
975993
help='skip testing Android device targets on the host machine (the '
976994
'phone itself)')
977995

996+
option('--skip-test-wasi',
997+
toggle_false('test_wasi'),
998+
help='skip testing all WebAssembly/WASI targets.')
999+
option('--skip-test-wasi-host',
1000+
toggle_false('test_wasi_host'),
1001+
help='skip testing WebAssembly/WASI device targets on the host machine (the '
1002+
'WebAssembly/WASI runtime)')
1003+
9781004
option('--skip-test-swiftpm', toggle_false('test_swiftpm'),
9791005
help='skip testing swiftpm')
9801006
option('--skip-test-swiftsyntax', toggle_false('test_swiftsyntax'),
@@ -1043,6 +1069,24 @@ def create_argument_parser():
10431069
'Currently only armv7 and aarch64 are supported. '
10441070
'%(default)s is the default.')
10451071

1072+
# -------------------------------------------------------------------------
1073+
in_group('Build settings for WebAssembly/WASI')
1074+
1075+
option('--wasi-sysroot', store_path,
1076+
help='An absolute path to WASI sysroot that will be used as a libc '
1077+
'implementation for WebAssembly builds')
1078+
1079+
option('--wasi-icu-uc', store_path,
1080+
help='Path to libicuuc.a')
1081+
option('--wasi-icu-uc-include', store_path,
1082+
help='Path to a directory containing headers for libicuuc')
1083+
option('--wasi-icu-i18n', store_path,
1084+
help='Path to libicui18n.a')
1085+
option('--wasi-icu-i18n-include', store_path,
1086+
help='Path to a directory containing headers libicui18n')
1087+
option('--wasi-icu-data', store_path,
1088+
help='Path to libicudata.a')
1089+
10461090
# -------------------------------------------------------------------------
10471091
in_group('Experimental language features')
10481092

utils/swift_build_support/swift_build_support/host_specific_configuration.py

+6
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ def __platforms_to_skip_build(self, args):
201201
StdlibDeploymentTarget.AppleWatchSimulator)
202202
if not args.build_android:
203203
platforms_to_skip_build.add(StdlibDeploymentTarget.Android)
204+
if not args.build_wasi:
205+
platforms_to_skip_build.add(StdlibDeploymentTarget.WASI)
204206
return platforms_to_skip_build
205207

206208
def __platforms_to_skip_test(self, args):
@@ -240,6 +242,8 @@ def __platforms_to_skip_test(self, args):
240242
StdlibDeploymentTarget.AppleWatchSimulator)
241243
if not args.test_android:
242244
platforms_to_skip_test.add(StdlibDeploymentTarget.Android)
245+
if not args.test_wasi:
246+
platforms_to_skip_test.add(StdlibDeploymentTarget.WASI)
243247

244248
return platforms_to_skip_test
245249

@@ -254,6 +258,8 @@ def __platforms_to_skip_test_host(self, args):
254258
platforms_to_skip_test_host = set()
255259
if not args.test_android_host:
256260
platforms_to_skip_test_host.add(StdlibDeploymentTarget.Android)
261+
if not args.test_wasi_host:
262+
platforms_to_skip_test_host.add(StdlibDeploymentTarget.WASI)
257263
if not args.test_ios_host:
258264
platforms_to_skip_test_host.add(StdlibDeploymentTarget.iOS)
259265
if not args.test_tvos_host:

utils/swift_build_support/swift_build_support/targets.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ class StdlibDeploymentTarget(object):
158158

159159
Haiku = Platform("haiku", archs=["x86_64"])
160160

161+
WASI = Platform("wasi", archs=["wasm32"])
162+
161163
# The list of known platforms.
162164
known_platforms = [
163165
OSX,
@@ -169,7 +171,8 @@ class StdlibDeploymentTarget(object):
169171
Cygwin,
170172
Android,
171173
Windows,
172-
Haiku]
174+
Haiku,
175+
WASI]
173176

174177
# Cache of targets by name.
175178
_targets_by_name = dict((target.name, target)
@@ -233,6 +236,10 @@ def host_target():
233236
if machine == 'x86_64':
234237
return StdlibDeploymentTarget.Haiku.x86_64
235238

239+
elif system == 'WASI':
240+
if machine == 'wasm32':
241+
return StdlibDeploymentTarget.WASI.wasm32
242+
236243
raise NotImplementedError('System "%s" with architecture "%s" is not '
237244
'supported' % (system, machine))
238245

0 commit comments

Comments
 (0)