diff --git a/doc/nimc.rst b/doc/nimc.rst index a7cee7f592..2bec61fd9f 100644 --- a/doc/nimc.rst +++ b/doc/nimc.rst @@ -281,6 +281,20 @@ The MinGW-w64 toolchain can be installed as follows:: CentOS: yum install mingw32-gcc | mingw64-gcc - requires EPEL OSX: brew install mingw-w64 +Cross compilation for Android +============================= + +There are two ways to compile for Android: terminal programs (Termux) and with the NDK (Android Native Development Kit). + +First one is to treat Android as a simple linux and use `Termux `_ to connect and run the nim compiler directly on android as if it was linux. These programs are console only apps +that can’t be distributed in the Play Store. + +Use regular ``nim c`` inside termux to make Android terminal apps. + +Android apps are written in Java, to use Nim inside an Android app you need a small Java stub that calls out to a native library written in Nim using the `NDK `_. You can also use `native-acitivty `_ to have the Java stub be auto generated for you. + +Use ``nim c -c --cpu:arm --os:android -d:androidNDK`` to generate the C source files you need to include in your Android Studio project. Add the generated C files to CMake build script. Then do the final compile with Android Studio which uses gradle to call CMake to compile the project. + Cross compilation for Nintendo Switch ===================================== diff --git a/lib/system/io.nim b/lib/system/io.nim index 977e8539a5..a6eeee7c74 100644 --- a/lib/system/io.nim +++ b/lib/system/io.nim @@ -112,6 +112,13 @@ proc c_setvbuf(f: File, buf: pointer, mode: cint, size: csize): cint {. proc c_fprintf(f: File, frmt: cstring): cint {. importc: "fprintf", header: "", varargs, discardable.} +## When running nim in android app stdout goes no where, so echo gets ignored +## To redreict echo to the android logcat use -d:androidNDK +when defined(androidNDK): + const ANDROID_LOG_VERBOSE = 2.cint + proc android_log_print(prio: cint, tag: cstring, fmt: cstring): cint + {.importc: "__android_log_print", header: "", varargs, discardable.} + template sysFatal(exc, msg) = raise newException(exc, msg) @@ -585,25 +592,31 @@ when declared(stdout): initSysLock echoLock proc echoBinSafe(args: openArray[string]) {.compilerproc.} = - # flockfile deadlocks some versions of Android 5.x.x - when not defined(windows) and not defined(android) and not defined(nintendoswitch): - proc flockfile(f: File) {.importc, nodecl.} - proc funlockfile(f: File) {.importc, nodecl.} - flockfile(stdout) - when defined(windows) and compileOption("threads"): - acquireSys echoLock - for s in args: - when defined(windows): - writeWindows(stdout, s) - else: - discard c_fwrite(s.cstring, s.len, 1, stdout) - const linefeed = "\n" - discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout) - discard c_fflush(stdout) - when not defined(windows) and not defined(android) and not defined(nintendoswitch): - funlockfile(stdout) - when defined(windows) and compileOption("threads"): - releaseSys echoLock + when defined(androidNDK): + var s = "" + for arg in args: + s.add arg + android_log_print(ANDROID_LOG_VERBOSE, "nim", s) + else: + # flockfile deadlocks some versions of Android 5.x.x + when not defined(windows) and not defined(android) and not defined(nintendoswitch): + proc flockfile(f: File) {.importc, nodecl.} + proc funlockfile(f: File) {.importc, nodecl.} + flockfile(stdout) + when defined(windows) and compileOption("threads"): + acquireSys echoLock + for s in args: + when defined(windows): + writeWindows(stdout, s) + else: + discard c_fwrite(s.cstring, s.len, 1, stdout) + const linefeed = "\n" + discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout) + discard c_fflush(stdout) + when not defined(windows) and not defined(android) and not defined(nintendoswitch): + funlockfile(stdout) + when defined(windows) and compileOption("threads"): + releaseSys echoLock when defined(windows) and not defined(nimscript):