I am defining some variables within the Android.mk
file (I am passing some flags for the compiler), but every time I build my project, the Android.mk
is overwritten. I am assuming that Gradle
is responsible and that I should be looking there? How do I use my own Android.mk file?
Background Info:
Ubuntu
64bit, Android Studio
1.0.1, JDK7.
I have wrapped my NDK
version with O-LLVM NDK, and as such am editing the Android.mk
file located at app/build/intermediates/ndk/debug
(it's the only Android.mk
file within my project dir), different to the location that the doc for O-LLVM
gives examples of.
Also, there is no Application.mk
file, so again I am assuming that Gradle
is responsible for the calls to the compiler?
Updated information
build.gradle - (app)
//The following code until the "----" line is the new build.gradle config file
// that disables automatic Android.mk file generation
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.md.helloworld"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk {
moduleName "MyLib"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jni
jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk file
}
// Call regular ndk-build (.cmd) script from the app directory
task ndkBuild(type: Exec) {
commandLine 'ndk-build', '-C', file('src/main/').absolutePath
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
/*
//The following code is the original Android.mk file
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.md.helloworld"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
//The only modified line
ndk {
moduleName "MyLib"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
*/
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := helloWorld
LOCAL_SRC_FILES := main.c
LOCAL_LDLIBS := -static
include $(BUILD_EXECUTABLE)
Application.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
APP_ABI := armeabi
NDK_TOOLCHAIN_VERSION := clang3.4-obfuscator
include $(BUILD_EXECUTABLE)
Please note: I am not passing any cflags just yet, I am trying to get a Vanilla build working first
The Android.mk file resides in a subdirectory of your project's jni/ directory, and describes your sources and shared libraries to the build system. It is really a tiny GNU makefile fragment that the build system parses once or more.
The Native Development Kit (NDK) is a set of tools that allows you to use C and C++ code with Android and provides platform libraries you can use to manage native activities. STEP 1: To use the ndk-tools with android, you need to download and install “NDK tools” from the SDK-manager.
Right click on the "app" folder and select New->Folder->JNI Folder. This should create a folder under app/src/main called "jni". List your *. c files on LOCAL_SRC_FILES and the name your library on LOCAL_MODULE.
It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++). JNI is vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.
yes, by default the gradle android plugin regenerates and uses its own Android.mk file to compile your sources.
You can deactivate this and use your own Android.mk file instead, by setting this inside your build.gradle configuration file:
import org.apache.tools.ant.taskdefs.condition.Os
...
android {
...
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jniLibs
jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk
}
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
Note that if you only need to pass your own cflags to the auto-generated Makefile, you can set these inside the cFlags ""
property to set inside android { ndk {}}
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