天天看點

android cocos2d-x for Android安裝和學習筆記(請用adt-bundle21.1或以上導入)

(20121108)注意:這篇文章用cdt編譯ndk工程的内容已過時(現在可以用adt-bundle,避免配置繁瑣的參數),最新版ADT 20.0.3支援右鍵把Android工程直接添加native特性(即Android工程和CDT Makefile工程合二為一),不需要做太多複雜的設定,而且完全相容ndk-build指令行編譯。當然,因為會執行完全編譯,是以如果經常clean,又想加快編譯速度,得另想方法。

(20130212)adt-bundle的導入方法文章最後

(20130314) adt-bundle 21.1貌似已修正.svn目錄導緻編譯失敗的bug

(TODO:内容未穩定)

一、安裝筆記

1. 下載下傳:

下載下傳官方的源碼包

<a href="http://code.google.com/p/cocos2d-x/downloads/list">http://code.google.com/p/cocos2d-x/downloads/list</a>

2. 建立示例工程:

因為官方沒有釋出編譯後的二進制檔案,是以要自己編譯。

下載下傳的cocos2d-1.0.1-x-0.13.0-beta.zip壓縮包裡根目錄有一個檔案叫create-android-project.bat。(還有個.sh字尾的檔案,它不能用cygwin運作)

如果直接運作的話可能會報錯,說某個目錄錯誤,需要用編輯器(我用的是notepad2)編輯,修改這幾個變量:

_CYGBIN:cygwin的bin目錄

_ANDROIDTOOLS:android sdk的tools目錄

_NDKROOT:ndk的根目錄

然後運作,根據提示輸入包名、工程名和API級别。

最後會生成一個以工程名命名的目錄,

3. 編譯.so檔案

生成的工程目錄有三個子目錄:

* android:特定于Android平台的工程檔案

* Classes:跨平台的C++源檔案和頭檔案

* Resources:公共的資源檔案(跨平台)

在cygwin下cd進去(切換到android子目錄中),然後執行

./build_native.sh

編譯JNI代碼。

編完後libs\armeabi下會出現一個1MB左右的libgame.so檔案

obj下會生成一堆中間.o檔案,應該是沒用的。

4. 編譯apk和安裝到手機

我事先用bat配置好ant的環境變量:

android cocos2d-x for Android安裝和學習筆記(請用adt-bundle21.1或以上導入)

@set PATH="C:\WINDOWS"  

@set PATH="C:\WINDOWS\system32";%PATH%  

@set PATH="D:\java\apache-ant-1.8.1\bin";%PATH%  

@set JAVA_HOME="D:\java\jdk1.6.0_20"  

@set PATH="D:\java\jdk1.6.0_20\bin";%PATH%  

@set PATH="D:\java\android-sdk_r10-windows\android-sdk-windows\platform-tools";%PATH%  

@set PATH="D:\java\android-sdk_r10-windows\android-sdk-windows\tools";%PATH%  

@cd /D "D:\java\android-sdk_r10-windows\android-sdk-windows\work"  

@cmd  

現在開始用ant編譯Android工程(先切換到build.xml的目錄中)

&gt; ant debug

(也可以執行ant release,可輸入ant檢視指令行用法)

生成bin\cocostest-debug.apk

然後用91或adb裝到手機上即可。

預設界面上隻有一張圖檔,一個Hello World字元串,一個fps值和一個退出按鈕。

android cocos2d-x for Android安裝和學習筆記(請用adt-bundle21.1或以上導入)

整個過程不需要導入到Eclipse中

二、參考

1. 如何在macox下面配置內建ios和android遊戲教程

<a href="http://www.cnblogs.com/andyque/archive/2012/02/23/2364163.html">http://www.cnblogs.com/andyque/archive/2012/02/23/2364163.html</a>

2. cocos2d-x初探學習筆記(1)--HelloWorld

<a href="http://blog.csdn.net/bill_man/article/details/7202458">http://blog.csdn.net/bill_man/article/details/7202458</a>

3. Cocos2D-X官網中文頁面

<a href="http://cn.cocos2d-x.org/">http://cn.cocos2d-x.org/</a>

-------------------------------

(2012/04/23更新)

三、獨立工具鍊的編譯(不編譯依賴庫)

(以下對于cocos2d-1.0.1-x-0.13.0-beta)

在(一)中最後會得到幾個.a檔案。如果不考慮那些庫檔案的編譯,整個.so的編譯過程是很簡單的。

在ndk-build後面添加V=1的方法打開Makefile的執行輸出,可以看到生成.so的關鍵指令是:

 寫道

arm-linux-androideabi-g++ -Wl,-soname,libgame.so -shared --sysroot=C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/platforms/android-8/arch-arm ./obj/local/armeabi/objs/game_shared/helloworld/main.o ./obj/local/armeabi/objs/game_shared/__/__/Classes/AppDelegate.o ./obj/local/armeabi/objs/game_shared/__/__/Classes/HelloWorldScene.o ./obj/local/armeabi/objs/game_shared/__/__/__/lua/cocos2dx_support/CCLuaEngine.o ./obj/local/armeabi/objs/game_shared/__/__/__/lua/cocos2dx_support/Cocos2dxLuaLoader.o ./obj/local/armeabi/objs/game_shared/__/__/__/lua/cocos2dx_support/LuaCocos2d.o ./obj/local/armeabi/objs/game_shared/__/__/__/lua/cocos2dx_support/tolua_fix.o -Wl,--whole-archive ./obj/local/armeabi/libcocos2dx.a ./obj/local/armeabi/libcocosdenshion.a ./obj/local/armeabi/libbox2d.a ./obj/local/armeabi/liblua.a ./obj/local/armeabi/png.a ./obj/local/armeabi/jpeg.a ./obj/local/armeabi/xml2.a -Wl,--no-whole-archive ./obj/local/armeabi/libgnustl_static.a C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a -Wl,--no-undefined -Wl,-z,noexecstack -LC:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/platforms/android-8/arch-arm/usr/lib -llog -lz -lGLESv1_CM -llog -lc -lm -o obj/local/armeabi/libgame.so

如果不考慮lua/cocos2dx_support下的.o檔案,而且假設.a檔案已經編譯好,那麼可以簡化為以下Makefile(頭檔案目錄進行了調整,而且因為我對ndk的工具鍊目錄也作了調整,是以不需要添加--sysroot開關)

android cocos2d-x for Android安裝和學習筆記(請用adt-bundle21.1或以上導入)

CC := arm-linux-androideabi-gcc  

CPP := arm-linux-androideabi-g++  

LD := arm-linux-androideabi-ld  

STRIP := arm-linux-androideabi-strip  

RM := rm -rf  

CPPFLAGS := -g  

CPPFLAGS += -DANDROID -I../Classes -I../cocos2dx -I../cocos2dx/include -I../cocos2dx/platform  

LDFLAGS := -shared  

LIBS := -Wl,--whole-archive ../cocos2dx/lib/libcocos2dx.a ../cocos2dx/lib/png.a ../cocos2dx/lib/jpeg.a ../cocos2dx/lib/xml2.a -Wl,--no-whole-archive ../cocos2dx/lib/libgnustl_static.a -Wl,--no-undefined -Wl,-z,noexecstack -llog -lz -lGLESv1_CM -llog -lc -lm  

TARGET := libs/armeabi/libgame.so  

OBJS := jni/helloworld/main.o   

OBJS += ../Classes/AppDelegate.o   

OBJS += ../Classes/HelloWorldScene.o  

all : $(TARGET)  

$(TARGET) : $(OBJS)  

    $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@  

    $(STRIP) --strip-unneeded $(TARGET)   

%.o : %.cpp  

    $(CPP) $(CPPFLAGS) -o $@ -c $&lt;  

clean :  

    $(RM) $(OBJS) $(TARGET)  

可以看到,實際上需要編譯的源檔案隻有三個:

Android/jni/helloworld/main.cpp 

Classes/AppDelegate.cpp 

Classes/HelloWorldScene.cpp

四、CDT配置

1. 修改CDT工程屬性

假設

(1) 已編譯好的所有.a檔案:

libcocos2dx.a

png.a

jpeg.a

xml2.a

libgnustl_static.a

已經複制到

G:/weimingtom_tools/android-ndk-r5b/home/Administrator/cocos2d-x/cocos2dx/lib/

目錄中。

(2) NDK目錄在

C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b

(3) Android工程的libs\armeabi目錄在子目錄

android\libs\armeabi

(4) cocos2dx源碼在

C:\cygwin\home\Administrator\android-ndk-r7b-windows\android-ndk-r7b\cocos2d

首先在C/C++ build-&gt;Configureation:中選擇[All configurations],

然後設定以下内容(清單框支援直接粘貼)

(1) New:

C++ Project-&gt;Shared Library-&gt;Cross-Compile Project

(2) Prefix:

arm-linux-androideabi-

(3) Path:

C:\cygwin\home\Administrator\android-ndk-r7b-windows\android-ndk-r7b\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin

(4) Text file encoding:

UTF-8

(5) Make:

C:\cygwin\home\Administrator\android-ndk-r7b-windows\android-ndk-r7b\prebuilt\windows\bin\make

(6) G++ Defined symbols:

ANDROID

(7) G++ Include path:

"C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/platforms/android-8/arch-arm/usr/include"

"C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/sources/cxx-stl/gnu-libstdc++/include"

"C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include"

"C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/cocos2d/cocos2dx"

"C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/cocos2d/cocos2dx/include"

"C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/cocos2d/cocos2dx/platform"

${workspace_loc:/${ProjName}/Classes}

(8) G++ Lib:

log

z

GLESv1_CM

c

m

(9) G++ Lib path:

"C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/platforms/android-8/arch-arm/usr/lib"

(10) -Wl,-soname=

libgame.so

(11) Artifact name:

game

(12) G++ linker linker flags

--sysroot="C:/cygwin/home/Administrator/android-ndk-r7b-windows/android-ndk-r7b/platforms/android-8/arch-arm"

(13) Expert settings:

Command line pattern:

${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} -Wl,--whole-archive "G:/weimingtom_tools/android-ndk-r5b/home/Administrator/cocos2d-x/cocos2dx/lib/libcocos2dx.a" "G:/weimingtom_tools/android-ndk-r5b/home/Administrator/cocos2d-x/cocos2dx/lib/png.a" "G:/weimingtom_tools/android-ndk-r5b/home/Administrator/cocos2d-x/cocos2dx/lib/jpeg.a" "G:/weimingtom_tools/android-ndk-r5b/home/Administrator/cocos2d-x/cocos2dx/lib/xml2.a" -Wl,--no-whole-archive "G:/weimingtom_tools/android-ndk-r5b/home/Administrator/cocos2d-x/cocos2dx/lib/libgnustl_static.a" -Wl,--no-undefined -Wl,-z,noexecstack ${INPUTS}

(14)Build Steps-&gt;Post-build steps-&gt;Command:

arm-linux-androideabi-strip --strip-unneeded libgame.so &amp;&amp; copy libgame.so ..\android\libs\armeabi

2. 如果修改了配置,錯誤提示仍然沒有改變,可嘗試:

工程-&gt;右鍵-&gt;Index-&gt;Rebuild

工程-&gt;右鍵-&gt;Refresh

直至錯誤完全消失

3. 編譯libgame.so

工程-&gt;右鍵-&gt;Build Configurations-&gt;Set Active選擇Debug還是Release

然後Clean Project, Build Project

4. 編譯apk

&gt; cd /d C:\Documents and Settings\Administrator\workspace_indigo_sr2\cocostest\android

&gt; ant clean debug install

我喜歡CDT的原因是它支援方法提示、錯誤警告跳轉和定義跳轉,但調試功能沒有Qt Creator強。如圖所示:

android cocos2d-x for Android安裝和學習筆記(請用adt-bundle21.1或以上導入)
android cocos2d-x for Android安裝和學習筆記(請用adt-bundle21.1或以上導入)
android cocos2d-x for Android安裝和學習筆記(請用adt-bundle21.1或以上導入)

 ----------------------------------------

 (20130212更新)

在adt-bundle-x86 r21.0.1上導入cocos2dx工程

(基于cocos2d-2.1beta3-x-2.1.1和android-ndk-r7b-windows,

假設已經建立好helloworld工程)

(工程建立方法是修改create-android-project.bat,然後執行它,和cocos2dx的舊版本的建立方法差不多)

1. 下載下傳解壓adt-bundle

https://developer.android.com/sdk/index.html

然後運作adt-bundle-windows-x86\eclipse\eclipse.exe

2. window-&gt;Preferences-&gt;Android-&gt;NDK填寫安裝NDK安裝根目錄,例如:

C:\cygwin\home\Administrator\android-ndk-r7b-windows\android-ndk-r7b

3. 右鍵-&gt;Import...-&gt;Android-&gt;Existing Android Code Into Workspace

4. 右鍵-&gt;Android Tools-&gt;Add Native Support...

5. 右鍵-&gt;Properties-&gt;C/C++ Build-&gt;Environment

假設cocos2dx安裝根目錄為C:/cygwin/home/Administrator/cocos2d-2.1beta3-x-2.1.1

添加環境變量NDK_MODULE_PATH為

C:/cygwin/home/Administrator/cocos2d-2.1beta3-x-2.1.1;C:/cygwin/home/Administrator/cocos2d-2.1beta3-x-2.1.1/cocos2dx/platform/third_party/android/prebuilt

(用分号隔開)

修改環境變量PATH為空字元串

6. 主菜單-&gt;Project-&gt;Clean...

7. 主菜單-&gt;Project-&gt;Build All...

(如果出現錯誤,可能需要:項目右鍵-&gt;Index-&gt;Rebuild)

8. 檢查是否生成libs/armeabi/libgame.so

注意事項:

1. 部分Java代碼在

cocos2dx安裝根目錄\cocos2dx\platform\android\java目錄下

如果編譯器支援Android庫工程有問題(例如Windows舊版本的adt),可直接把java源檔案複制到工程中。

2. 如果執行Build All時出現

/usr/bin/sh: -c: line 1: syntax error: unexpected end of file

make: *** [libs/armeabi/libgame.so] Error 1

make: *** Deleting file `libs/armeabi/libgame.so'

可能是由于ndk-build編譯時環境變量不同造成

請環境變量PATH設定為空字元串(見上面第5步)

3. 如果用指令行,相當于在proj.android目錄下執行:

set NDK_MODULE_PATH=C:/cygwin/home/Administrator/cocos2d-2.1beta3-x-2.1.1;C:/cygwin/home/Administrator/cocos2d-2.1beta3-x-2.1.1/cocos2dx/platform/third_party/android/prebuilt

C:\cygwin\home\Administrator\android-ndk-r7b-windows\android-ndk-r7b\ndk-build.cmd 

(可以寫一個bat檔案放在proj.android目錄下執行)

 (20130313補充)

4. Resources下的圖檔需複制到proj.android\assets下,否則會彈對話框報錯

5. 如果不考慮跨平台,可以把Classes目錄移動到proj.android\Classes

然後把Android.mk中的../../Classes改為../Classes

項目右鍵-&gt;Properties-&gt;C/C++ General-&gt;Path and Symbols-&gt;Source Location添加Classes目錄

以友善用adt-bundle修改源代碼

6. 出現錯誤:Errors running builder 'Android Pre Compiler' on project…無法編譯和運作工程

參考:http://stackoverflow.com/questions/14455018/eclipse-android-errors-running-builder-android-pre-compiler-on-project

Open properties of project in Eclipse then Resources -&gt; Resource filters.

Click the "Add..." button -&gt; Check "Exclude all", "Files and folders", "All children". In the text entry box input ".svn" (without quotes).

Restart Eclipse.

原因是舊版本的adt-bundle不支援.svn檔案的忽略

解決辦法是:

右鍵屬性-&gt;Resources -&gt; Resource filters

點選add按鈕

勾選"Exclude all", "Files and folders", "All children"

文本框中填入.svn

然後重新開機Eclipse,重新編譯

 (或更新至最新版本的adt-bundle)

7. 新版本cocos2dx貌似隻支援gles 2.0的裝置,是以模拟器似乎不能運作(反正模拟器跑得很慢)。

(20130325)

windows上遊戲demo例子(基于舊版本):

https://code.google.com/p/android-app-examples/

-------------------------------------------------------

(以下内容未實踐驗證,僅記錄備忘)

(20130402)

1. jni目錄中二級目錄的Android.mk配置:(參考自https://github.com/eric-h/ObjLoader)

* 頂級目錄的Android.mk:

LOCAL_PATH := $(call my-dir)

include $(call all-subdir-makefiles)

* 次級目錄的Android.mk:(最後一行的include,對于jni入口用BUILD_SHARED_LIBRARY,對于庫用BUILD_STATIC_LIBRARY)

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

...(變量指派,以下是按順序排列的設定指定)

include $(BUILD_SHARED_LIBRARY)

#include $(BUILD_STATIC_LIBRARY)

* 修改LOCAL_PATH(不推薦,建議不要使用,放在include $(CLEAR_VARS)前的第一行)

LOCAL_PATH := $(realpath $(call my-dir)/..)

* 非标準的指定靜态庫(Android.mk所在目錄與jni入口的Android.mk不平行。放在所有編譯變量的指派前。不建議,因為include的mk檔案的内容不是以LOCAL_PATH := $(call my-dir)開頭)

include $(ENGINEDIR)/src/zlib/Android.mk

* 指定輸出檔案名:

LOCAL_MODULE := libapp

LOCAL_MODULE_FILENAME:= libapp(此項非必須)

* 指定編譯用檔案(可以是cpp或c檔案)和編譯參數:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../(多用于include $(BUILD_SHARED_LIBRARY)所在的Android.mk)

LOCAL_CFLAGS := -Werror -Wall -O4(此項非必須)

LOCAL_SRC_FILES := app.cpp 

* 條件編譯參數:

ifeq ($(TARGET_ARCH_ABI),x86)

LOCAL_CFLAGS += -fno-stack-protector 

endif

* 指定靜态庫:(多用于include $(BUILD_SHARED_LIBRARY)所在的Android.mk)

LOCAL_STATIC_LIBRARIES := libobj libzip libpng

(需要注意次序,被依賴的庫放在最後,例如A依賴于B,那麼LOCAL_STATIC_LIBRARIES :=  A  B)

* 指定動态庫:(一般放在所有變量指派的最後)

LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog -lz(此項非必須)

2. jni目錄中Application.mk配置:

* 全局的編譯參數:

APP_STL := gnustl_static(多數情況用stlport_static)

APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1

* 打開vfp編譯開關-march=armv6 -mcpu=generic-armv6 -mfloat-abi=softfp

(見http://stackoverflow.com/questions/13870691/android-ndk-armv6-vfp-devices-wrong-calculations-nan-denormal-numbers-vfp)

或用github搜尋-mfloat-abi=softfp(在Makefile分類中的Application.mk裡)

* 交叉編譯的目标機器類型和Android版本号(參考自https://code.google.com/p/orange-grass/source/browse/trunk/jni/Application.mk)

APP_PLATFORM := android-10(注意,不同平台所支援的系統jni接口有所不同,由系統的c/c++頭檔案限制。預設貌似是讀取AndroidMenifest.xml的版本号?這個變量通常是預設不寫的)

APP_ABI := armeabi(多數情況用armeabi,也可以指定all來編譯目前ndk支援的所有cpu架構類型,或者指定x86,armeabi和armeabi-v7a其中的若幹個)

(20130411)

3. 同一個Android.mk編譯多個目标(同時編譯依賴的靜态庫和jni動态庫)(适用于隻有一個依賴庫的情況)

(參考自:https://github.com/kenhys/zinnia-android/tree/master/jni)

#####

LOCAL_MODULE    := libzinnia

LOCAL_SRC_FILES := character.cpp feature.cpp libzinnia.cpp param.cpp recognizer.cpp sexp.cpp svm.cpp trainer.cpp

LOCAL_CFLAGS    := -Werror -DHAVE_CONFIG_H

include $(BUILD_STATIC_LIBRARY)

# JNI

LOCAL_MODULE    := libzinniajni

LOCAL_SRC_FILES := libzinniajni.cpp

LOCAL_STATIC_LIBRARIES := libzinnia

4. 導出變量(用于靜态庫)

LOCAL_EXPORT_C_INCLUDES

LOCAL_EXPORT_LDLIBS

(20130530)

5. 擷取簽名字元串(GetMethodID的第四參數)

cd bin/classes

javap -s -private &lt;類名全稱&gt;

例如

private void progress(long size, long timestamp, double duration)

的簽名是:

(JJD)V

則在JNI中擷取該方法:

jmethodID progress = (*env)-&gt;GetMethodID(env, cls, "progress", "(JJD)V");

在JNI中調用(因為傳回值為void,是以使用CallVoidMethod):

(*env)-&gt;CallVoidMethod(env, obj, progress, size, timestemp, duration);

參數中使用的在JNI中局部建立的對象(JNI局部引用)需要在調用後釋放,例如:

(*env)-&gt;CallVoidMethod(env, obj, log, result);

(*env)-&gt;DeleteLocalRef(env, result);

(*env)-&gt;DeleteLocalRef(env, stringClass);

否則可能有堆棧崩潰的危險。

(TODO:待補充)