Hi,
I am building "https://github.com/apple/swift-log" for Android using NDK 21.3.6528147 and getting errors below when targeting Android API 21:
error: module 'Glibc' has no member named 'stderr'
_ = Glibc.stderr!
^~~~~ ~~~~~~
error: module 'Glibc' has no member named 'stdout'
_ = Glibc.stdout!
^~~~~ ~~~~~~
The problem seems that stdin, stdout and stderr defined in NDK using #define.
// File: sysroot/usr/include/stdio.h
/* Before API 23 the actual symbols for stdin and friends had different names. */
extern FILE __sF[] __REMOVED_IN(23);
#define stdin (&__sF[0])
#define stdout (&__sF[1])
#define stderr (&__sF[2])
As I understand clang not including into module types defined with #define. Thus stdin, stdout and stderr not visible by Swift.
Is the any workaround or solution for such cases (when some type defined with #define on C side)?
Thank you in advance!
To reproduce you can:
-
Download Swift Android Toolchain: https://github.com/vgorloff/swift-everywhere-toolchain/releases/tag/1.0.65
-
Create file with following contents:
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
import Darwin
#elseif os(Windows)
import MSVCRT
#else
import Glibc
#endif
func test() {
tolower(5) // sysroot/usr/include/ctype.h
fesetround(6) // sysroot/usr/include/fenv.h
localeconv() // sysroot/usr/include/locale.h
#if os(Android)
isnan(7) // sysroot/usr/include/math.h
#endif
#if os(Android)
_ = Glibc.stderr!
_ = Glibc.stdout!
#endif
//> sysroot/usr/include/stdio.h
_ = FOPEN_MAX
_ = off_t()
clearerr(nil)
fclose(nil)
//<
}
- Compile it for Android API 23 (Should be no error):
/.../swift-android-toolchain/usr/bin/swiftc-arm-linux-androideabi ./FILE.swift -v -Xcc -D__ANDROID_API__=23
- Compile it for Android API 21 (Should be an error):
/.../swift-android-toolchain/usr/bin/swiftc-arm-linux-androideabi ./FILE.swift -v -Xcc -D__ANDROID_API__=21