将cocos2dx里的lua升级至5.3

由于项(ge)目(ren)需(xing)要(qu),决定将项目的代码升级到最新的5.3.0版,源码点这下载

由于cocos2d-x是个跨平台项目,所以要分别对windows,android,ios三个环境均要做一定修改。而由于cocos2d-x默认是使用luajit的,而最新的luajit并不支持Lua5.3,所以作为代价就是放弃jit带来的效率提升,然而这个对我们的项目其实并没有什么影响(游戏玩法决定不需要太注重效率)

windows:
1.添加源代码。这里我就不采用库的形式了,直接将源码写进去,也方便调试。进入工程设置,将lua的源码全部添加到liblua这个工程里,并最好是为他建立一个filter。

2.修改工程属性。将include依赖里的$(EngineRoot)external\lua\luajit\include 改为放置lua代码的地址,比如我的是:$(EngineRoot)external\lua\lua,然后将引用的lua51.lib库去掉。

3.API修改。由于5.3对Lua进行了较大改动,所以API变动比较大,幸运的是作者提供了向上兼容的宏,所以这里我们只要往工程里加入LUA_COMPAT_5_1
和LUA_COMPAT_APIINTCASTS 这两个宏定义即可。但是有个比较麻烦的就是tolua++因为里头用到的一些API似乎并没有看到,所以这里还是需要对tolua++的一些源码进行修改,这里列出修改内容如下:

Index: tolua_event.c
...
static void storeatubox (lua_State* L, int lo)
{
#ifdef LUA_VERSION_NUM
#if LUA_VERSION_NUM > 501
lua_getuservalue(L, lo);
#else
lua_getfenv(L, lo);
#endif
if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
lua_pop(L, 1);
lua_newtable(L);
lua_pushvalue(L, -1);
#if LUA_VERSION_NUM > 501
lua_setuservalue(L, lo); /* stack: k,v,table */
#else
lua_setfenv(L, lo); /* stack: k,v,table */
#endif
...
static int class_index_event (lua_State* L)
{
int t = lua_type(L,1);
if (t == LUA_TUSERDATA)
{
/* Access alternative table */
#ifdef LUA_VERSION_NUM /* new macro on version 5.1 */
#if LUA_VERSION_NUM > 501
lua_getuservalue(L, 1);
#else
lua_getfenv(L,1);
#endif
...
TOLUA_API int class_gc_event (lua_State* L)
{
void* u = NULL;
int top;
if (!lua_isuserdata(L, 1)) return 0;
u = *((void**)lua_touserdata(L,1));

...

Index: tolua_map.c
===================================================================
--- tolua_map.c (revision 19)
+++ tolua_map.c (working copy)
@@ -275,7 +275,11 @@
lua_pop(L, 1);
lua_pushvalue(L, TOLUA_NOPEER);
};
- lua_setfenv(L, -2);
+#if LUA_VERSION_NUM > 501
+ lua_setuservalue(L, -2);
+#else
+ lua_setfenv(L, -2);
+#endif

return 0;
};
@@ -283,7 +287,11 @@
static int tolua_bnd_getpeer(lua_State* L) {

/* stack: userdata */
- lua_getfenv(L, -1);
+#if LUA_VERSION_NUM > 501
+ lua_getuservalue(L, -1);
+#else
+ lua_getfenv(L, -1);
+#endif
if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
lua_pop(L, 1);
lua_pushnil(L);
@@ -448,7 +456,11 @@
lua_rawget(L,-2);
}
else
- lua_pushvalue(L,LUA_GLOBALSINDEX);
+#if LUA_VERSION_NUM > 501
+ lua_pushglobaltable(L);
+#else
+ lua_pushvalue(L,LUA_GLOBALSINDEX);
+#endif
}

/* End module
@@ -482,7 +494,11 @@
else
{
/* global table */
- lua_pushvalue(L,LUA_GLOBALSINDEX);
+#if LUA_VERSION_NUM > 501
+ lua_pushglobaltable(L);
+#else
+ lua_pushvalue(L,LUA_GLOBALSINDEX);
+#endif
}
if (hasvar)
{
Index: tolua_push.c
===================================================================
--- tolua_push.c (revision 19)
+++ tolua_push.c (working copy)
@@ -51,10 +51,13 @@
/*luaL_getmetatable(L,type);*/
lua_pushvalue(L, -2); /* stack: mt newud mt */
lua_setmetatable(L,-2); /* update mt, stack: mt newud */
-
-#ifdef LUA_VERSION_NUM
- lua_pushvalue(L, TOLUA_NOPEER); /* stack: mt newud peer */
- lua_setfenv(L, -2); /* stack: mt newud */
+
+#if (LUA_VERSION_NUM > 501)
+ lua_pushvalue(L, TOLUA_NOPEER); /* stack: mt newud peer */
+ lua_setuservalue(L, -2); /* stack: mt newud */
+#else
+ lua_pushvalue(L, TOLUA_NOPEER); /* stack: mt newud peer */
+ lua_setfenv(L, -2); /* stack: mt newud */
#endif
}
else

那么windows平台的就已经全部搞定了,可以放心编译了。

Android:
在做完上述的步骤之后,接下来是对Android下面的mk文件进行修改了。
1.首先找到cocos2d-x\cocos\scripting\lua-bindings\Android.mk,对其修改如下:

Index: scripting/lua-bindings/Android.mk
===================================================================
--- scripting/lua-bindings/Android.mk (revision 19)
+++ scripting/lua-bindings/Android.mk (working copy)
@@ -39,6 +39,40 @@
auto/lua_cocos2dx_physics_auto.cpp \
auto/lua_cocos2dx_experimental_auto.cpp \
auto/lua_cocos2dx_experimental_video_auto.cpp \
+ ../../../external/lua/lua/lapi.c \
+ ../../../external/lua/lua/lauxlib.c \
+ ../../../external/lua/lua/lbaselib.c \
+ ../../../external/lua/lua/lbitlib.c \
+ ../../../external/lua/lua/lcode.c \
+ ../../../external/lua/lua/lcorolib.c \
+ ../../../external/lua/lua/lctype.c \
+ ../../../external/lua/lua/ldblib.c \
+ ../../../external/lua/lua/ldebug.c \
+ ../../../external/lua/lua/ldo.c \
+ ../../../external/lua/lua/ldump.c \
+ ../../../external/lua/lua/lfunc.c \
+ ../../../external/lua/lua/lgc.c \
+ ../../../external/lua/lua/linit.c \
+ ../../../external/lua/lua/liolib.c \
+ ../../../external/lua/lua/llex.c \
+ ../../../external/lua/lua/lmathlib.c \
+ ../../../external/lua/lua/lmem.c \
+ ../../../external/lua/lua/loadlib.c \
+ ../../../external/lua/lua/lobject.c \
+ ../../../external/lua/lua/lopcodes.c \
+ ../../../external/lua/lua/loslib.c \
+ ../../../external/lua/lua/lparser.c \
+ ../../../external/lua/lua/lstate.c \
+ ../../../external/lua/lua/lstring.c \
+ ../../../external/lua/lua/lstrlib.c \
+ ../../../external/lua/lua/ltable.c \
+ ../../../external/lua/lua/ltablib.c \
+ ../../../external/lua/lua/ltm.c \
+ ../../../external/lua/lua/lua.c \
+ ../../../external/lua/lua/lundump.c \
+ ../../../external/lua/lua/lutf8lib.c \
+ ../../../external/lua/lua/lvm.c \
+ ../../../external/lua/lua/lzio.c \
../../../external/lua/tolua/tolua_event.c \
../../../external/lua/tolua/tolua_is.c \
../../../external/lua/tolua/tolua_map.c \
@@ -59,11 +93,18 @@
../../../external/lua/luasocket/udp.c \
../../../external/lua/luasocket/unix.c \
../../../external/lua/luasocket/usocket.c \
../../../external/xxtea/xxtea.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../external/lua/tolua \
- $(LOCAL_PATH)/../../../external/lua/luajit/include \
+ $(LOCAL_PATH)/../../../external/lua/lua \
$(LOCAL_PATH)/../../../external/lua \
$(LOCAL_PATH)/../../../extensions \
$(LOCAL_PATH)/../../editor-support/spine \
@@ -80,7 +121,7 @@

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../external/lua/tolua \
- $(LOCAL_PATH)/../../../external/lua/luajit/include \
+ $(LOCAL_PATH)/../../../external/lua/lua \
$(LOCAL_PATH)/../external \
$(LOCAL_PATH)/auto \
$(LOCAL_PATH)/manual
@@ -96,11 +137,13 @@
LOCAL_WHOLE_STATIC_LIBRARIES += spine_static

LOCAL_CFLAGS += -Wno-psabi
-LOCAL_EXPORT_CFLAGS += -Wno-psabi
+LOCAL_CFLAGS += -DLUA_COMPAT_5_1
+LOCAL_CFLAGS += -DLUA_COMPAT_APIINTCASTS
+LOCAL_EXPORT_CFLAGS += -DLUA_COMPAT_5_1
+LOCAL_EXPORT_CFLAGS += -DLUA_COMPAT_APIINTCASTS

include $(BUILD_STATIC_LIBRARY)

-$(call import-module,lua/luajit/prebuilt/android)
$(call import-module,extensions)
$(call import-module,.)
$(call import-module,websockets/prebuilt/android)

那么Android下的配置也就完成了。

iOS:
lua-binding工程:
1. 将lua的源码文件加入工程里,同时在Build Phases 里的Compile Sources也添加上。
2. 把Build Phases 里的Link Binary With Libraries里的liblua.a删掉,同时将工程Linking里的Other Librarian Flags里的-llua删除掉。
3. 在Apple LLVM 6.1 = Preprocessing 的 Preprocessor Macros 里添加LUA_COMPAT_5_1和LUA_COMPAT_APIINTCASTS 这两个宏定义。

游戏本身工程:
1. 将游戏工程里的include依赖external\lua\luajit\include改为我们要的,这里我没找到设置,直接打开project.pbxproj用文本编辑器查找修改。

OK,iOS下的配置也完成了。

搞定收工!

发表评论

电子邮件地址不会被公开。