Upgrade to Pro — share decks privately, control downloads, hide ads and more …

building android apps with haskell

building android apps with haskell

a basic overview on how to build android apps with haskell

Avatar for Moritz Angermann

Moritz Angermann

January 11, 2018
Tweet

More Decks by Moritz Angermann

Other Decks in Programming

Transcript

  1. Who • Moritz Angermann / zw3rk • mobile and dekstop

    apps blog: https:/ /medium.com/@zw3rk twitter: @angerman_io, @zw3rktech, @mobilehaskell Moritz Angermann, Haskell.sg November Meetup, Singapore
  2. Prerequisites • LLVM 5 - http:/ /releases.llvm.org/download.html#5.0.1 • Android Cross

    Compiler - http:/ /hackage.mobilehaskell.org • Toolchain Wrapper - https:/ /github.com/zw3rk/toolchain-wrapper • Android Studio - https:/ /developer.android.com/studio/index.html • (A recent cabal - https:/ /github.com/haskell/cabal/) Moritz Angermann, Haskell.sg November Meetup, Singapore
  3. Installing LLVM & GHC Cross Compiler $ curl -L -O

    http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-x86_64-apple-darwin.tar.xz $ tar xjf clang+llvm-5.0.0-x86_64-apple-darwin.tar.xz $ export PATH=$PWD/clang+llvm-5.0.0-x86_64-apple-darwin/bin:$PATH $ curl -L -O http://hackage.mobilehaskell.org/.../ghc-8.4.0.20180109-x86_64-linux-android.tar.xz $ curl -L -O http://hackage.mobilehaskell.org/.../ghc-8.4.0.20180109-armv7-linux-androideabi.tar.xz $ curl -L -O http://hackage.mobilehaskell.org/.../ghc-8.4.0.20180109-aarch64-linux-android.tar.xz $ mkdir ghc-{x86_64,armv7,aarch64} $ tar xjf ghc-8.4.0.20180109-x86_64-linux-android.tar.xz -C ghc-x86_64 $ tar xjf ghc-8.4.0.20180109-armv7-linux-androideabi.tar.xz -C ghc-armv7 $ tar xjf ghc-8.4.0.20180109-aarch64-linux-android.tar.xz -C ghc-aarch64 $ export PATH=$PWD/ghc-x86_64/bin:$PWD/ghc-armv7/bin:$PWD/ghc-aarch64/bin:$PATH Moritz Angermann, Haskell.sg November Meetup, Singapore
  4. Installing the Toolchain Wrapper # Clone it, bootstrap it and

    add it to PATH $ git clone https://github.com/zw3rk/toolchain-wrapper $ (cd toolchain-wrapper && ./bootstrap) $ export PATH=$PWD/toolchain-wrapper:$PATH Modify the toolchain config: - toolchain-wrapper/android-toolchain.config (macOS) - toolchain-wrapper/linux-android-toolchain.config (linux) to match your installed Android NDK. Moritz Angermann, Haskell.sg November Meetup, Singapore
  5. The Application • Create the application in Android Studio •

    Create a small Haskell library • Link the Haskell library with the application • Run some trivial Haskell code Moritz Angermann, Haskell.sg November Meetup, Singapore
  6. The Glorious Haskell library {-# LANGUAGE ForeignFunctionInterface #-} module MeetupDemo

    where import Foreign.C foreign export ccall "hs_hello" hello :: IO CString hello :: IO CString hello = newCString "Hello from Haskell" Moritz Angermann, Haskell.sg November Meetup, Singapore
  7. Building the Static library $ x86_64-linux-android-ghc -fllvmng -staticlib -fPIC \

    -o hs-libs/x86_64/libHSmeetupdemo.a \ -odir build/hs/x86_64 -hidir build/hs/x86_64 src/main/hs/Lib.hs [1 of 1] Compiling MeetupDemo ( src/main/hs/Lib.hs, src/main/hs/Lib.o ) Linking hs-libs/x86_64/libHSmeetupdemo.a ... Moritz Angermann, Haskell.sg November Meetup, Singapore
  8. Adjust the app/build.gradle: add abiFilters defaultConfig { applicationId "com.zw3rk.meetupdemo" minSdkVersion

    21 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags "" } } ndk { abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a' } } Moritz Angermann, Haskell.sg November Meetup, Singapore
  9. Adjust the CMakeLists.txt cmake_minimum_required(VERSION 3.4.1) add_library( native-lib SHARED src/main/cpp/native-lib.cpp )

    find_library( log-lib log ) find_library( c-lib c ) find_library( z-lib z ) find_library( hs-lib HSmeetupdemo PATHS ${PROJECT_SOURCE_DIR}/hs-libs/${ANDROID_ABI} NO_CMAKE_FIND_ROOT_PATH ) target_link_libraries( native-lib ${log-lib} ${hs-lib} ${c-lib} ${z-lib} ) Moritz Angermann, Haskell.sg November Meetup, Singapore
  10. Adapting the JNI glue (1) #include <jni.h> #include <string> extern

    "C" JNIEXPORT jstring JNICALL Java_com_zw3rk_meetupdemo_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } Moritz Angermann, Haskell.sg November Meetup, Singapore
  11. Adapting the JNI glue (2) extern "C" { extern void

    hs_init(int * argc, char ** argv[]); extern void hs_hello(); } extern "C" JNIEXPORT void JNICALL Java_com_zw3rk_meetupdemo_MainActivity_hsInit(JNIEnv *env, jobject /* this */) { hs_init(NULL,NULL); } Moritz Angermann, Haskell.sg November Meetup, Singapore
  12. Adapting the JNI glue (3) extern "C" JNIEXPORT jstring JNICALL

    Java_com_zw3rk_meetupdemo_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { return env->NewStringUTF(hs_hello()); } Moritz Angermann, Haskell.sg November Meetup, Singapore
  13. Adapting the Main Activity class MainActivity : AppCompatActivity() { override

    fun onCreate(savedInstanceState: Bundle?) { hsInit() super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) sample_text.text = stringFromJNI() } external fun stringFromJNI(): String external fun hsInit() companion object { init { System.loadLibrary("native-lib") } } } Moritz Angermann, Haskell.sg November Meetup, Singapore
  14. Notes • Building for iOS is very similar. Just drag

    the archive into Xcode and link; glue code easier in Obj-C. • Building with cabal It is possible, requires a very recent cabal from git and some manual intervention (haskell/cabal#4939; haskell/cabal#4972) • Make sure you keep your package databases separate! This could and should be handled better by cabal and ghc. • User Guide and Tutorials are coming mobile-haskell-user-guilde.rtfd.io Moritz Angermann, Haskell.sg November Meetup, Singapore
  15. Code Source code can be found at - github.com/angerman/2018-01-MeetupDemo Run

    the Makefile in the app folder then building with Android Studio. Moritz Angermann, Haskell.sg November Meetup, Singapore