I have a gradle-experimental 0.6.0-alpha1 compliant build.gradle file:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 21
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.company.application"
minSdkVersion.apiLevel = 21
targetSdkVersion.apiLevel = 21
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.pro'))
}
}
android.ndk {
moduleName = "moduleName"
}
}
dependencies {
compile project(':libcocos2dx')
}
And I am using cocos2dx as my engine. I have a folder hierarchy that looks like this:
- Classes (which contains all the C++ code of my project)
- proj.android/src/main/projectName/jni (which contains the main.cpp file for cocos2d to hook on)
I also have many other cpp classes that are in a different folders outside the proj.android one (the cocos2d cpp file for example are at proj.android/../../../dependencies/XXXX/cocos2d-x and the engine files are at proj.android/../../../dependencies/XXXX/engine, and all my C++ code is at proj.android/../Classes, as in every cocos2dx project)
I am trying to build my application using the latest gradle experimental plugin (gradle-experimental-0.6.0-alpha1).
I first try to build it as-is, project compile and run but was empty (no libMyApp.so was generated), because I didn't included any C++ source file in my gradle build.
I then made some symbolic link to the source file folder so that gradle could pick them:
ln -s proj.android/../../../dependencies/XXXX/cocos2d-x proj.android/src/main/projectName/jni
Now when I am building (./gradlew assembleDebug), I get it compile symboliquely linked C++ files, but it fails on the first include of header everytime, no matter what I try.
I have tried to add source file/ header include as described here using:
android.sources {
main {
jni {
source {
srcDir "src"
}
exportedHeaders {
srcDir "src"
}
}
}
}
but I couldn't get it to find the missing ".h" headers. If anybody has tried to build a consequent C++ project using cocos2Dx, gradle-experimental and android-studio please feel free to share any experience. I will try to compile some sort of guide when I will be able to compile it (one day :))
for reference: latest gradle doc:
https://docs.gradle.org/2.9/userguide/nativeBinaries.html
usefull link:
http://ph0b.com/new-android-studio-ndk-support/
Hi Thank you for your file, I made some modification to you files.
I works then, I did it with cocos2Dx 3.9 on my Mac OSX.
You need : com.android.tools.build:gradle-experimental:0.6.0-alpha5'
You can put breakpoints in Java and C++ at the same time.
Cyrl
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.model.library'
model {
repositories {
libs(PrebuiltLibraries) {
chipmunk {
headers.srcDir "../../../../external/chipmunk/include"
binaries.withType(SharedLibraryBinary) {
//
// NOTE: this block should be "StaticLibraryBinary"/staticLibraryFile - but SharedLibraryBinary works and StaticLibraryBinary doesn't as of 0.6.0-alpha2
// bug reported here: https://code.google.com/p/android/issues/detail?id=196065
//
sharedLibraryFile = file("../../../../external/chipmunk/prebuilt/android/${targetPlatform.getName()}/libchipmunk.a")
}
}
freetype2 {
headers.srcDir "../../../../external/freetype2/include/android/freetype2"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/freetype2/prebuilt/android/${targetPlatform.getName()}/libfreetype.a")
}
}
curl {
headers.srcDir "../../../../external/curl/include/android/curl"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/curl/prebuilt/android/${targetPlatform.getName()}/libcurl.a")
}
}
png {
headers.srcDir "../../../../external/png/include/android"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/png/prebuilt/android/${targetPlatform.getName()}/libpng.a")
}
}
jpeg {
headers.srcDir "../../../../external/jpeg/include/android"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/jpeg/prebuilt/android/${targetPlatform.getName()}/libjpeg.a")
}
}
tiff {
headers.srcDir "../../../../external/tiff/include/android"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/tiff/prebuilt/android/${targetPlatform.getName()}/libtiff.a")
}
}
webp {
headers.srcDir "../../../../external/webp/include/android"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/webp/prebuilt/android/${targetPlatform.getName()}/libwebp.a")
}
}
bullet {
headers.srcDir "../../../../external/bullet/"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/bullet/obj/local/${targetPlatform.getName()}/libbullet.a")
}
}
recast {
headers.srcDir "../../../../external/recast/"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/recast/obj/local/${targetPlatform.getName()}/librecast.a")
}
}
websockets {
headers.srcDir "../../../../external/websockets/include/android"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/websockets/prebuilt/android/${targetPlatform.getName()}/libwebsockets.a")
}
}
ssl {
headers.srcDir "../../../../external/curl/include/android/curl"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/curl/prebuilt/android/${targetPlatform.getName()}/libssl.a")
}
}
crypto {
headers.srcDir "../../../../external/curl/include/android/curl"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../../../../external/curl/prebuilt/android/${targetPlatform.getName()}/libcrypto.a")
}
}
}
}
android {
compileSdkVersion = 21
buildToolsVersion = "23.0.2"
defaultConfig.with {
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 9
}
}
android.ndk {
moduleName = "cocos2dx"
stl = "c++_static"
cppFlags.add("-std=c++11")
cppFlags.add("-pthread")
cppFlags.add("-fexceptions")
cppFlags.add("-frtti")
CFlags.add("-DUSE_FILE32API")
CFlags.add("-fexceptions")
ldLibs.addAll(["atomic", "log", "android", "EGL", "GLESv2", "z" ])
}
android.sources {
main {
manifest.source {
srcDir "."
include "AndroidManifest.xml"
}
jni {
source {
// INTERNAL CPP FILES
//srcDir "../../../../cocos/"
// include only file at this level
srcDir "../../../../cocos/2d"
srcDir "../../../../cocos/sourceFile"
srcDir "../../../../cocos/3d"
srcDir "../../../../cocos/math"
srcDir "../../../../cocos/base"
srcDir "../../../../cocos/platform/sourceFiles"
srcDir "../../../../cocos/cpufeatures"
// include only file at this level
srcDir "../../../../cocos/platform/android"
srcDir "../../../../cocos/renderer"
srcDir "../../../../cocos/deprecated"
srcDir "../../../../cocos/physics"
srcDir "../../../../cocos/physics3d"
srcDir "../../../../cocos/navmesh"
srcDir "../../../../cocos/network"
srcDir "../../../../tests/cpp-empty-test/Classes"
srcDir "../../../../tests/cpp-empty-test/Main"
// EXTERNAL CPP FILES
srcDir "../../../../external/ConvertUTF"
srcDir "../../../../external/tinyxml2"
srcDir "../../../../external/unzip"
srcDir "../../../../external/edtaa3func"
srcDir "../../../../external/poly2tri"
srcDir "../../../../external/clipper"
srcDir "../../../../external/xxhash"
}
exportedHeaders {
// INTERNAL HEADERS
srcDir "../../../../cocos"
srcDir "../../../../cocos/2d"
srcDir "../../../../cocos/math"
srcDir "../../../../cocos/base"
srcDir "../../../../cocos/platform"
srcDir "../../../../cocos/platform/android"
srcDir "../../../../cocos/renderer"
srcDir "../../../../cocos/deprecated"
srcDir "../../../../cocos/physics"
srcDir "../../../../cocos/physics3d"
srcDir "../../../../cocos/navmesh"
srcDir "../../../../tests/cpp-empty-test/Classes"
// EXTERNAL HEADERS
srcDir "../../../../external"
srcDir "../../../../external/ConvertUTF"
srcDir "../../../../external/tinyxml2"
srcDir "../../../../external/unzip"
srcDir "../../../../external/edtaa3func"
srcDir "../../../../external/poly2tri"
srcDir "../../../../external/poly2tri/common"
srcDir "../../../../external/poly2tre/sweep"
srcDir "../../../../external/clipper"
srcDir "../../../../external/xxhash"
// STATIC LIBRARIES
srcDir "../../../../external/chipmunk/include/chipmunk"
srcDir "../../../../external/freetype2/include/android/freetype2"
srcDir "../../../../external/curl/include/android"
srcDir "../../../../external/png/include/android"
srcDir "../../../../external/tiff/include/android"
srcDir "../../../../external/jpeg/include/android"
srcDir "../../../../external/webp/include/android"
srcDir "../../../../external/websockets/include/android"
}
dependencies {
library "chipmunk"
library "freetype2"
library "curl"
library "png"
library "jpeg"
library "tiff"
library "webp"
library "bullet"
library "recast"
library "websockets"
library "ssl"
library "crypto"
}
}
}
}
android.buildTypes {
release {
}
debug {
ndk.with {
debuggable = true
}
}
}
android.productFlavors {
create ("arm") {
ndk.with {
abiFilters.add("armeabi-v7a")
ldFlags.addAll([
"-L${file("./obj/local/armeabi-v7a")}".toString()
])
}
}
create("x86") {
ndk.with {
abiFilters.add("x86")
ldFlags.addAll([
"-L${file("./obj/local/x86")}".toString()
])
}
}
}
}
task buildMkRecast(type: Exec) {
// Retrieve ndk dir
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkDir = properties.getProperty('ndk.dir', null)
// Call ndk build
def ndkBuildExt = Os.isFamily(Os.FAMILY_WINDOWS) ? ".cmd" : ""
commandLine "$ndkDir/ndk-build${ndkBuildExt}",
'-C', file('.').absolutePath,
'NDK_APPLICATION_MK=Application.mk',
'APP_BUILD_SCRIPT=../../../../external/recast/Android.mk',
'NDK_PROJECT_PATH=../../../../external/recast/'
}
task buildMkBullet(dependsOn: "buildMkRecast",type: Exec) {
// Retrieve ndk dir
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkDir = properties.getProperty('ndk.dir', null)
// Call ndk build
def ndkBuildExt = Os.isFamily(Os.FAMILY_WINDOWS) ? ".cmd" : ""
commandLine "$ndkDir/ndk-build${ndkBuildExt}",
'-C', file('.').absolutePath,
'NDK_APPLICATION_MK=Application.mk',
'APP_BUILD_SCRIPT=../../../../external/bullet/Android.mk',
'NDK_PROJECT_PATH=../../../../external/bullet/'
}
tasks.whenTaskAdded { task ->
def taskName = task.name
if (taskName.startsWith("compile")) {
task.dependsOn "buildMkBullet"
}
}
dependencies {
compile files('../java/libs/android-async-http-1.4.8.jar')
}
So I finally made it working by adding the
exportedHeaders {
srcDir "src"
}
line and point it to the right directory where the missing headers were.