After a bit of fiddling, I managed to get a native binary executable file, 
cross-compiled from Nim source code, which runs on my Android phone running 
Android 8.0 (Oreo).

Figured someone would find it useful to see how I did it, although there's 
probably a cleaner way to do it than what I ended up doing. This was rather 
just thrown together in a way that I found worked, so bear that in mind. x')

Hopefully this can also help the Nim developers make cross-compiling a Nim 
program for Android easier to do. 

I'll also note that I did this from a Windows x64 machine.

Disclaimer: You follow these instructions at your own risk, etc... Not my fault 
if you brick your device fiddling with it.

  * Download the [Android 
NDK](https://developer.android.com/ndk/downloads/index.html) onto your machine. 
Open a terminal, change into its build/tools subdirectory and run:


    
    
    make_standalone_toolchain.py --arch=arm64 
--install-dir=../../../android-toolchain --api 27
    

This will have created the android-toolchain directory in the same location 
where you put the NDK.

Note that the number given for api is the [minimum Android API level that your 
app will 
target](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels).

  * Compile your Nim code into C source files. A simple 'Hello World' program 
in my case:


    
    
    nim c --os:android --cpu=arm64 --compileOnly hello.nim
    

  * Create the executable using the NDK's clang command. In a terminal, change 
into the android-toolchain/bin directory and run:


    
    
    clang -I../sysroot/usr/include -I/path/to/nim/installation/lib -fPIE -pie 
-o /path/to/output/hello.bin path/to/nimcache/hello.c 
/path/to/nimcache/stdlib_system.c
    

This generated 19 warnings for me, but it still ran just fine in the end. Note 
that I've specified all the C files manually here, but you could do *.c if you 
ensure that you clean the nimcache every time.

I am compiling manually via C here because Nim calls out to clang.exe or 
gcc.exe and cannot be told to call the clang.cmd as we need to here, so far as 
I could tell.

I tried using a config file like 'hello.nim.cfg' to config this but I was not 
able to get that to work.

At any rate, you should now have an executable binary file that runs on Android 
ARM64.

Unfortunately, I can only tell you how to run it on real hardware. You can do 
that like this:

  * Enable 'USB Debugging' on your phone, and install your phone's USB drivers 
which came with your phone.
  * Upload the binary to your phone.


    
    
    adb push hello.bin /data/local/tmp/hello.bin
    

  * Set the executable bit on your executable, and run it.


    
    
    adb shell
    $ chmod +x /data/local/tmp/hello.bin
    $ /data/local/tmp/hello.bin
    Hello World!
    $
    

If your program segfaults but you know that it's not your Nim code's fault, try 
removing the '-fPIE -pie' from the clang complication step; particularly if you 
have a very old version of Android. Position independant code was not 
originally supported, IIRC.

Hopefully there will be an easier, cleaner, way to do this in the future! xD

Reply via email to