From d909e0b8a7c991867886655a42afdc7e75def4e0 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Wed, 11 Jun 2025 16:31:10 +0900 Subject: [PATCH 1/3] Enable building swift-testing for wasm32-unknown-wasip1-threads --- ...ding-swift-testing-for-wasm32-unknow.patch | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 schemes/main/swift/0001-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch diff --git a/schemes/main/swift/0001-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch b/schemes/main/swift/0001-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch new file mode 100644 index 0000000..a7ea819 --- /dev/null +++ b/schemes/main/swift/0001-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch @@ -0,0 +1,171 @@ +From b702fbfc0d98516fae058c7b43908d55e1f8e67e Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Wed, 11 Jun 2025 16:05:40 +0900 +Subject: [PATCH] [wasm] Enable building swift-testing for + wasm32-unknown-wasip1-threads + +--- + .../products/wasmswiftsdk.py | 102 ++++++++++-------- + 1 file changed, 58 insertions(+), 44 deletions(-) + +diff --git a/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py b/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py +index ad4f197a174..987722f901b 100644 +--- a/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py ++++ b/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py +@@ -16,6 +16,7 @@ from . import product + from . import wasisysroot + from .swift_testing import SwiftTestingCMakeShim + from .wasmstdlib import WasmStdlib, WasmThreadsStdlib ++from .cmake_product import CMakeProduct + from .. import shell + + +@@ -41,52 +42,66 @@ class WasmSwiftSDK(product.Product): + def _target_package_path(self, swift_host_triple): + return os.path.join(self.build_dir, 'Toolchains', swift_host_triple) + +- def _build_swift_testing(self, swift_host_triple, short_triple, wasi_sysroot): +- # TODO: We currently build swift-testing outside of SwiftTesting +- # build-script product because we build Wasm stdlib outside of +- # the main Swift build unit and we can't use build-script's cross +- # compilation infrastructure. +- # Once stdlib build is decoupled from compiler's CMake build unit +- # and we can use different CMake options for different targets +- # for stdlib build, we can fully unify library builds with the +- # regular path. +- dest_dir = self._target_package_path(swift_host_triple) ++ def _append_platform_cmake_options(self, cmake_options, swift_host_triple, has_pthread, wasi_sysroot, extra_swift_flags): ++ cmake_options.define('CMAKE_SYSTEM_NAME:STRING', 'WASI') ++ cmake_options.define('CMAKE_SYSTEM_PROCESSOR:STRING', 'wasm32') ++ cmake_options.define('CMAKE_C_COMPILER_TARGET', swift_host_triple) ++ cmake_options.define('CMAKE_CXX_COMPILER_TARGET', swift_host_triple) ++ cmake_options.define( ++ 'CMAKE_Swift_COMPILER_TARGET', swift_host_triple) ++ cmake_options.define('CMAKE_SYSROOT', wasi_sysroot) + +- swift_testing = SwiftTestingCMakeShim( ++ dest_dir = self._target_package_path(swift_host_triple) ++ swift_resource_dir = os.path.join(dest_dir, 'usr', 'lib', 'swift_static') ++ clang_resource_dir = os.path.join(swift_resource_dir, 'clang') ++ ++ swift_flags = ['-sdk', wasi_sysroot, '-resource-dir', swift_resource_dir] + extra_swift_flags ++ c_flags = ['-resource-dir', clang_resource_dir] ++ cxx_flags = c_flags + ['-fno-exceptions'] ++ if has_pthread: ++ clang_flags = ['-mthread-model', 'posix', '-pthread'] ++ c_flags.extend(clang_flags) ++ cxx_flags.extend(clang_flags) ++ swift_flags.extend(['-Xcc', '-matomics', '-Xcc', '-mbulk-memory', '-Xcc', '-mthread-model', '-Xcc', 'posix', '-Xcc', '-pthread']) ++ ++ cmake_options.define('CMAKE_Swift_FLAGS', ' '.join(swift_flags)) ++ cmake_options.define('CMAKE_C_FLAGS', ' '.join(c_flags)) ++ cmake_options.define('CMAKE_CXX_FLAGS', ' '.join(cxx_flags)) ++ cmake_options.define('CMAKE_Swift_COMPILER_FORCED', 'TRUE') ++ cmake_options.define('CMAKE_CXX_COMPILER_FORCED', 'TRUE') ++ cmake_options.define('CMAKE_BUILD_TYPE', self.args.build_variant) ++ ++ # Explicitly choose ar and ranlib from just-built LLVM tools since tools in the host system ++ # unlikely support Wasm object format. ++ native_toolchain_path = self.native_toolchain_path(self.args.host_target) ++ cmake_options.define('CMAKE_AR', os.path.join(native_toolchain_path, 'bin', 'llvm-ar')) ++ cmake_options.define('CMAKE_RANLIB', os.path.join(native_toolchain_path, 'bin', 'llvm-ranlib')) ++ ++ def _build_swift_testing(self, swift_host_triple, has_pthread, wasi_sysroot): ++ swift_testing = CMakeProduct( + args=self.args, + toolchain=self.toolchain, + source_dir=os.path.join( + os.path.dirname(self.source_dir), 'swift-testing'), +- build_dir=os.path.join( +- os.path.dirname(self.build_dir), +- 'swift-testing-%s' % short_triple)) +- +- swift_testing.cmake_options.define('CMAKE_SYSTEM_NAME:STRING', 'WASI') +- swift_testing.cmake_options.define('CMAKE_SYSTEM_PROCESSOR:STRING', 'wasm32') +- swift_testing.cmake_options.define( +- 'CMAKE_CXX_COMPILER_TARGET', swift_host_triple) +- swift_testing.cmake_options.define( +- 'CMAKE_Swift_COMPILER_TARGET', swift_host_triple) +- swift_testing.cmake_options.define('CMAKE_SYSROOT', wasi_sysroot) +- swift_resource_dir = os.path.join(dest_dir, 'usr', 'lib', 'swift_static') ++ build_dir=os.path.join(self.build_dir, 'swift-testing', swift_host_triple)) + # For statically linked objects in an archive, we have to use singlethreaded + # LLVM codegen unit to prevent runtime metadata sections from being stripped + # at link-time. +- swift_testing.cmake_options.define( +- 'CMAKE_Swift_FLAGS', +- f'-sdk {wasi_sysroot} -resource-dir {swift_resource_dir} -Xfrontend -enable-single-module-llvm-emission') +- clang_resource_dir = os.path.join(dest_dir, 'usr', 'lib', 'clang') +- swift_testing.cmake_options.define( +- 'CMAKE_CXX_FLAGS', f'-resource-dir {clang_resource_dir}') +- swift_testing.cmake_options.define('CMAKE_Swift_COMPILER_FORCED', 'TRUE') +- swift_testing.cmake_options.define('CMAKE_CXX_COMPILER_FORCED', 'TRUE') +- +- swift_testing.build('wasi-wasm32') ++ self._append_platform_cmake_options( ++ swift_testing.cmake_options, swift_host_triple, has_pthread, wasi_sysroot, ++ extra_swift_flags=['-Xfrontend', '-enable-single-module-llvm-emission']) ++ swift_testing.cmake_options.define('BUILD_SHARED_LIBS', 'FALSE') ++ swift_testing.cmake_options.define('CMAKE_Swift_COMPILATION_MODE', 'wholemodule') ++ swift_testing.cmake_options.define('SwiftTesting_MACRO', 'NO') ++ ++ swift_testing.build_with_cmake([], self.args.build_variant, [], ++ prefer_native_toolchain=True) ++ dest_dir = self._target_package_path(swift_host_triple) + with shell.pushd(swift_testing.build_dir): + shell.call([self.toolchain.cmake, '--install', '.', '--prefix', '/usr'], + env={'DESTDIR': dest_dir}) + +- def _build_target_package(self, swift_host_triple, short_triple, ++ def _build_target_package(self, swift_host_triple, has_pthread, + stdlib_build_path, llvm_runtime_libs_build_path, + wasi_sysroot): + +@@ -107,7 +122,7 @@ class WasmSwiftSDK(product.Product): + '--component', 'clang_rt.builtins-wasm32'], + env={'DESTDIR': clang_dir}) + # Build swift-testing +- self._build_swift_testing(swift_host_triple, short_triple, wasi_sysroot) ++ self._build_swift_testing(swift_host_triple, has_pthread, wasi_sysroot) + + return dest_dir + +@@ -115,17 +130,15 @@ class WasmSwiftSDK(product.Product): + build_root = os.path.dirname(self.build_dir) + + target_packages = [] +- # NOTE: We have three types of target triples: ++ # NOTE: We have two types of target triples: + # 1. swift_host_triple: The triple used by the Swift compiler's '-target' option + # 2. clang_multiarch_triple: The triple used by Clang to find library + # and header paths from the sysroot + # https://github.com/llvm/llvm-project/blob/73ef397fcba35b7b4239c00bf3e0b4e689ca0add/clang/lib/Driver/ToolChains/WebAssembly.cpp#L29-L36 +- # 3. short_triple: The triple used by build-script to name the build directory +- for swift_host_triple, clang_multiarch_triple, short_triple, build_basename in [ +- ('wasm32-unknown-wasi', 'wasm32-wasi', 'wasi-wasm32', 'wasmstdlib'), +- # TODO: Enable threads stdlib once sdk-generator supports multi-target SDK +- # ('wasm32-unknown-wasip1-threads', 'wasm32-wasip1-threads', +- # 'wasip1-threads-wasm32', 'wasmthreadsstdlib'), ++ for swift_host_triple, clang_multiarch_triple, build_basename, build_sdk, has_pthread in [ ++ ('wasm32-unknown-wasi', 'wasm32-wasi', 'wasmstdlib', True, False), ++ # TODO: Include p1-threads in the Swift SDK once sdk-generator supports multi-target SDK ++ ('wasm32-unknown-wasip1-threads', 'wasm32-wasip1-threads', 'wasmthreadsstdlib', False, True), + ]: + stdlib_build_path = os.path.join( + build_root, '%s-%s' % (build_basename, host_target)) +@@ -135,9 +148,10 @@ class WasmSwiftSDK(product.Product): + build_root, '%s-%s' % ('wasmllvmruntimelibs', host_target), + clang_multiarch_triple) + package_path = self._build_target_package( +- swift_host_triple, short_triple, stdlib_build_path, ++ swift_host_triple, has_pthread, stdlib_build_path, + llvm_runtime_libs_build_path, wasi_sysroot) +- target_packages.append((swift_host_triple, wasi_sysroot, package_path)) ++ if build_sdk: ++ target_packages.append((swift_host_triple, wasi_sysroot, package_path)) + + swiftc_path = os.path.abspath(self.toolchain.swiftc) + toolchain_path = os.path.dirname(os.path.dirname(swiftc_path)) +-- +2.39.5 (Apple Git-154) + From e85bd9eab426b9609c7274617e50e651fc08f16f Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Wed, 11 Jun 2025 16:31:29 +0900 Subject: [PATCH 2/3] Adjust swift-testing build directory --- schemes/main/build/build-target-toolchain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemes/main/build/build-target-toolchain.sh b/schemes/main/build/build-target-toolchain.sh index 30f2286..8e53202 100755 --- a/schemes/main/build/build-target-toolchain.sh +++ b/schemes/main/build/build-target-toolchain.sh @@ -40,7 +40,7 @@ build_target_toolchain() { env DESTDIR="$TRIPLE_DESTDIR" \ cmake --install "$TARGET_BUILD_ROOT/$STDLIB_PRODUCT-$HOST_SUFFIX" --prefix /usr - local swift_testing_build_dir="$TARGET_BUILD_ROOT/swift-testing-$SHORT_TRIPLE" + local swift_testing_build_dir="$TARGET_BUILD_ROOT/wasmswiftsdk-$HOST_SUFFIX/swift-testing/$TRIPLE" # TODO: Remove this check once we build swift-testing for +threads target if [[ -d "$swift_testing_build_dir" ]]; then env DESTDIR="$TRIPLE_DESTDIR" \ From f9c51bb299bf31d519d63810e7fafe8230a2520b Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Wed, 11 Jun 2025 16:35:01 +0900 Subject: [PATCH 3/3] Add preliminary patch --- ...ting.a-objects-with-single-threaded-.patch | 41 +++++++++++++++++++ ...ing-swift-testing-for-wasm32-unknow.patch} | 0 2 files changed, 41 insertions(+) create mode 100644 schemes/main/swift/0001-wasm-Emit-libTesting.a-objects-with-single-threaded-.patch rename schemes/main/swift/{0001-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch => 0002-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch} (100%) diff --git a/schemes/main/swift/0001-wasm-Emit-libTesting.a-objects-with-single-threaded-.patch b/schemes/main/swift/0001-wasm-Emit-libTesting.a-objects-with-single-threaded-.patch new file mode 100644 index 0000000..b4e0987 --- /dev/null +++ b/schemes/main/swift/0001-wasm-Emit-libTesting.a-objects-with-single-threaded-.patch @@ -0,0 +1,41 @@ +From e46480e98c8eb6eb08b8ec0bb0de58fbd9831ff3 Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Mon, 9 Jun 2025 21:39:17 +0000 +Subject: [PATCH] [wasm] Emit libTesting.a objects with single-threaded LLVM + codegen unit + +Since 5f2b0022d14d6eaddd48d4f36034c31218965ead, swift-testing is being +compiled with WMO, which removes some of inter-object references in +object files by DCE. The inter-object reference removal revealed a +long-standing issue that the runtime metadata sections of objects in an +archive are not always included in the final binary if symbols from +those objects are not referenced anywhere. To force including all +metadata sections in the final binary, we have to emit everything in a +single object file when building the archive. +This issue happens only for Wasm SDK, which ships swift-testing as a +static archive. +--- + .../swift_build_support/products/wasmswiftsdk.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py b/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py +index e5769ca9622..ad4f197a174 100644 +--- a/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py ++++ b/utils/swift_build_support/swift_build_support/products/wasmswiftsdk.py +@@ -69,9 +69,12 @@ class WasmSwiftSDK(product.Product): + 'CMAKE_Swift_COMPILER_TARGET', swift_host_triple) + swift_testing.cmake_options.define('CMAKE_SYSROOT', wasi_sysroot) + swift_resource_dir = os.path.join(dest_dir, 'usr', 'lib', 'swift_static') ++ # For statically linked objects in an archive, we have to use singlethreaded ++ # LLVM codegen unit to prevent runtime metadata sections from being stripped ++ # at link-time. + swift_testing.cmake_options.define( + 'CMAKE_Swift_FLAGS', +- f'-sdk {wasi_sysroot} -resource-dir {swift_resource_dir}') ++ f'-sdk {wasi_sysroot} -resource-dir {swift_resource_dir} -Xfrontend -enable-single-module-llvm-emission') + clang_resource_dir = os.path.join(dest_dir, 'usr', 'lib', 'clang') + swift_testing.cmake_options.define( + 'CMAKE_CXX_FLAGS', f'-resource-dir {clang_resource_dir}') +-- +2.39.5 (Apple Git-154) + diff --git a/schemes/main/swift/0001-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch b/schemes/main/swift/0002-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch similarity index 100% rename from schemes/main/swift/0001-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch rename to schemes/main/swift/0002-wasm-Enable-building-swift-testing-for-wasm32-unknow.patch