With NDK 10 releases, I used to use ndk-build
to compile standalone binaries for many different ABIs and multiple API levels. These binaries were to be included in an app. However, I installed the NDK on a new development machine as described in this article. This resulted in a folder ndk-bundle
within my Android SDK directory. I used to compile the code from a command line and then copy the binaries to the resources of my Android Studio project, but I could not figure out how to do this with NDK 13 so I tried to follow the tutorial to include my native code in the Android Studio project. However, almost all recent instructions assume that one wants to build a library, not a standalone binary, so I did not get far.
I would switch to CMake if I figured out how to get it to work. My native project has the following (simplified) structure:
native
Android.mk
LOCAL_PATH := $(call my-dir)/my_tool/src
include $(CLEAR_VARS)
LOCAL_MODULE := my_tool
LOCAL_SRC_FILES := main.c
include $(BUILD_EXECUTABLE)
Application.mk
APP_ABI := all
APP_PLATFORM := android-21
my_tool
How can I compile this using either Android Studio or the NDK from the command line on our Windows 10 development machines?
Edit:
I am using this in build.gradle:
externalNativeBuild {
ndkBuild {
path "../native/Android.mk"
}
}
Gradle creates a directory .externalNativeBuild
which contains build configurations, but I cannot find out how to actually build the native code. No binaries are created when I run gradle.
I cannot find any information about gradle configuration for ndk-build
.
I tried to follow your simplified structure as closely as possible.
Here is the file app/build.gradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 24
buildToolsVersion "25.0.1"
defaultConfig {
minSdkVersion 21
targetSdkVersion 24
externalNativeBuild {
ndkBuild {
targets "my_tool"
abiFilters "armeabi-v7a"
}
}
}
externalNativeBuild {
ndkBuild {
path "../native/Android.mk"
}
}
}
The file native/Android.mk is identical to yours:
LOCAL_PATH := $(call my-dir)/my_tool/src
include $(CLEAR_VARS)
LOCAL_MODULE := my_tool
LOCAL_SRC_FILES := main.c
include $(BUILD_EXECUTABLE)
I also have the files native/main.c and a minimal app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="my.tool" />
I did not touch the root build.gradle script generated by Android Studio wizard:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0-alpha3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Now I can build the project and here is what I get:
$> file ./app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/my_tool
ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Android Studio shows my main.c in the cpp folder in default view:
Update: to have the executable stripped and packaged in the APK, native/Android.mk must be changed:
LOCAL_PATH := $(call my-dir)/my_tool/src
install: LIB_PATH := $(call my-dir)/libs
include $(CLEAR_VARS)
LOCAL_MODULE := my_tool
LOCAL_SRC_FILES := main.c
include $(BUILD_EXECUTABLE)
install: $(LOCAL_INSTALLED)
-mkdir $(LIB_PATH)
-rm -r $(LIB_PATH)
mv $< $(<:my_tool=lib-my_tool-.so)
mv $(realpath $(dir $<)..) $(LIB_PATH)
.PHONY: install
Also, app/build.gradle needs some tweaking:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.1"
defaultConfig {
minSdkVersion 21
targetSdkVersion 24
externalNativeBuild {
ndkBuild {
targets "my_tool"
abiFilters "armeabi-v7a"
arguments 'V=1', 'install'
}
}
}
externalNativeBuild {
ndkBuild {
path "../native/Android.mk"
}
}
sourceSets {
main {
jniLibs.srcDirs = ['../native/libs']
}
}
}
This relies on the old hack which depends on undocumented behavior of NDK, and may break without notice on a future NDK upgrade.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With