Skip to content
Elias Ku edited this page Jun 6, 2018 · 9 revisions

Here's some rough info for compiling for Android:

To run on Android, what you have to do is compile HL runtime, supporting libraries, and your project's code compiled to C (since there's no HL/JIT for ARMs as of moment of writing) as a native library using NDK. Instead of a standard main entry-point, you need to provide a special exported function conforming to JNI standards, and then call main routines from it.


CMakeLists.txt in the hashlink repo is useful: you can basiscally copy-paste configurations into CMakeLists.txt of your android project and get libhl and friends built.


minSdkVersion should be at least 17, otherwise you'll get posix_memalign undefined reference error


The JNI_OnLoad function located in sys_android.c (called on library load) imposes some requirements:

  • The activity class name should be whatever is defined with HL_ANDROID_ACTIVITY (by default: org/haxe/HashLinkActivity)
  • The activity class must have a public static Context getContext() method that returns the application context.

Here's what worked for me for a simple HL/C hello world:

package com.example.native_activity;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

public class MainActivity extends Activity {
    private static MainActivity instance;

    @Override
    protected void onCreate(Bundle state) {
        super.onCreate(state);
        instance = this;

        System.loadLibrary("hl"); // hl run-time (if build separately), other libs loaded similarly
        System.loadLibrary("native-activity"); // application code (linked against the libs above)

        startHL();
    }

    public static Context getContext() {
        return instance.getApplicationContext();
    }

    public native void startHL(); // see comment below
}

the startHL function is just something like this:

#include <jni.h>

extern int main(int argc, char *argv[]); // assuming that haxe->hl/c entry point is included (which includes hlc_main.c which includes the main function)

JNIEXPORT jstring JNICALL Java_com_example_native_1activity_MainActivity_startHL(JNIEnv* env, jobject thiz) {
	main(0, NULL);
}

TurboJPEG (part of fmt) required setting SIZEOF_SIZE_T define to compile:

include(CheckTypeSize)
check_type_size(size_t SIZEOF_SIZE_T)

target_compile_definitions(fmt
    PRIVATE
    SIZEOF_SIZE_T=${SIZEOF_SIZE_T}
)

Also, the bundled libpng lacks ARM NEON optimization source file, so another define is required: PNG_ARM_NEON_OPT=0


Some work has been started on calling Java from HashLink (through JNI): https://github.com/nadako/hljni


Some comments from @rtissera on the topic: https://github.com/HaxeFoundation/hashlink/issues/109#issuecomment-363055631

Clone this wiki locally