1+ From 8db43c6290ee04145264c04728a030dd74f87452
2+ From: Marc Prud'hommeaux <
[email protected] >
3+ Date: Sun, 18 May 2025 19:10:36 -0400
4+ Subject: Support 16 KB page sizes on Android
5+
6+ Android 15+ requires that native libraries be compiled with a linker flag to support 16 KB page sizes. See: https://developer.android.com/guide/practices/page-sizes#compile-r26-lower
7+
8+ diff --git a/swift/stdlib/cmake/modules/AddSwiftStdlib.cmake b/swift/stdlib/cmake/modules/AddSwiftStdlib.cmake
9+ index ce113989ad75d..089f5f30acbb5 100644
10+ --- a/swift/stdlib/cmake/modules/AddSwiftStdlib.cmake
11+ +++ b/swift/stdlib/cmake/modules/AddSwiftStdlib.cmake
12+ @@ -2469,6 +2469,8 @@ function(add_swift_target_library name)
13+ list(APPEND swiftlib_link_flags_all "-shared")
14+ # TODO: Instead of `lib${name}.so` find variable or target property which already have this value.
15+ list(APPEND swiftlib_link_flags_all "-Wl,-soname,lib${name}.so")
16+ + # Ensure compatibility with Android 15+ devices using 16KB memory pages.
17+ + list(APPEND swiftlib_link_flags_all "-Wl,-z,max-page-size=16384")
18+ endif()
19+
20+ if (SWIFTLIB_BACK_DEPLOYMENT_LIBRARY)
21+ diff --git a/swift/utils/swift_build_support/swift_build_support/targets.py b/swift/utils/swift_build_support/swift_build_support/targets.py
22+ index fba09416ddb90..7f3f35ec8097c 100644
23+ --- a/swift/utils/swift_build_support/swift_build_support/targets.py
24+ +++ b/swift/utils/swift_build_support/swift_build_support/targets.py
25+ @@ -72,7 +72,7 @@ class Platform(object):
26+ return True
27+ return False
28+
29+ - def swift_flags(self, args):
30+ + def swift_flags(self, args, resource_path=None):
31+ """
32+ Swift compiler flags for a platform, useful for cross-compiling
33+ """
34+ @@ -154,17 +154,21 @@ class AndroidPlatform(Platform):
35+ """
36+ return True
37+
38+ - def swift_flags(self, args):
39+ + def swift_flags(self, args, resource_path=None):
40+ flags = '-target %s-unknown-linux-android%s ' % (args.android_arch,
41+ args.android_api_level)
42+
43+ - flags += '-resource-dir %s/swift-%s-%s/lib/swift ' % (
44+ - args.build_root, self.name, args.android_arch)
45+ + if resource_path is not None:
46+ + flags += '-resource-dir %s ' % (resource_path)
47+ + else:
48+ + flags += '-resource-dir %s/swift-%s-%s/lib/swift ' % (
49+ + args.build_root, self.name, args.android_arch)
50+
51+ android_toolchain_path = self.ndk_toolchain_path(args)
52+
53+ flags += '-sdk %s/sysroot ' % (android_toolchain_path)
54+ - flags += '-tools-directory %s/bin' % (android_toolchain_path)
55+ + flags += '-tools-directory %s/bin ' % (android_toolchain_path)
56+ + flags += '-Xclang-linker -Wl,-z,max-page-size=16384'
57+ return flags
58+
59+ def cmake_options(self, args):
160diff --git a/swift/utils/build-script-impl b/swift/utils/build-script-impl
261index 16e05052609..7ab8cebfab8 100755
362--- a/swift/utils/build-script-impl
@@ -25,18 +84,68 @@ index e62eb23c8bb..d88c3c242ad 100644
2584 """
2685 Generates a new CMake tolchain file that specifies Linux as a target
2786 platform.
28- @@ -402,8 +408,9 @@ class Product(object):
87+ @@ -409,18 +409,32 @@ class Product(object):
2988
3089 toolchain_args = {}
3190
3291- toolchain_args['CMAKE_SYSTEM_NAME'] = 'Linux'
3392- toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch
3493+ if crosscompiling:
35- + toolchain_args['CMAKE_SYSTEM_NAME'] = 'Linux'
36- + toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch
94+ + if platform == "linux":
95+ + toolchain_args['CMAKE_SYSTEM_NAME'] = 'Linux'
96+ + toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch
97+ + elif platform == "android":
98+ + toolchain_args['CMAKE_SYSTEM_NAME'] = 'Android'
99+ + toolchain_args['CMAKE_SYSTEM_VERSION'] = self.args.android_api_level
100+ + toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = self.args.android_arch if not \
101+ + self.args.android_arch == 'armv7' else 'armv7-a'
102+ + toolchain_args['CMAKE_ANDROID_NDK'] = self.args.android_ndk
103+ + toolchain_args['CMAKE_FIND_ROOT_PATH'] = self.args.cross_compile_deps_path
104+ + toolchain_args['CMAKE_SHARED_LINKER_FLAGS'] = '\"\"'
37105
38106 # We only set the actual sysroot if we are actually cross
39107 # compiling. This is important since otherwise cmake seems to change the
108+ # RUNPATH to be a relative rather than an absolute path, breaking
109+ # certain cmark tests (and maybe others).
110+ - maybe_sysroot = self.get_linux_sysroot(platform, arch)
111+ - if maybe_sysroot is not None:
112+ - toolchain_args['CMAKE_SYSROOT'] = maybe_sysroot
113+ -
114+ - target = self.get_linux_target(platform, arch)
115+ + if platform == "linux":
116+ + maybe_sysroot = self.get_linux_sysroot(platform, arch)
117+ + if maybe_sysroot is not None:
118+ + toolchain_args['CMAKE_SYSROOT'] = maybe_sysroot
119+ +
120+ + target = self.get_linux_target(platform, arch)
121+ + elif platform == "android":
122+ + target = '%s-unknown-linux-android%s' % (self.args.android_arch,
123+ + self.args.android_api_level)
124+ if self.toolchain.cc.endswith('clang'):
125+ toolchain_args['CMAKE_C_COMPILER_TARGET'] = target
126+ if self.toolchain.cxx.endswith('clang++'):
127+ @@ -466,9 +479,19 @@ class Product(object):
128+ platform, arch,
129+ macos_deployment_version=override_macos_deployment_version)
130+ self.cmake_options.define('CMAKE_TOOLCHAIN_FILE:PATH', toolchain_file)
131+ - elif platform == "linux":
132+ - toolchain_file = self.generate_linux_toolchain_file(platform, arch)
133+ + elif platform == "linux" or platform == "android":
134+ + # Always cross-compile for linux, but not on Android, as a native
135+ + # compile on Android does not use the NDK and the CMake config.
136+ + cross_compile = platform == "linux" or self.is_cross_compile_target(host_target)
137+ + toolchain_file = self.generate_linux_toolchain_file(platform, arch, cross_compile)
138+ self.cmake_options.define('CMAKE_TOOLCHAIN_FILE:PATH', toolchain_file)
139+ + if cross_compile and platform == "android":
140+ + resource_dir = None
141+ + if not self.is_before_build_script_impl_product() and not self.is_build_script_impl_product():
142+ + install_path = self.host_install_destdir(host_target) + self.args.install_prefix
143+ + resource_dir = '%s/lib/swift' % install_path
144+ + flags = targets.StdlibDeploymentTarget.get_target_for_name(host_target).platform.swift_flags(self.args, resource_dir)
145+ + self.cmake_options.define('CMAKE_Swift_FLAGS', flags)
146+
147+ return toolchain_file
148+
40149diff --git a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
41150index b6bfa5760ef..324d1a77eea 100644
42151--- a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
@@ -50,6 +159,18 @@ index b6bfa5760ef..324d1a77eea 100644
50159
51160 def _cmake_product(self, host_target):
52161 build_root = os.path.dirname(self.build_dir)
162+ @@ -127,3 +127,11 @@ class SwiftTestingCMakeShim(cmake_product.CMakeProduct):
163+ install_prefix = install_destdir + self.args.install_prefix
164+
165+ self.install_with_cmake(['install'], install_prefix)
166+ +
167+ + @classmethod
168+ + def is_build_script_impl_product(cls):
169+ + return False
170+ +
171+ + @classmethod
172+ + def is_before_build_script_impl_product(cls):
173+ + return False
53174diff --git a/swift-corelibs-foundation/Sources/CoreFoundation/CFPlatform.c b/swift-corelibs-foundation/Sources/CoreFoundation/CFPlatform.c
54175index 90f4aa78..0429425b 100644
55176--- a/swift-corelibs-foundation/Sources/CoreFoundation/CFPlatform.c
0 commit comments