Search code examples
c++android-ndkandroid-gradle-plugincocos2d-xgradle-experimental

cocos2dx-based project in android-studio using gradle-experimental plugin


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/


Solution

  • 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')
    }