I'm trying to import a little C++ Open GL ES framework I wrote for an iOS application into an Android application.
I want to use Android NDK to import this framework.
As the framework will be shared between iOS and Android, I placed it outside the jni folder. I specified the path to the source dir of this framework in my grade file as follow (http://tools.android.com/tech-docs/new-build-system/gradle-experimental#TOC-Source-Set):
In this framework I used the GLM library for math operation, but as you could see again from the above screenshot, when I try to compile the project I receive the error:
/Users/chicio/Desktop/SpectralBRDFExplorer/SpectralBRDFExplorer/glm/detail/glm.cpp:4:10: fatal error: 'glm/glm.hpp' file not found
What am I doing wrong?
I found a solution to the problem by myself.
As stated before, it was a problem in the setup of the include directories.
I made the app compile by specifying in the gradle file the include directories suing the C++ flag -I
Here you can find the complete gradle file:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion 24
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "it.chicio.android.spectralbrdfexplorer"
minSdkVersion.apiLevel 22
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file('proguard-android.txt'))
}
}
ndk {
moduleName "LibOpenGLJNI"
toolchain = 'clang'
stl = 'gnustl_static'
CFlags.addAll(['-Wall'])
cppFlags.addAll(['-std=c++11','-Wall',
'-I' + file('src/main/jni'),
'-I' + file('../../SpectralBRDFExplorer'),
'-I' + file('../../SpectralBRDFExplorer/lodepng')])
ldLibs.addAll(['android', 'log', 'GLESv3'])
}
sources {
main {
jni {
source {
srcDir "../../SpectralBRDFExplorer"
}
}
}
}
sources {
main {
assets {
source {
srcDir "../../Assets"
}
}
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:24.2.0'
}
Related
I am using the android gradle experimental plugin to build an app module with some native code. This native code uses a library with pre-built .so files, which I am bundling into a .aar file via an android library module. The .aar file builds fine, but how do I link the native code module in the app module to the pre-built .so files in the .aar module? The gradle experimental documentation doesn't mention this scenario.
Also, I'd like to package up include files in the .aar file if possible (although they shouldn't be packaged with the final application).
In /prebuiltlib:
build.gradle
-src/
--main/
---jniLibs/
----libfoo.so
Here are the gradle files:
/prebuiltlib/build.gradle
apply plugin: "com.android.model.library"
model {
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
minSdkVersion.apiLevel = 21
targetSdkVersion.apiLevel = 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file("proguard-rules.pro"))
}
}
}
}
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:25.3.1"
}
Here is /app/build.gradle, note the ??? where I'm not sure what to put:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.model.application'
model {
repositories {
libs(PrebuiltLibraries) {
// ??? is this right, and does this go into app/build.gradle or mylib/build.gradle?
foo {
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file('???/libfoo.so')
}
}
}
}
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.3'
defaultConfig {
applicationId = 'com.jeremy.stackoverflow.sample'
minSdkVersion.apiLevel = 21
targetSdkVersion.apiLevel = 21
versionCode = 1
versionName = '1.0'
}
ndk {
platformVersion = 21
moduleName = 'native-activity'
toolchain = 'gcc'
toolchainVersion = '4.9'
stl = 'gnustl_shared'
abiFilters.add('armeabi-v7a')
ldLibs.addAll(['log',
'android',
'EGL',
'GLESv2'
])
// ??? How do I add include paths from the .aar module?
cppFlags.add('-I' + file('???/include'))
cppFlags.addAll(['-std=c++11', '-fexceptions'])
}
sources {
main {
jni {
dependencies {
// ??? Is this right?
library 'foo' linkage 'shared'
}
}
jniLibs {
source {
// ??? Do I need one of these for the libs in the .aar?
srcDir file('???/jniLibs')
}
dependencies {
// ??? Is this right?
library 'foo'
}
}
}
}
buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.pro'))
}
}
}
}
dependencies {
println rootProject.getName()
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:25.3.1'
compile project(':prebuiltlib')
}
Starting with Android Gradle Plugin 4.0, C/C++ dependencies can be imported from AARs linked in your build.gradle file. Gradle will automatically make these available to the native build system, but your build system must be configured to make use of the imported libraries and headers.
In gradle 4.0: add the following to your project's gradle.properties file:
android.enablePrefab=true
In gradle 4.1: add the following to the android block of your module's build.gradle file:
buildFeatures {
prefab true
}
, if your application defines libapp.so and it uses cURL, your CMakeLists.txt should include the following:
add_library(app SHARED app.cpp)
# Add these two lines.
find_package(curl REQUIRED CONFIG)
target_link_libraries(app curl::curl)
app.cpp is now able to #include "curl/curl.h", libapp.so will be automatically linked against libcurl.so when building, and libcurl.so will be included in the APK.
Source: https://developer.android.com/studio/build/native-dependencies
I am trying to compile Crypto++ library on Android using JNI. I have cloned the project of https://github.com/morgwai/ndktutorial. I imported the project into android studio, I am able to call the JNI class and read the Crypto++, but when the library gets called I get an inside error which says "memory" no such file or directory pointing to #include <memory>.
Here is my build.gradle:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.moham.myapplication"
minSdkVersion.apiLevel 22
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file('proguard-android.txt'))
}
}
ndk {
moduleName "crypt_user.cpp"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.2.1'
}
Also here is the error I get when I compile:
MYPATH\Android\sdk\ndk-bundle\platforms\android-23\arch-arm64\usr\include\stdcpp.h
Error:(10, 18) memory: No such file or directory
compilation terminated.
Error:Execution failed for task ':app:compileCrypt_userArm64-v8aDebugSharedLibra
ryCrypt_userMainCpp'.
> A build operation failed.
C++ compiler failed while compiling crypt_user.cpp.
See the complete log at: file:///D:/MyApplication/app/build/tmp/compileCrypt_u
serArm64-v8aDebugSharedLibraryCrypt_userMainCpp/output.txt
Thank you in advance.
Add
APP_STL = c++_shared
to your Application.mk
I am trying to make use of the "Multiple NDK Projects" feature of the experimental gradle plugin. I am using Android Studio 2.1 and gradle plugin 0.7.0 stable. The blog seems to say that the header files specified in the exportedHeaders section of the native library will be included during compilation
exportedHeaders {
srcDir "src"
}
This does not seem to work for me. Say for example I have the following folder structure, I would expect Addition.h to be available in native.cpp, ie I should be able to say
#include <Addition.h>
but only
#include "../../../../../../../Framework/Addition/src/Addition.h"
works. Adding cppFlags to include the headers makes no difference.
Here's how some relevant files look for an example project. The example project module "app" depends on a native library module "addition" to add 2 numbers. The native library uses the new native plugin.
settings.gradle
include ':app'
include ':Addition'
project (":Addition").projectDir = new File("../../../Framework/Addition")
gradle-wrapper.properties
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
build.gradle (:app)
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
ndk {
moduleName = 'native'
platformVersion = 17
toolchain "clang"
cppFlags.addAll(['-I' + file('src/main/jni'),
'-I' + file('../../../Framework/Addition')])
}
sources {
main {
jni {
dependencies {
project ':Addition' linkage 'static'
}
}
}
}
defaultConfig {
applicationId "com.harkish.nativepluginexample"
minSdkVersion.apiLevel 21
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
}
build.gradle (:Addition)
apply plugin: 'com.android.model.native'
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
defaultConfig {
minSdkVersion.apiLevel = 21
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = '1.0'
}
ndk {
moduleName = 'addition'
}
sources {
main {
jni {
source {
srcDir "src"
}
exportedHeaders {
srcDir "src"
}
}
}
}
}
}
Anyone solved this problem? ideas?
I've inherited a really messy android project with a lot of NDK dependencies and having a lot of problems with getting gradle to correctly link and include all .so and .a files into the resulting apk.
The project consists of some java code that sets up some activities and call into a big NDK library, built from C++ which in turn links with a dosens of 3rd party library (prebuilt or built from source).
I have managed to make it build with the latest gradle experimental plugin, but for some reason, my module isn't included in the apk while my 3rd party .so files are even though I can see that gradle have built my module into a .so file which it have placed in the build directory.
My build.gradle looks like this:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "22.0.1"
defaultConfig.with {
applicationId = "<removed>"
minSdkVersion.apiLevel = 7
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
ndk {
moduleName = "XM"
CFlags.add("-I${file("src/main/jni")}".toString())
cppFlags.addAll(["-I${file("../../3rd_part/android/osg")}".toString()])
cppFlags.addAll(["-I${file("../../3rd_part/android/opus")}".toString()])
ldFlags.add("-L${file("src/main/jniLibs/armeabi-v7a")}".toString())
ldLibs.addAll(["osgdb_jpeg", "osgdb_freetype", "jpeg","argsub_es", "jnigraphics", "android", "log"])
stl = "gnustl_shared"
abiFilters.add("armeabi-v7a")
}
sources {
main {
jni {
source {
srcDir "../../core"
srcDir "src/main/jni"
}
}
}
}
lintOptions.abortOnError = false
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:23.0.0'
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:design:23.0.0'
compile 'com.wunderlist:sliding-layer:1.1.1'
}
So to sum up my question: why does gradle build my module (libXM.so), place it into build/libs/xM/shared/armeabi-v7a/debug, but not include it into my final apk file?
I didn't get several things: if you want to build a shared library with gradle, then you have to use apply plugin: 'com.android.model.library' and not application
If you want to build an application and use prebuilt library, then you have to write something like this:
sources {
main {
jni {
source {
srcDir "../../core"
srcDir "src/main/jni"
}
dependencies{
library "XM" linkage "shared"
}
And, of course, to set ldFlags previously.
Android Studio 1.1 generated apk file (located # app/build/outputs/apk folder) contains the lib directory, and for every cpu type there exists a non-empty folder, like /x86. Each of these folder contain a libapp.so shared library that is around 5Kb in size per cpu.
I've searched the net and the only thing I found so far is this link from Intel https://software.intel.com/en-us/articles/building-native-android-apps-using-intelr-c-compiler-in-android-studio that shows how to change the default libapp.so to user-provided library.
So, I guess that this library (libapp.so) is somehow built by gradle.
In fact I do my own native library building, using ndk-build command line tool, and my libs are placed alongside that libapp.so. It's not causing any issues btw, but I feel that I'm losing the control over what is built and why.
Here's my humble build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
/**
* Path to *.so files
*/
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //disable automatic ndk-build
}
}
defaultConfig {
applicationId "com.sample.android"
minSdkVersion 9
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
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:22.0.0'
}
How can I disable this libapp.so being built?
defaultConfig {
ndk {
moduleName "yourSelfLib"
}
}