Android Studioでndk-buildする

という訳で、久々にNDKをさわり始めたので、念のためメモ。

こちらが参考になりました。

Android StudioでNDKのビルド – 車輪の再発見みたいな?

で、本題なんだけど、
以前、これを書いたので、
今回も同じようにやりたいと思って調べてました。
つまり、NDKのビルドは”Android.mk”を使いたいのです。

やったことはこんな感じ。

1. build.gradle(Modulde: app)を書き換える

(省略)

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.1"

    defaultConfig {
        (省略)
    }
    buildTypes {
        (省略)
    }

    sourceSets {
        main {
            jni.srcDirs = []
            jniLibs.srcDir "src/main/libs"
        }
    }
}

(省略)

書き加えたのは、sourceSets { ... }のところです。

jni.srcDirs = [] は、
Android Studioにネイティブのコードを無視して貰う、
jniLibs.srcDir "src/main/libs" は、
ndk-buildで生成されたライブラリを、
プロジェクトに追加するという意味です。(*1)

2. Cでコードを書く

まずは、”AndroidManifest.xml”と同じ階層に”jni”フォルダを作って、
その中にコードを書きます。

Cのコードを”sample.c”に書く場合はこんな感じ。
jni
├── Android.mk
├── Application.mk
└── sample.c

3. “Android.mk”と”Application.mk”

__android_log_printを使う場合の例です。

“Android.mk”

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES := sample.c
LOCAL_MODULE    := sample
LOCAL_LDLIBS    := -llog
 
include $(BUILD_SHARED_LIBRARY)

“Application.mk”

APP_ABI := all

4. ビルドする

“AndroidManifest.xml”と同じ階層で、

$ ndk-build

すると、Android Studioで”app”の中に”jniLibs”フォルダが追加されて、
プラットフォームの数だけサブフォルダとライブラリができます。

注意点

2015/03/10 追記
コメントを貰って、もう一度試したらそんな事無かったです。(*2)
たぶん、__android_log_printでエラーが出ます。
すべてのプラットフォームで使える訳ではないらしく、

アーキテクチャを判別する方法を探していたところ、
NDKフォルダの中のサンプルコードが役に立ちました。

android-ndk-r10d/samples/hello-jni/jni/hello-jni.c

結果的に、Cのコードの先頭はこんな感じ。

#include <jni.h>
#include <android/log.h>

#define LOG_TAG "Sample"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

/* ここから関数を書く */

あと、jnigraphicsを使いたい場合は、
“Application.mk”に、

APP_PLATFORM := android-8

を追加する必要があります。
たぶん、minSdkVersionと同じ値を記述するのが良いです。

おしまい。

(*1) ちょっと、自信ない・・・。
(*2) コメント欄参照

3 Responses to “Android Studioでndk-buildする”

  1. ピンバックを頂いたので見に来てしまいました。
    で、__android_log_printなんですけど、どのアーキテクチャでも使えますよ。
    APP_ABI := all
    でビルドしても普通に使えます。
    最新のNDKだとarmeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips_64を指定するのと等価です。もっともmipsとmips_64は実際に走らせたことは無いですが。
    Android.mkかApplication.mkのどちらかで何かたりなんじゃないかと思います。

    ちなみに、NDKのドキュメントではx86-64と書いてありますが、実際はx86_64です。
    (86と64の間はハイフンではなくアンダーバーです)

    saki

  2. > sakiさん

    わざわざ、ありがとうございます!

    MacOS 10.9,5, ndk-r10dだと、
    undefined reference to __android_log_print
    って出たので、今回はこんな感じにしました。
    何か漏れてたのかも知れないですね。

    もう一度、試してみたら問題なかったです!
    (LOCAL_LDLIBSのtypoを直す前の話だったのかなぁ・・・。)

  3. […] こちらが、参考になる。 http://www.nekonotechno.com/nekopress/?p=5535 […]

Leave a Comment