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

cocos2d-x-3.0alpha1メモ(環境構築編)

自メモ)



新規プロジェクト作成編)

cd tools/project-creator
python create_project.py -p mygame -k com.your_company.mygame -l cpp
cd ../../projects/mygame

  • .project (projectエラーが出てbuildコマンドが着火しない記述)
<buildCommand>
	<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
	<triggers>full,incremental,</triggers>
	<arguments>
		<dictionary>
			<key>LaunchConfigHandle</key>
					<value>&lt;project&gt;/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder (1).launch</value>
		</dictionary>
	</arguments>
</buildCommand>

  • .project (genmakebuilderの記述修正)
<buildCommand>
	<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
	<triggers>clean,full,incremental,</triggers>
	<arguments>
	</arguments>
</buildCommand>

  • .project
<linkedResources>
		<link>
			<name>Classes</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/Classes</locationURI>//☆修正
		</link>
		<link>
			<name>Resources</name>
			<type>2</type>
			<locationURI>PARENT-1-PROJECT_LOC/Resources</locationURI>//☆追加
		</link>
		<link>
			<name>cocos2dx</name>
			<type>2</type>
			<locationURI>COCOS2DX/cocos/2d</locationURI> //☆修正
		</link>
		<link>
			<name>extensions</name>
			<type>2</type>
			<locationURI>COCOS2DX/extensions</locationURI>
		</link>
		<link>
			<name>include</name>
			<type>2</type>
			<locationURI>COCOS2DX/plugin/protocols/include</locationURI>//☆追加
		</link>
		<link>
			<name>scripting</name>
			<type>2</type>
			<locationURI>COCOS2DX/cocos/scripting</locationURI>//☆修正
		</link>
</linkedResources>

<variableList>
	<variable>
		<name>COCOS2DX</name>
		<value>file:/XXXX/cocos2d-x-3.0alpha1</value>
	</variable>
<!--
	<variable>
		<name>COCOS2DX</name>
		<value>PARENT-3-PROJECT_LOC</value>
	</variable>
-->
</variableList>

残念ながら PARENT-3-PROJECT_LOC とかって locationURIの時しか展開してくれないorz
絶対パスしか無理みたい。

のお話

  1. 追加ポイント
    1. assets の画像はビルド時に消されるので実体の方の Resources のリンクを追加した
    2. include はPluginのヘッダをincludeするときにCDT上で警告が出るので追加*1


ここらへんの話はcocos2d-xの

のパス絡みの設定の話と同じ。だだこれworkspace単位に再設定が必要。
eclipse上からlinkedResourcesのフォルダ認識させるために必要なだけなので
コレってパスが固定ならテンプレートいじる形の
上記の方が楽だよなーとか思う*2


  • .cproject
<builder arguments="${ProjDirPath}/build_native.sh" buildPath="${ProjDirPath}" command="bash" enabledIncrementalBuild="true" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="org.eclipse.cdt.build.core.settings.default.builder.1648661634" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" stopOnErr="true" superClass="org.eclipse.cdt.build.core.settings.default.builder">

=>

<builder arguments="${ProjDirPath}/build_native.py" buildPath="${ProjDirPath}" command="python" enabledIncrementalBuild="true" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="org.eclipse.cdt.build.core.settings.default.builder.1648661634" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" stopOnErr="true" superClass="org.eclipse.cdt.build.core.settings.default.builder">

 ただこれ1個問題はあって、python入れたくないみたいな話があったりする(汗
ANDROID_SDK/tools/lib/jython-standalone-2.5.3.jar
を使う jython.bat/jython.sh 辺りの起動シェル作って動かしたほうがいいんだろうなとか思いつつ

やるとしたら

#!/bin/sh
$JAVA_HOME/bin/java -jar $ANDROID_HOME/tools/lib/jython-standalone-2.5.3.jar $*

winなら

set JAVA_HOME=C:\adt-bundle-windows-x86_64\jdk
set ANDROID_SDK_HOME=C:\adt-bundle-windows-x86_64\sdk

%JAVA_HOME%/bin/java -jar %ANDROID_SDK_HOME%/tools/lib/jython-standalone-2.5.3.jar %*

C++ build記述を

${SDK_ROOT}/jython.sh ${ProjDirPath}/build_native.py NDK_DEBUG=1

C++ build->Enviroment に

  1. SDK_ROOT
  2. NDK_ROOT
  3. PLUGIN_ROOT

みたいに環境パスを追加するのが一般的なのかもしれない





その他のいじっておいた方がいいtemplate>

template/multi-platform-cpp/proj.android

  • project.properties
target=android-10
=>
target=android-14

10だとAndroidManifest.xmlの定義の属性指定でエラーが出るはず*4

これちなみに

  • cocos2d-x-3.0alpha0 だと
target=android-13

だったんだけど、これデグレ


あと NDK_ROOTの設定の話があるんだけど

って話があって

  • local.properties
sdk.dir=/Users/xxxx/android-sdks
ndk.dir=/Users/xxxx/android-ndk-r9b

とか定義したものを用意して実行するほうが楽*5

で build_native.py を書き換えてみる*6

#!/usr/bin/python
# build_native.py
# Build native codes


from __future__ import with_statement
import sys
import os, os.path
import shutil

def load_properties_variables():
    d = {}

    with open('local.properties') as f:
        for line in f:
            tokens = line.split('=')
            if len(tokens) <2:
                continue
            d[tokens[0]] = '='.join(tokens[1:]).rstrip('\n')
            print ('%s, [%s]' % (tokens[0],d[tokens[0]]))

    try:
        NDK_ROOT = d['ndk.dir']
    except Exception:
        NDK_ROOT = None
    return NDK_ROOT

def check_environment_variables():
    ''' Checking the environment NDK_ROOT, which will be used for building
    '''
    NDK_ROOT = None
    NDK_ROOT = load_properties_variables()
    print ('[PROP]NDK_ROOT=[%s]' % NDK_ROOT)
    if NDK_ROOT != None:
        return NDK_ROOT
    
    try:
        NDK_ROOT = os.environ['NDK_ROOT']
    except Exception:
        print ('NDK_ROOT not defined. Please define NDK_ROOT in your environment')
        sys.exit(1)
    print ('[ENV]NDK_ROOT=[%s]' % NDK_ROOT)
    return NDK_ROOT

def select_toolchain_version():
    '''Because ndk-r8e uses gcc4.6 as default. gcc4.6 doesn't support c++11. So we should select gcc4.7 when
    using ndk-r8e. But gcc4.7 is removed in ndk-r9, so we should determine whether gcc4.7 exist.
    Conclution:
    ndk-r8e  -> use gcc4.7
    ndk-r9   -> use gcc4.8
    '''

    ndk_root = check_environment_variables()
    if os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.8")):
        os.environ['NDK_TOOLCHAIN_VERSION'] = '4.8'
        print ('The Selected NDK toolchain version was 4.8 !')
    elif os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.7")):
        os.environ['NDK_TOOLCHAIN_VERSION'] = '4.7'
        print ('The Selected NDK toolchain version was 4.7 !')
    else:
        print "Couldn't find the gcc toolchain."
        exit(1)

def do_build(cocos_root, ndk_root, app_android_root):

    ndk_path = os.path.join(ndk_root, "ndk-build")

    # windows should use ";" to seperate module paths
    platform = sys.platform
    if platform == 'win32':
        #ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos' % (cocos_root, cocos_root, cocos_root)
        ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos;%s/plugin/publish' % (cocos_root, cocos_root, cocos_root, cocos_root)
    else:
        #ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root)
        ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos:%s/plugin/publish' % (cocos_root, cocos_root, cocos_root, cocos_root)
        
    ndk_build_param = sys.argv[1:]
    if len(ndk_build_param) == 0:
        command = '%s -C %s %s' % (ndk_path, app_android_root, ndk_module_path)
    else:
        command = '%s -C %s %s %s' % (ndk_path, app_android_root, ' '.join(str(e) for e in ndk_build_param), ndk_module_path)
    os.system(command)

def copy_files(src, dst):

    for item in os.listdir(src):
        path = os.path.join(src, item)
        # Android can not package the file that ends with ".gz"
        if not item.startswith('.') and not item.endswith('.gz') and os.path.isfile(path):
            shutil.copy(path, dst)
        if os.path.isdir(path):
            new_dst = os.path.join(dst, item)
            os.mkdir(new_dst)
            copy_files(path, new_dst)

def copy_resources(app_android_root):

    # remove app_android_root/assets if it exists
    assets_dir = os.path.join(app_android_root, "assets")
    if os.path.isdir(assets_dir):
        shutil.rmtree(assets_dir)

    # copy resources
    os.mkdir(assets_dir)
    resources_dir = os.path.join(app_android_root, "../Resources")
    if os.path.isdir(resources_dir):
        copy_files(resources_dir, assets_dir)

def build():

    ndk_root = check_environment_variables()
    select_toolchain_version()

    current_dir = os.path.dirname(os.path.realpath(__file__))
    cocos_root = os.path.join(current_dir, "../../..")

    app_android_root = current_dir
    copy_resources(app_android_root)
    do_build(cocos_root, ndk_root, app_android_root)

# -------------- main --------------
if __name__ == '__main__':

    build()

改定)

の話があるようなので print()の形に修正。
一応 python 2.7/MountanLion環境では動作確認済



cocos2d-xの本で書いてる

らへんの話。ただこれはProjectごとに設定になるので毎回設定忘れするよりは良かも。



既存Project移行編)

  • plugin周り事前準備

pluginのビルド>
$COCOS2DX_ROOT/plugin/protocols/proj.android/jni

  • Application.mk
APP_ABI :=armeabi armeabi-v7a x86	#genymotionで使えるように指定を追加
#APP_ABI :=armeabi armeabi-v7a
APP_OPTIM := debug					#debug可能にする
APP_CFLAGS += -Wno-error=format-security #log関係の関数使用のworning無視
APP_PLATFORM := android-9 #1)

1)の設定対応


Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 9 in ./AndroidManifest.xml
らへんのワーニングが気になるため

  • コンソール
cd $COCOS2DX_ROOT/plugin/tools
./publish.sh

これADT18の頃からの話なんだけど未だに直ってないみたい

な話がありますよね。。
しかも 手動で XXX.jarとか通さないはず*7

  • build_native.py をコピー
  • build_native.pyを使うように設定を変更


    if platform == 'win32':
#       ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos' % (cocos_root, cocos_root, cocos_root)
        ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos;%s/plugin/publish' % (cocos_root, cocos_root, cocos_root, cocos_root)
    else:
#       ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root)
        ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos:%s/plugin/publish' % (cocos_root, cocos_root, cocos_root, cocos_root)

こちらは環境による

#   cocos_root = os.path.join(current_dir, "../../..")
    cocos_root = os.path.join(current_dir, "../../../..")

#        command = '%s -C %s %s %s' % (ndk_path, app_android_root, ' '.join(str(e) for e in ndk_build_param), ndk_module_path)
        command = '%s -C %s %s %s' % (ndk_path, app_android_root, '  '.join(str(e) for e in ndk_build_param), ndk_module_path)



旧来通りbuild_native.shを使いたい場合)

  • build_native.sh
COCOS2DX_ROOT="$DIR/../../.." 

#〜中略〜

#COCOS_AND_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt"
COCOS_AND_PATH="${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos/2d/platform/android"
# run ndk-build
if [[ "$buildexternalsfromsource" ]]; then
    echo "Building external dependencies from source"
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS_AND_PATH}"
else
    echo "Using prebuilt externals"
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS_AND_PATH}"
fi

COCOS2DX_ROOTの指定は環境による

#COCOS2DX_ROOT="$DIR/../../../"
COCOS2DX_ROOT="$DIR/../../../../"

pluginのpathまで入れるなら

PLUGIN_ROOT="$DIR/../../../plugin" 
COCOS2DX_ROOT="$DIR/../../.." 

#〜中略〜

PLUGIN_PATH=${PLUGIN_ROOT}/publish
#COCOS_AND_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt:${PLUGIN_PATH}"
COCOS_AND_PATH="${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos/2d/platform/android:${PLUGIN_PATH}"
# run ndk-build
if [[ "$buildexternalsfromsource" ]]; then
    echo "Building external dependencies from source"
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS_AND_PATH}"
else
    echo "Using prebuilt externals"
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS_AND_PATH}"
fi

あと直下にobjフォルダがあるとコンパイル誤爆するばあいは消してから実行すること

  • ndkgdb.sh (sample/TestCppあたりからもらってくる)
PLUGIN_ROOT="$DIR/../../../plugin" 
COCOS2DX_ROOT="$DIR/../../.." 

#〜中略〜


PLUGIN_PATH=${PLUGIN_ROOT}/publish
#COCOS_AND_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt:${PLUGIN_PATH}"
COCOS_AND_PATH="${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos/2d/platform/android:${PLUGIN_PATH}"

NDK_MODULE_PATH="${COCOS_AND_PATH} \
    "${NDK_ROOT}"/ndk-gdb-py \
    --adb="${SDK_ROOT}"/platform-tools/adb \
    --tui \
    --verbose \
    --launch=android.app.NativeActivity \
    --force \
    --nowait \
	$*

備考>
ちなみに JSB版のbuild_native.shだと

PARALLEL_BUILD_FLAG=\-j8

#〜略〜

"$NDK_ROOT"/ndk-build $PARALLEL_BUILD_FLAG -C "$APP_ANDROID_ROOT" $* \
   "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt" \
   NDK_LOG=0 V=0

な記載があるわけだけど,PARALLEL_BUILD_FLAG ってJSB専用なのかな?
JSB版のbuild_native.pyだとココらへんの指定は消えてるみたいだけど・・

NDK_LOG=0 V=0 に関してはJSだけでゴニョゴニョって方針が
JSBだから凄く理解はできるけど<でもPlugin連携時にハマると思う
その場合は

   NDK_LOG=0 V=0
#=>
   $*

あたりに書き換えとくといいのかな?とかと思ったりも*8



NDK Debugの指定)

で解決編でも指定してますが箇条書きしてみると下記のようになります

python ${ProjDirPath}/build_native.py NDK_DEBUG=1
  • jni/Application.mk
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 := all
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -ldl -llog
APP_PLATFORM := android-9
APP_OPTIM := debug
  • APP_ABI は1個のみ指定しないと Debug As/Native Applicationの実行に必要な


obj/local/armeabi-v7a/app_process
あたりが何故か生成されない。。これもGoogle様の考慮漏れなのかな(汗 *9
genymotionを使う場合は

APP_ABI := x86

を指定

LOCAL_PATH := $(call my-dir)
PROJECT_DIR := $(LOCAL_PATH)/../
# Android.mkからの相対位置なので1階層深い
COCOS2DX_ROOT := $(LOCAL_PATH)/../../../..

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
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos2dxandroid_static
LOCAL_WHOLE_STATIC_LIBRARIES += PluginProtocolStatic 

include $(BUILD_SHARED_LIBRARY)

# =======NativeApplication用のDebug記述(α0版)
#$(call import-add-path,$(COCOS2DX_ROOT))
#$(call import-add-path,$(COCOS2DX_ROOT)/cocos2dx)
#$(call import-add-path,$(COCOS2DX_ROOT)/cocos2dx/platform/third_party/android/prebuilt)
#$(call import-add-path,$(COCOS2DX_ROOT)/plugin/publish)

# =======NativeApplication用のDebug記述(現在版)
$(call import-add-path,$(COCOS2DX_ROOT))
$(call import-add-path,$(COCOS2DX_ROOT)/cocos)
$(call import-add-path,$(COCOS2DX_ROOT)/cocos/2d/platform/android)
$(call import-add-path,$(COCOS2DX_ROOT)/external)

$(call import-module,2d)
$(call import-module,audio/android)
#$(call import-module,Box2D)
$(call import-module,2d/platform/android)
$(call import-module,plugin/publish/protocols/android) 

# ========以前の設定============
#$(call import-module,cocos2dx)
#$(call import-module,cocos2dx/platform/third_party/android/prebuilt/libcurl)
#$(call import-module,CocosDenshion/android)
#$(call import-module,extensions)
#$(call import-module,external/Box2D)
  • call import-add-path に関しても

普通に ndkgdb.sh とかだとNDK_MODULE_PATHを指定してるものの代替ですから*10
NativeActivityの デバック実行に環境変数指定すれば 行けそうな気がする。。


備考)

  1. Debug As=>NativeApplication でエラーで実行できない時
    1. objフォルダがbuild時にうまく作成出来ない時にエラーが出ることが有り(clean & obj消しても改善されない場合)
    2. 一度実行してobjフォルダ作成
    3. Debug As=>NativeApplicationを再度実行する
  1. cocos2d-x の場合はいろんなモジュールをAndrod.mkしている
    1. モジュールによってはアドレス参照っぽくなってしまう状況は有り*11
  1. javaレイヤーとしてデバックする場合と、C++でデバックする場合は現在別実行するしか無い
    1. それでいてブレークポイントの箇所の表示がeclipse上では共有されてるのでカオス気味orz
  1. library-project等を更新してcleanするとfull-buildになってしまう。
    1. C++Projectだと Build-Automatically を外しておく チップスがよくあるが*12
    2. javaビルド前にC++ビルドが走るの仕組みは genmakerを設定している限り無理なので
      1. terminal(plugin)等経由で python build_native.py 等を事前に行っておいて再コンパイルコストを下げる

辺しか無いのか、コーディングスタイル的に考察が必要*13

  1. projectの最小構成


hoge
Classes //いじるソース
proj.android //Android用のプロジェクト
Resources //画像リソース
特に画像リソースに関しては

  1. コンパイル時にproj.android/assets の中身消去
  2. Resources => proj.android/assets にコピーするので、Resoucesに画像データを入れないと意味が無い*14

*1:plugin使わないならいらない

*2:editorのwarningがウザいのを消す為的な

*3:toolsの下は android update sdkの時に消されるので直下のほうがベターでした。修正<汗

*4:もちろんローカルにあるtargetのmax<19とか>を指定してもOK

*5:antとかもそうだし。

*6:load_properties_variables辺りを追加

*7:antで認識しない

*8:引数の指定がなければ、NDK_LOG=0 V=0 指定としたほうが多分既存の動きにはなると思う

*9:複数指定なんてそんな奴居ねーから使うやつ毎回指定しろよって感じ?

*10:他に設定を取得するすべがない??

*11:ここらへんは下の方もDEBUG指定するしか無いのかな?(汗

*12:じゃないとソース保存時にフルビルドかかるため

*13:cocos2d-xの本書いてる偉い人だと x-code開発せよ しか言わないorz

*14:一時期コレで悩んでた><