在cocos2d-x中使用luajit

来源:互联网 发布:淘宝保险 编辑:程序博客网 时间:2024/04/29 16:55

今天尝试了一下如何在cocos2d-x中使用luajit,发现cocos2d-x本身对luajit的支持还算不错,但是有一些地方做的还是不够完善,我的平台是linux,我不知道是不是平台的问题,也许mac上做的很完善,所以写下这往篇文章希望对在linux平台上开发cocos2d-x的同学有所帮助。

首先,为什么要用luajit呢?我能想到的原因有两个,一是效率,二是加密。用luajit之后执行效率会有很大的提升,特别是在android下,另外呢luajit之后得到的文件是二进制的bytecode,基本无法反编译,因此对于商业产品来说,提高了被反解的成本

那么luajit与lua到底有什么区别呢?从使用上来说没有区别,因为头文件都是一致的,所以将lua换成luajit来说,有两个步骤,一个是将头文件换成luajit的,另外一个是将动态链接库或者静态链接库也换成luajit的

开发平台:Ubuntu 13.04 64位

cocos2d-x:2.2.1

首先我们来看一下如何让cocos2d-x在linux平台上支持luajit

事实上在linux平台上cocos2d-x对于各模块均采用了动态链接来进行链接,因此我们可以单独处理luajit,而最后在Makefile里引用luajit

事实上对于linux平台来说cocos2d-x并没有支持luajit,大家可以查看${COCOS_ROOT}/scripting/lua/proj.linux

TARGET = liblua.soINCLUDES += -I.. -I../lua -I../tolua \        -I../Classes -I../../../CocosDenshion/include -I../../../extensions -I../../../external/chipmunk/include/chipmunkSOURCES = ../lua/lapi.o \          ../lua/lauxlib.c \          ../lua/lbaselib.c \          ../lua/lcode.c \          ../lua/ldblib.c \          ../lua/ldebug.c \          ../lua/ldo.c \          ../lua/ldump.c \          ../lua/lfunc.c \          ../lua/lgc.c \          ../lua/linit.c \          ../lua/liolib.c \          ../lua/llex.c \          ../lua/lmathlib.c \          ../lua/lmem.c \          ../lua/loadlib.c \          ../lua/lobject.c \          ../lua/lopcodes.c \          ../lua/loslib.c \          ../lua/lparser.c \          ../lua/lstate.c \          ../lua/lstring.c \          ../lua/lstrlib.c \          ../lua/ltable.c \          ../lua/ltablib.c \          ../lua/ltm.c \          ../lua/lundump.c \          ../lua/lvm.c \          ../lua/lzio.c \          ../lua/print.c \          ../tolua/tolua_event.c \          ../tolua/tolua_is.c \          ../tolua/tolua_map.c \          ../tolua/tolua_push.c \          ../tolua/tolua_to.c \          ../cocos2dx_support/tolua_fix.c \          ../cocos2dx_support/CCLuaBridge.cpp \          ../cocos2dx_support/CCLuaEngine.cpp \          ../cocos2dx_support/CCLuaStack.cpp \          ../cocos2dx_support/CCLuaValue.cpp \          ../cocos2dx_support/Cocos2dxLuaLoader.cpp \          ../cocos2dx_support/LuaCocos2d.cpp \          ../cocos2dx_support/CCBProxy.cpp \          ../cocos2dx_support/Lua_extensions_CCB.cpp \          ../cocos2dx_support/lua_cocos2dx_extensions_manual.cppinclude ../../../cocos2dx/proj.linux/cocos2dx.mkTARGET := $(LIB_DIR)/$(TARGET)SHAREDLIBS += -lextensionall: $(TARGET)$(TARGET): $(OBJECTS) $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_LINK)$(CXX) $(CXXFLAGS) $(OBJECTS) -shared -o $@ $(SHAREDLIBS) $(STATICLIBS)$(OBJ_DIR)/%.o: ../%.cpp $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_CXX)$(CXX) $(CXXFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@$(OBJ_DIR)/%.o: ../%.c $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_CC)$(CC) $(CCFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@

显然对于linux来说,直接使用了lua而非luajit,既然我们要使用luajit,那么有两种选择,一种是将这里Makefile里的lua全部换成luajit,另外一种是将这个Makefile里的lua部分删除,将一个so文件分成两个。因为对luajit不是很熟悉,所以我们采用第二种。新的Makefile文件如下

TARGET = liblua.soINCLUDES += -I.. -I../luajit/include -I../tolua \        -I../Classes -I../../../CocosDenshion/include -I../../../extensions -I../../../external/chipmunk/include/chipmunkSOURCES = ../tolua/tolua_event.c \          ../tolua/tolua_is.c \          ../tolua/tolua_map.c \          ../tolua/tolua_push.c \          ../tolua/tolua_to.c \          ../cocos2dx_support/tolua_fix.c \          ../cocos2dx_support/CCLuaBridge.cpp \          ../cocos2dx_support/CCLuaEngine.cpp \          ../cocos2dx_support/CCLuaStack.cpp \          ../cocos2dx_support/CCLuaValue.cpp \          ../cocos2dx_support/Cocos2dxLuaLoader.cpp \          ../cocos2dx_support/LuaCocos2d.cpp \          ../cocos2dx_support/CCBProxy.cpp \          ../cocos2dx_support/Lua_extensions_CCB.cpp \          ../cocos2dx_support/lua_cocos2dx_extensions_manual.cppinclude ../../../cocos2dx/proj.linux/cocos2dx.mkTARGET := $(LIB_DIR)/$(TARGET)SHAREDLIBS += -lextensionall: $(TARGET)$(TARGET): $(OBJECTS) $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_LINK)$(CXX) $(CXXFLAGS) $(OBJECTS) -shared -o $@ $(SHAREDLIBS) $(STATICLIBS)$(OBJ_DIR)/%.o: ../%.cpp $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_CXX)$(CXX) $(CXXFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@$(OBJ_DIR)/%.o: ../%.c $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_CC)$(CC) $(CCFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@

但是这样一来就没有luajit了,怎么办呢?当然需要编译一个libluajit.so出来了,这个其实很简单,在${COCOS_ROOT}/scripting/lua/luajit/LuaJIT-2.0.1

然后make就会在src下产生一下libluajit.so出来,只需要将这个文件拷贝到${COCOS_ROOT}/lib/linux/release以及${COCOS_ROOT}/lib/linux/debug下即可

到这里,其实已经将luajit准备好了,但是我们需要将工程里的Makefile文件进行一点小的修改,以${COCOS_ROOT}/samples/Lua/HelloLua为例

新的proj.linux/Makefile如下

EXECUTABLE = HelloLuaCOCOS_ROOT = ../../../..INCLUDES =  -I../ -I../Classes -I$(COCOS_ROOT)/CocosDenshion/include \    -I$(COCOS_ROOT)/scripting/lua/luajit/include \    -I$(COCOS_ROOT)/scripting/lua/tolua \    -I$(COCOS_ROOT)/scripting/lua/cocos2dx_support \    -I$(COCOS_ROOT)/extensions \SOURCES = main.cpp ../Classes/AppDelegate.cpp SHAREDLIBS += -lcocos2d -lcocosdenshion -llua -lluajit -lextensionCOCOS_LIBS = $(LIB_DIR)/libcocos2d.so $(LIB_DIR)/libcocosdenshion.so $(LIB_DIR)/liblua.so $(LIB_DIR)/libluajit.soinclude $(COCOS_ROOT)/cocos2dx/proj.linux/cocos2dx.mk$(TARGET): $(OBJECTS) $(STATICLIBS) $(COCOS_LIBS) $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_LINK)$(CXX) $(CXXFLAGS) $(OBJECTS) -o $@ $(SHAREDLIBS) $(STATICLIBS) $(LIBS)$(OBJ_DIR)/%.o: ../%.cpp $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_CXX)$(CXX) $(CXXFLAGS) $(INCLUDES) $(DEFINES) $(VISIBILITY) -c $< -o $@$(OBJ_DIR)/%.o: %.cpp $(CORE_MAKEFILE_LIST)@mkdir -p $(@D)$(LOG_CXX)$(CXX) $(CXXFLAGS) $(INCLUDES) $(DEFINES) $(VISIBILITY) -c $< -o $@

显然我们加了一个-lluajit以及${LIB_DIR}/libluajit.so,至此就可以在linux下使用了。


接下来我们看一下如何让cocos2d-x在android平台上支持luajit

事实上android下对luajit的支持相对较好,有一个shell文件来完成大部分编译的事情,${COCOS_ROOT}/scripting/lua/luajit/build_android.sh

但是这个文件有点小问题,一个是第5行SRCDIR=$DIR/LuaJIT-2.0.1原来是LuaJit,可能这个文件原来是在mac上写的,所以不区分大小写

另外一个是里面的一些命令没有使用arch,大家可以直接看最终版的文件如下

#!/bin/shDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"host_os=`uname -s | tr "[:upper:]" "[:lower:]"`arch_os=`uname -m | tr "[:upper:]" "[:lower:]"`SRCDIR=$DIR/LuaJIT-2.0.1cd "$SRCDIR"NDK=$NDK_ROOTNDKABI=8NDKVER=$NDK/toolchains/arm-linux-androideabi-4.7NDKP=$NDKVER/prebuilt/${host_os}-${arch_os}/bin/arm-linux-androideabi-NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"# Android/ARM, armeabi (ARMv5TE soft-float), Android 2.2+ (Froyo)DESTDIR=$DIR/android/armeabirm "$DESTDIR"/*.amake cleanmake HOST_CC="gcc -m32" CROSS=$NDKP TARGET_SYS=Linux TARGET_FLAGS="$NDKF"if [ -f $SRCDIR/src/libluajit.a ]; then    mv $SRCDIR/src/libluajit.a $DESTDIR/libluajit.afi;# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS)NDKARCH="-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8"DESTDIR=$DIR/android/armeabi-v7arm "$DESTDIR"/*.amake cleanmake HOST_CC="gcc -m32" CROSS=$NDKP TARGET_SYS=Linux TARGET_FLAGS="$NDKF $NDKARCH"if [ -f $SRCDIR/src/libluajit.a ]; then    mv $SRCDIR/src/libluajit.a $DESTDIR/libluajit.afi;# Android/x86, x86 (i686 SSE3), Android 4.0+ (ICS)NDKABI=14DESTDIR=$DIR/android/x86NDKVER=$NDK/toolchains/x86-4.7NDKP=$NDKVER/prebuilt/${host_os}-${arch_os}/bin/i686-linux-android-NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-x86"rm "$DESTDIR"/*.amake cleanmake HOST_CC="gcc -m32" CROSS=$NDKP TARGET_SYS=Linux TARGET_FLAGS="$NDKF"if [ -f $SRCDIR/src/libluajit.a ]; then    mv $SRCDIR/src/libluajit.a $DESTDIR/libluajit.afi;make clean

修改完成之后,我们可以直接执行./build_android.sh来生成android下用的.a文件

注:这一步如果报错,那就应该是你的编译环境的问题,而非是cocos2d-x的问题,我遇到的一个问题就是少了mulitlib库,所以如果大家在这一步报错

不妨仔细看一眼错误在说什么,然后按错误去google一把,来解决问题,因为这里的错误一般来说真不是cocos2d-x的问题

这一步完成之后,事实上android就直接换成luajit的了


因为土鳖没有mac机器,所以也不知道怎么换,这里就献丑了。


0 0