読者です 読者をやめる 読者になる 読者になる

cocos2d-x-3.0beta2のプロジェクトをgradle化してみる(比較検証版)

自メモ)
記事分割
 分割元:



ちょっとこれ読んだけど、なんか色々と違うんじゃないかなと思った

少なくとも気づいてることは

  1. lnで対応って駄目じゃない?
  2. build_native.sh使わなくてもできるよね?*1

+ cocosフォルダとか一覧にないけど beta以前のプロジェクトを移行=>それをもとに解説されたお話の認識でいいのか? *2 とか・・・・・。

 なんか読んでると
開発はXCodeでやってて、androidはbuildだけ通せればいいや
の公式のサイトの開発スタイルを踏襲してるかな。。うーん><*3

 cocos2d-xのandroidのprojectの状態だと
ADTでデバック転送して開発できない状態がデフォルトなので*4

 改めて変更設定全部書きだしたほうがいい気もするけどすぐRC1とかでるだろうし、native連携系のX-pluginも中国系の奴は揃ってるけど、GAすらないから厳しいだろうなとは思う*5






>>>プロジェクト作成から 一連の修正手順まで含めたgradleプロジェクト化(きよこみさん比較版)

 自分の場合はx-pluginまで使っているが普通は使わないで開発するらしいので、
そこは割愛して進める。

id:kyokomi さんの例の場合は

の同梱まで想定されてるけど、これだとただ同梱してるだけだよなという感じがする*6

そもそも 3.0系って

  • JNIなんか普通使わないからNativeActivityでよくね?(JSBも高速になるしw)

って構想だと思ってたし。

まあ一応比較のために記述を追加はしておく*7

◎プロジェクトの作成)

cd cocos2d-x 
./tools/project-creator/create_project.py -n irof -k com.hoge.driven -l cpp -p projects
  • 作成された projects/irof 以下の構成
irof
├── Classes
├── cocos2d 
├── proj.android
              ├── project.properties (△)
              ├── .project(△)
              ├── .cproject(△<手動追加>)
              ├── local.properties(△<手動追加>)
              ├── jni
                      ├── Android.mk(△)
                      ├── Application.mk(△)
├── proj.ios_mac
├── proj.linux
├── proj.win32
└── Resources


◎proj.androidを ADTで使える形に修正+α)

  • proj.android/project.properties
    • これalpha1あたりからずっとデグレってるのでtargetを修正する*8
      • 元のテンプレートは template/multi-platform-cpp/proj.android
target=android-10
=>
target=android-14

勿論SDKandroid-19とか 操作端末に入っていればそれを指定してもOK

betaから create_project.pyで相対パスにcocos2dのソース一式コピーする動きなのに
現状だとCOCOS2DXなるworkspace情報いじること前提の変数が残ってるので置換*9

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>irof</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
		<buildCommand>
			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.jdt.core.javabuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
			<triggers>full,incremental,</triggers>
			<arguments>
			</arguments>
		</buildCommand>
	</buildSpec>
	<natures>
		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
		<nature>org.eclipse.jdt.core.javanature</nature>
		<nature>org.eclipse.cdt.core.cnature</nature>
		<nature>org.eclipse.cdt.core.ccnature</nature>
		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
	</natures>
	<linkedResources>
		<link>
			<name>Classes</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/Classes</locationURI>
		</link>
		<link>
			<name>cocos2dx</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/cocos2d/cocos/2d</locationURI>
		</link>
		<link>
			<name>extensions</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/cocos2d/extensions</locationURI>
		</link>
		<link>
			<name>scripting</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/cocos2d/cocos/scripting</locationURI>
		</link>
<!-- 追加 start-->		
		<link>
			<name>Resources</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/Resources</locationURI>
		</link>
<!-- 追加 end-->
		
<!-- X-pluginを使うなら追加  start-->
		<link>
			<name>include</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/cocos2d/plugin/protocols/include</locationURI>
		</link>
<!-- X-pluginを使うなら追加 end-->		
	</linkedResources>
</projectDescription>

betaあたりからテンプレートから消えてるんだけど、これGUIで手動で設定しろってこと?

 ADT20あたりから

  1. プロジェクト上で右クリック
  2. tools=>AndroidNativeSupport

で既存プロジェクトにNDK構成を簡単に追加できるようにはなってるらしいけど。。

 予想通り今の状態だと


CDTプロジェクトではありません
とでていじれない。これは.cprojectが破損かない場合に出るものらしい。中途半端にNatureが登録されてると AndroidNativeSupport 自体が表示されない
したがって eclipse上で 空プロジェクトで作った.cprojectをコピーして持ってくる
=>そのまま認識。

 CDTが設定できるようになったら

みたいに
build_native.py 設定するか

まあ従来通りに

ndk-build NDK_DEBUG=1

を設定するか。そこら辺はおこのみで

☆☆ただし、従来通りのndk-buildで遣る場合
build_native.py や build_native.shが

  1. assetsの中身を全消し
  2. Resources=>assetsにコピー

ということをやってるので Android.mkに下記の追加をして遣らないと
[Resource not found =>SEGV]で落ちる仕様。。。

# use ndk-build
$(shell rm -f $(PROJECT_DIR)/assets/*)
$(shell cp -fr $(PROJECT_DIR)/../Resources/* $(PROJECT_DIR)/assets)


備考:android ndkプロジェクトとしてeclipseが認識する条件>
.project

<!-- 〜略〜 -->
	<buildCommand>
			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
			<triggers>full,incremental,</triggers>
			<arguments>
			</arguments>
	</buildCommand>
</buildSpec>
<natures>

<!-- 〜略〜 -->
	<nature>org.eclipse.cdt.core.cnature</nature>
	<nature>org.eclipse.cdt.core.ccnature</nature>
	<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
	<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
  • 正常な .cproject がプロジェクト直下にあること
  • proj.android/jni/Application.mk
    • ndkdebugするための情報等を追加
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1 -std=c++11 -fsigned-char

#以下を追加(APP_ABI は armeabi-v7aでも可)
APP_ABI :=armeabi
APP_OPTIM := debug
APP_PLATFORM := android-9 

注>

APP_ABI :=armeabi armeabi-v7a x86

とかけばgenymotion等をも対象にできるが [APP_ABI :=◎ ]の形で単一にとしないとndkdebugが出来ない*10

を使うと楽かも

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := cocos2dcpp_shared
LOCAL_MODULE_FILENAME := libcocos2dcpp

#LOCAL_SRC_FILES := hellocpp/main.cpp \
#                  ../../Classes/AppDelegate.cpp \
#                   ../../Classes/HelloWorldScene.cpp

# ソースの自動検索
CPP_FILES := $(shell find $(LOCAL_PATH)/../../Classes -name *.cpp)                   
LOCAL_SRC_FILES := hellocpp/main.cpp
LOCAL_SRC_FILES += $(CPP_FILES:$(LOCAL_PATH)/%=%)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static


include $(BUILD_SHARED_LIBRARY)

# add seatch path(☆)
COCOS2DX_ROOT := $(LOCAL_PATH)/../../cocos2d
$(call import-add-path,$(COCOS2DX_ROOT))
$(call import-add-path,$(COCOS2DX_ROOT)/cocos)
$(call import-add-path,$(COCOS2DX_ROOT)/external)

$(call import-module,2d)
$(call import-module,audio/android)
$(call import-module,Box2D)
  • proj.android/local.properties
    • これなければ作った方がいい*12
sdk.dir=/Users/xxxx/android-sdks
ndk.dir=/Users/xxxx/android-ndk-r9c

create_project.py時の コピーテンプレ系で半自動化考えるなら
ant.properties に追記したほうがいいんだろうけどな。
でもADTは

  • local.propertiesのsdk.dir

を参照してますし。。

ndk.dirを追加してるのはndkを特定verで運用していたり
人によって環境パス違うから。

PS)
自分の場合はant運用も考えた場合、署名キーもlocal.propertiesに記載している

sdk.dir=/Users/xxxx/android-sdks
ndk.dir=/Users/xxxx/android-ndk-r9c

#custom value
key.store=irof.keystore
key.store.password=driven
key.alias=irof
key.alias.password=hoge

其の場合、gradleプロジェクト内に反映するには

def prop1 = new Properties()

//[NOTE]マルチプロジェクト構成(AS形式で)ルート直下の場合はこちら
//prop1.load(new FileInputStream( new File(settigDir,'local.properties') ))
//[NOTE]eclipse-export形式だとこちら
prop1.load(new FileInputStream( new File(projectDir,'local.properties') )) 


def config = new ConfigSlurper().parse(prop1)


println config.dump()
//println config.key."store.password"

project.ext {
    storeFile=config.key.store
    storePassword=config.key."store.password"
    keyAlias=config.key.alias
    keyPassword=config.key."alias.password"
}

NOTE)
windows等であれば ndk-buildにpathが通っていないので
NDK_ROOT=XXX の形で代入して
${NDK_ROOT}/ndk-build としたほうがベター
環境変数に定義済みなら


${System.env.NDK_ROOT}
で参照可能だとは思いますが‥‥‥*13


apply from:"config.gradle"

を上部に追加して適応


◎gradleプロジェクト化の準備)

  • android-sdks/tools/templates/gradle/wrapper から projects/irof 以下へ ごっそりコピー
  • コピー後のprojects/irof 以下の構成
irof
├── Classes
├── cocos2d 
├── gradle            //☆
├── gradlew         //☆
├── gradlew.bat   //☆
├── proj.android
├── proj.ios_mac
├── proj.linux
├── proj.win32
└── Resources

基本的にASのみ更新されている状態でANDROID_SDKの方は放置気味なので
手動で gradle/wrapper/gradle-wrapper.properties を最新に修正

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip

PS)
ちなみに offline buildをしたい場合には

をダウンロードしてきて irof/localRepoってフォルダ作成=>保存

#distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
distributionUrl=../../localRepo/gradle-1.10-all.zip

な書き換えだけでいける。

フルパスにしたい場合は

#distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
distributionUrl=file\:/home/hoge/localRepo/gradle-1.10-all.zip

でOK

WinにしてもMacにしても
> file\:
にしないと認識できないみたい

> http\:
もおんなじ感じじゃないかなーと



◎gradleプロジェクト化の開始)

 ベース自体は
GitHub - zaki50/android_gradle_template: Gradle を使った Android 用のプロジェクトのひな形
が日本ではテンプレート的に一番詳しいらしいのでこれをベースに変更
(使っていない箇所はコメントの方向で進める)

 因みに

        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7

実行JDKが1.7以上であることが必須。

  • $HOME/.bash_profile
#export JAVA_HOME=`/usr/libexec/java_home -v 1.6`
export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
#export JAVA_HOME=`/usr/libexec/java_home -v 1.8`

等の設定等も場合によっては必要か。。。

PS)
他の有名なgradleテンプレート(for AS)

  • ルート直下系のファイルの配置(☆)
    • ルート直下系のbuild.gradle等の設置(☆☆)
irof
├── Classes
├── cocos2d 
├── gradle            //☆
├── gradlew         //☆
├── gradlew.bat   //☆
├── proj.android
├── proj.ios_mac
├── proj.linux
├── proj.win32
├── Resources
├── settings.gradle  //☆☆
└── build.gradle     //☆☆
  • settings.gradle (☆☆)
include ':proj.android',':cocos2d/cocos/2d/platform/android/java'
  • build.gradle (☆☆)
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:0.8.+"
        classpath 'com.uphyca.gradle:gradle-android-apt-plugin:0.9.+'
    }
}

subprojects {
    repositories {
        mavenCentral()
//https://plus.google.com/109385828142935151413/posts/hF7W59uZ7rX
//        mavenLocal()
        maven {
            url "${System.env.HOME}/.m2/repository"
        }
    }
}

// http://www.gradle.org/docs/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html
/*
project.ext {
    supportPackageVersion = "19.0.+"
    playServicesVersion = "4.0.+"
    daggerVersion = "1.1.0"
    androidAnnotationsVersion = '3.0.1';
    nineOldAndroidsVersion = "2.4.0"
    commonsLangVersion = "3.2.1"
    commonsIoVersion = "2.4"
    guavaVersion = "16.0"
    jppVersion = '1.6.+';
    googleApiClientVersion = "1.16.0-rc"
}
*/

task wrapper(type: Wrapper) {
    gradleVersion = '1.9'
}
  • サブプロジェクトにgradleファイルを設定する(☆☆☆)


irof
├── Classes
├── cocos2d
├──cocos/2d/platform/android/java/build.gradle //☆☆☆
├── gradle //☆
├── gradlew //☆
├── gradlew.bat //☆
├── proj.android
├── build.gradle //☆☆☆
├── proj.ios_mac
├── proj.linux
├── proj.win32
├── Resources
├── settings.gradle //☆☆
└── build.gradle //☆☆

    • proj.android/build.gradle (☆☆☆)
apply plugin: 'android'

dependencies {
    // libs/ にある *.jar を一括で追加する
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':cocos2d/cocos/2d/platform/android/java')
}


//see http://dev.xconnecting.com/2012/11/gradle_26.html
ant.condition(property: "os", value: "windows") { os(family: "windows") }
ant.condition(property: "os", value: "unix" ) { os(family: "unix") }
ant.echo "[OS]=$ant.properties.os"

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.1"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 19

        versionCode 1
        versionName '0.0.1'
    }

// ADT LIKE Source Location add start
	sourceSets {
    	main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
    	}
    }
//ADT LIKE Source Location add end

    compileOptions {
        encoding = "UTF-8"
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    packagingOptions {
        // exclude duplicate files in apache commons
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }

    signingConfigs {
        // debug {
        //     storeFile file("debug.keystore")
        // }

        release
    }



    buildTypes {
        release {
            runProguard true
            proguardFile getDefaultProguardFile('proguard-android.txt')
            proguardFile file('proguard-project.txt')

            // gradle.properties にリリース署名用の設定があれば署名を有効化します。設定のサンプルとして gradle.properties.forReleaseSigning を置いたので参考にしてください。
            if (project.hasProperty('storeFile')) {
                signingConfig signingConfigs.release
            }
        }
    }

    task ndkBuild(type:Exec) {
	cpu_num = Runtime.getRuntime().availableProcessors()
        println "cpu_num=${cpu_num}"
        commandLine 'ndk-build', "-j${cpu_num}"
    }

    task ndkClean(type:Exec) {
        commandLine 'ndk-build', 'clean'
    }

    task libsClean(type:Exec) {
		switch(ant.properties.os){
        	case 'windows':
				commandLine 'rd', '/S', '/Q', 'libs/armeabi', 'libs/armeabi-v7a', 'libs/x86', 'libs/mips'
				break;
        	case 'unix':
				commandLine 'rm', '-rf', 'libs/armeabi', 'libs/armeabi-v7a', 'libs/x86', 'libs/mips'
				break;
		}
    }

    task objClean(type:Exec) {
		switch(ant.properties.os){
        	case 'windows':
				commandLine 'rd', '/S', '/Q', 'obj'
				break;
        	case 'unix':
				commandLine 'rm', '-rf', 'obj'
				break;
		}
    }

    if(new File(projectDir, "jni").exists()){
        tasks.withType(Compile) {
            compileTask -> compileTask.dependsOn ndkBuild
    }

    //mod see http://stackoverflow.com/questions/20704812/android-studio-0-4-could-not-find-method-jnidir
        tasks.withType(com.android.build.gradle.tasks.PackageApplication) {pkgTask -> 
			pkgTask.jniFolders = new HashSet<File>()
		    pkgTask.jniFolders.add(new File(projectDir, 'libs'))
        }

        clean.dependsOn 'ndkClean'
        clean.dependsOn 'libsClean'
        clean.dependsOn 'objClean'
    }
}

if (project.hasProperty('storeFile')) {
    android.signingConfigs.release.storeFile = file(storeFile)
}
if (project.hasProperty('storePassword')) {
    android.signingConfigs.release.storePassword = storePassword
}
if (project.hasProperty('keyAlias')) {
    android.signingConfigs.release.keyAlias = keyAlias
}
if (project.hasProperty('keyPassword')) {
    android.signingConfigs.release.keyPassword = keyPassword
}

手を入れた箇所>
 ndk-build周りは現状で微妙だったので修正をした

  • 今回のbuild_native.pyのウリが ndk-build の -j[CPU数] でビルド高速化 みたいな話だったので反映
  • clean対象にobjフォルダ追加
  • pkgTask.jniFolders あたりの記述が動かなくなってたので修正
  • rm -r の記述は乱暴だと思うのでのちのち書き換え予定*14
    • ADTでも使うこと前提だと単純同梱も消える。。
    • ASベースなら単純同梱soの設定か下記になってるからたしかに問題はないんだろうけどな。。。(汗

 まあべき論から言うとjni/Android.mkのライブラリ名からso検索して消すべき

android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['jniLibs']
        }
apply plugin: 'android-library'

dependencies {
    // libs/ にある *.jar を一括で追加する
    compile fileTree(dir: 'libs', include: '*.jar')
    //compile "com.android.support:support-v4:${supportPackageVersion}"
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.1"

//ADT LIKE Source Location add start
	sourceSets {
    	main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
    	}
    }
//ADT LIKE Source Location add end

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 19
    }

    compileOptions {
        encoding = "UTF-8"
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

一応この設定で


./gradlew assembleDebug
でビルドは完了です

 apkのlunchDebugまで考えるなら

なtask追加の方向性も有るよう

 勿論

のカスタムタスクを追加する方向も楽かも



x-pluginの追加によるビルド)

に記述移動


現時点での考察メモ>

 現時点での上記の構成状態だと問題はあって、

ASと同じく

  • メモリバカ食う
  • CPU使用率が凄いことになってる
    • ndk-buildを少なくともforkしないと駄目かも。。。

で操作端末が固まりやすくなる

ココらへんは gradle.properties あたりでパラメータチューニングしないと死ぬ。

  • gradle.properties


# see http://www.gradle.org/docs/current/userguide/build_environment.html
# org.gradle.daemon=true
org.gradle.jvmargs=-Dgroovy.source.encoding=UTF-8 -Dfile.encoding=UTF-8 -Xmx96m -XX:MaxPermSize=64m -XX:NewRatio=12 -XX:SurvivorRatio=25 -XX:+UseSerialGC
# org.gradle.parallel=true
最低環境はコレ。

最新のMBP辺ならコメントにしてる

  • org.gradle.daemon=true
  • org.gradle.parallel=true

あたり有効にしてもいいけど古めの本体で有効にしてるとしばらく端末が使えなくなる(Box2Dとか重めのコンパイルするとき)

  • build_native.py
  • build_native.sh

等で遣る場合にそういうことなかったからなんか上手く動かせてない仕組みがあるんだろうな。。(汗

*1:カスタムタスク呼ぶならndkbuild呼ぶほうが建設的

*2:後から読み直したらalphaの話でしたね<汗

*3:eclipse等のjavaIDEで開発するのはそんなにナンセンス?

*4:もちろんndk-debugも出来ない状態

*5:どうもtwitter4j使ったpluginサンプルの方は、有一、英語のコミッターの方が作られたものらしい

*6:多分入れる意味ないんじゃないかと。。IOS開発主にしているとしてもcocosであればUIKitを触らせない<OpenGLベースの代替を用意>方針みたいですし

*7:Android.mk等に関する言及もないようなのでただbuildを通しただけであろう。JNI使わないならやらんでも良い操作だとは思う

*8:どのままだとADTのAndroidManifext.xmlがLintエラー

*9:cocos2dxの開発者の人はADT使ってないと断言できる!

*10:eclipseからだと Debug As=>NativeApplication

*11:ただし自動検索だとコンパイル順が名前順になるようで、サードパーティライブラリをjniフォルダの下にまるっとぶっこむ等をした場合にはコンパイルエラーが出ることも有り。その場合は諦めて手動で書く

*12:cocos2dxフォーラムでもant運用の時しかでてこないネタなのでしらん人も多いらしい。まあ最近のSDKはlocal.propertiesが無ければ環境変数を見に行くようですが。。。

*13:build_native.py/sh使うなら ANDROID_SDK_ROOT, NDK_ROOTを環境変数に定義しておけ的な記載は有ると思う<でも local.properties 読むようにしたほうが建設的

*14:そもそもwinじゃ動かないし=>win対応のみしました