38
38
"x86" : "i686-linux-android" ,
39
39
}
40
40
41
+ CLANG_RT_ARCH_TARGETS = {
42
+ "armv7" : "arm-android" ,
43
+ "armv8" : "aarch64-android" ,
44
+ "x86_64" : "x86_64-android" ,
45
+ "x86" : "i686-android" ,
46
+ }
47
+
41
48
42
49
def profile_to_rust_target (platform : str , arch : str , sdk : Optional [str ]) -> str :
43
50
if platform == "Android" :
@@ -74,7 +81,7 @@ def get_android_bin_path() -> Path:
74
81
tankerci .run (
75
82
"conan" ,
76
83
"install" ,
77
- "android-ndk/r22b @" ,
84
+ "android-ndk/r25c @" ,
78
85
"--profile:host" ,
79
86
"linux-x86_64" ,
80
87
"--profile:build" ,
@@ -83,7 +90,7 @@ def get_android_bin_path() -> Path:
83
90
_ , out = tankerci .run_captured (
84
91
"conan" ,
85
92
"info" ,
86
- "android-ndk/r22b @" ,
93
+ "android-ndk/r25c @" ,
87
94
"--profile" ,
88
95
"linux-x86_64" ,
89
96
"--profile:build" ,
@@ -179,6 +186,65 @@ def _copy_includes(self, package_path: Path, depsConfig: DepsConfig) -> None:
179
186
ui .info_2 (header , "->" , header_dest_dir )
180
187
shutil .copy (header , header_dest_dir )
181
188
189
+ # Import only soft float128 builtins from compiler-rt
190
+ # This is necessary on 64bit android archs, as Clang doesn't build them by default,
191
+ # and Google's NDK distribution doesn't take care of that either...
192
+ @staticmethod
193
+ def _armerge_soft_float128_compiler_rt_builtins (compiler_rt_lib : Path , output_path : Path , env : dict [str , str ]):
194
+ f128_builtins = [
195
+ "__addtf3" ,
196
+ "__subtf3" ,
197
+ "__multf3" ,
198
+ "__divtf3" ,
199
+ "__negtf2" ,
200
+ "__extenddftf2" ,
201
+ "__extendsftf2" ,
202
+ "__trunctfdf2" ,
203
+ "__trunctfsf2" ,
204
+ "__fixdfti" ,
205
+ "__fixsfti" ,
206
+ "__fixunsdfti" ,
207
+ "__fixunssfti" ,
208
+ "__fixtfdi" ,
209
+ "__fixtfsi" ,
210
+ "__fixtfti" ,
211
+ "__fixunstfdi" ,
212
+ "__fixunstfsi" ,
213
+ "__fixunstfti" ,
214
+ "__floattidf" ,
215
+ "__floattisf" ,
216
+ "__floatuntidf" ,
217
+ "__floatuntisf" ,
218
+ "__floatditf" ,
219
+ "__floatsitf" ,
220
+ "__floattitf" ,
221
+ "__floatunditf" ,
222
+ "__floatunsitf" ,
223
+ "__floatuntitf" ,
224
+ "__cmptf2" ,
225
+ "__unordtf2" ,
226
+ "__eqtf2" ,
227
+ "__getf2" ,
228
+ "__gttf2" ,
229
+ "__letf2" ,
230
+ "__lttf2" ,
231
+ "__netf2" ,
232
+ "__powitf2" ,
233
+ "__multc3" ,
234
+ "__divtc3" ,
235
+ ]
236
+ keep_symbol_args = [e for sym_name in f128_builtins for e in ['-k' , sym_name ]]
237
+
238
+ tankerci .run (
239
+ "armerge" ,
240
+ * keep_symbol_args ,
241
+ "--output" ,
242
+ str (output_path .relative_to (Path .cwd ())),
243
+ str (compiler_rt_lib ),
244
+ shell = False ,
245
+ env = env ,
246
+ )
247
+
182
248
def _merge_all_libs (
183
249
self , depsConfig : DepsConfig , package_path : Path , native_path : Path
184
250
) -> None :
@@ -202,15 +268,31 @@ def _merge_all_libs(
202
268
if self ._is_android_target :
203
269
ndk_arch = NDK_ARCH_TARGETS [self .arch ]
204
270
android_lib_path = android_bin_path / f"../sysroot/usr/lib/{ ndk_arch } "
271
+
272
+ # Starting with NDK r23, Google in its infinite wisdom has decided to make things more interesting
273
+ # libgcc is gone, and now we use clang's libcxx and compiler-rt.
274
+ # Unfortunately, the libcxx_static.a is currently missing soft float128 builtins for 64bit archs
275
+ # (See https://reviews.llvm.org/D53608 and https://github.com/llvm/llvm-project/issues/51395)
276
+ # It is possible to find those symbols in the separate libclang_rt.builtins libs
277
+ # However, we can't pull in all of rt.builtins, or we will have duplicate symbols and fail linking
278
+ if self .arch in ['x86_64' , 'armv8' ]:
279
+ compiler_rt_arch = CLANG_RT_ARCH_TARGETS [self .arch ]
280
+ compiler_rt_dir = android_bin_path / f"../lib64/clang/14.0.7/lib/linux/"
281
+ compiler_rt_lib = compiler_rt_dir / f"libclang_rt.builtins-{ compiler_rt_arch } .a"
282
+ out_path = cxx_package_libs / f"libclang_rt.builtins.float128-{ compiler_rt_arch } .a"
283
+ self ._armerge_soft_float128_compiler_rt_builtins (compiler_rt_lib , out_path , env )
284
+
205
285
for lib in android_lib_path .glob ("*.a" ):
206
286
# Rust already links some (non-C++) NDK libs, skip to avoid duplicate symbols
287
+ # Also we already link rt builtins above, so we don't need/can't have these
207
288
skipped = [
208
289
"libc.a" ,
209
290
"libm.a" ,
210
291
"libdl.a" ,
211
292
"libz.a" ,
212
293
"libstdc++.a" ,
213
294
"libunwind.a" ,
295
+ "libcompiler_rt-extras.a" ,
214
296
]
215
297
if lib .is_dir () or lib .name in skipped :
216
298
continue
0 commit comments