Android CrossCompilation on macOS: Is Swift Float80 support really needed for Android Intel x86 and x86_64 targets?

Hello,

I am getting compile error addressed Swift Float80 when building Swift on macOS cross-compile host targeted Android Intel x86 and x86_64 targets: #error "Are you certain 'long double' on this platform is really Intel 80-bit extended precision?". See details below:

cd /swift-everywhere-toolchain/ToolChain/Build/darwin/swift && ninja -j3 swiftGlibc-android-i686 swiftCore-android-i686 swiftSwiftOnoneSupport-android-i686
[33/75] Building CXX object stdlib/public/runtime/CMakeFiles/swiftRuntime-android-i686.dir/SwiftDtoa.cpp.o
FAILED: stdlib/public/runtime/CMakeFiles/swiftRuntime-android-i686.dir/SwiftDtoa.cpp.o
/swift-everywhere-toolchain/ToolChain/Build/darwin/llvm/./bin/clang++  \
-DCMARK_STATIC_DEFINE -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS \
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Istdlib/public/runtime \
-I/swift-everywhere-toolchain/ToolChain/Sources/swift/stdlib/public/runtime \
-Iinclude -I/swift-everywhere-toolchain/ToolChain/Sources/swift/include \
-I/swift-everywhere-toolchain/ToolChain/Sources/llvm/include \
-I/swift-everywhere-toolchain/ToolChain/Build/darwin/llvm/include \
-I/swift-everywhere-toolchain/ToolChain/Sources/llvm/tools/clang/include \
-I/swift-everywhere-toolchain/ToolChain/Build/darwin/llvm/tools/clang/include \
-I/swift-everywhere-toolchain/ToolChain/Sources/cmark/src \
-I/swift-everywhere-toolchain/ToolChain/Build/darwin/cmark/src \
-Wno-unknown-warning-option -Werror=unguarded-availability-new -fno-stack-protector \
-fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -Wall -Wextra -Wno-unused-parameter \
-Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-class-memaccess \
-Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -Werror=switch -Wdocumentation \
-Wimplicit-fallthrough -Wunreachable-code -Woverloaded-virtual -DOBJC_OLD_DISPATCH_PROTOTYPES=0 \
-fno-sanitize=all -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1 -O3  \
-isysroot /Volumes/Data/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk   \
-UNDEBUG  -fno-exceptions -fno-rtti -Wall -Wglobal-constructors -Wexit-time-destructors -fvisibility=hidden -DswiftCore_EXPORTS \
-I/swift-everywhere-toolchain/ToolChain/Sources/swift/include -DSWIFT_TARGET_LIBRARY_NAME=swiftRuntime \
-target i686-unknown-linux-android \
--sysroot=/Users/vova/Library/Android/sdk/ndk-bundle/platforms/android-24/arch-x86 \
-B /Users/vova/Library/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/darwin-x86_64/i686-linux-android/bin \
-O2 -momit-leaf-frame-pointer -g0 -DNDEBUG -I/ndk-bundle/sources/cxx-stl/llvm-libc++/include \
/ndk-bundle/sysroot/usr/include/i686-linux-android -D__ANDROID_API__=24 \
-isystem /swift-everywhere-toolchain/ToolChain/Sources/icu/icu4c/source/common \
-isystem /swift-everywhere-toolchain/ToolChain/Sources/icu/icu4c/source/i18n \
-MD -MT stdlib/public/runtime/CMakeFiles/swiftRuntime-android-i686.dir/SwiftDtoa.cpp.o \
-MF stdlib/public/runtime/CMakeFiles/swiftRuntime-android-i686.dir/SwiftDtoa.cpp.o.d \
-o stdlib/public/runtime/CMakeFiles/swiftRuntime-android-i686.dir/SwiftDtoa.cpp.o \
-c /swift-everywhere-toolchain/ToolChain/Sources/swift/stdlib/public/runtime/SwiftDtoa.cpp
/swift-everywhere-toolchain/ToolChain/Sources/swift/stdlib/public/runtime/SwiftDtoa.cpp:148:2: error: "Are you certain `long double` on this platform is really Intel 80-bit extended precision?"
#error "Are you certain `long double` on this platform is really Intel 80-bit extended precision?"
 ^
1 error generated.

This error can be eliminated by disabling Float80 support:

diff --git a/include/swift/Runtime/SwiftDtoa.h b/include/swift/Runtime/SwiftDtoa.h
index c309d2e97985ef70d6c714ca802e00831f113fe9..07670af400c2b6a137b18b73b34406dd41002a8e 100644
--- a/include/swift/Runtime/SwiftDtoa.h
+++ b/include/swift/Runtime/SwiftDtoa.h
@@ -37,6 +37,10 @@
  #endif
 #endif
 
+#if defined(__ANDROID__) && (defined(__i386) || defined(__x86_64__))
+ #undef SWIFT_DTOA_FLOAT80_SUPPORT
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif

Plus similar changes in various places inside stdlib:

diff --git a/stdlib/public/core/FloatingPoint.swift b/stdlib/public/core/FloatingPoint.swift
index a5ecdf598395e5d0b4515dc5455fdd9f4fbc4b44..03a3e9d364ff22958af623bfec7a91bb1ff7dcac 100644
--- a/stdlib/public/core/FloatingPoint.swift
+++ b/stdlib/public/core/FloatingPoint.swift
@@ -1491,7 +1491,7 @@ public protocol BinaryFloatingPoint: FloatingPoint, ExpressibleByFloatLiteral {
   /// - Parameter value: A floating-point value to be converted.
   init(_ value: Double)
 
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
   /// Creates a new instance from the given value, rounded to the closest
   /// possible representation.
   ///

Is it a good idea to disable Float80 support for Android Intel x86 and x86_64 targets (i.e. Android Simulators) to avoid build errors?

I want to clarify this before making Pull Request.
Thanks!

@scanon would be best able to respond to this, but I suspect the answer is both "it's okay to not support Float80 on x86 Android" and "x86 Android should support Float80 just fine, so you can add it to the list of platforms where that's an established thing".

I'm having a hard time finding a definitive answer, but it appears to me that long double on Android is just an alias of double, even on x86. In which case your suggested changes are correct, but Float80 should be removed more widely throughout the stdlib when building for Android.

Note that the NDK's C ABI definition of long double does not, in itself, mean that Swift cannot provide the type, but the problem is that systems that do not support long double don't need to take care not to trash x87 state in the runtime, so we can't necessarily depend on things working correctly if we do expose it, and we certainly can't import the C long double type as Float80.

1 Like

Thank you!
I created PR with fix: https://github.com/apple/swift/pull/25502

2 Likes