zoukankan      html  css  js  c++  java
  • SLua 中使用 Lua 5.3 的编译工程

    2016-03-05 更新:

    之前编译的库,在 Android 下 Lua_Number 和 Lua_Integer 被编译为了32位,导致从 C# 到 Lua 过程中有64位到32位整型转换会出现溢出出错,出现异常大的负整数。

    以下修改或是之前遗漏的部分均使用红色表示。


    2016-11-21 更新:

    之前编译的库都是用的是 32位的 NDK(当时vs2015还不支持最新的64位ndk),如果你是用64位的 NDK 编译请注意兼容性问题;其二请注意安卓打包的库目录问题,安卓库 "libs"目录下对应于不同的cpu目录:

    ARM 32: "armeabi-v7a"

    ARM 64: "arm64-v8a"

    x86 32: "x86"

    x86 64: "x86_64"


      我们项目将 SLua 中的 Lua 核心升级为了 5.3.2,添加了 LPeg 和 sproto(和服务器兼容)。

    整个工程直接分别创建了 Mac 和 IOS 的 XCode 工程,以及 Windows 和 Android 的 VS2015工程,vs 支持 clang 和 gcc 后,可以直接创建 Android NDK 工程。

      安装 vs2015 的过程中,可以选择安装 Android 的支持,但是 NDK 以及其他工具的安装需要从谷歌下载,会导致这些组件安装失败,所以只能安装完成后,手动安装 NDK。

      vs2015 只支持 NDK r10e 32位,使用更高版本将无法使用 clang,因为 vs2015默认且只支持 clang 3.6,具体请阅读这里。各个 Android 需求工具的安装默认路径,请参考这里

      一个简单的办法是:将下载好的 NDK 放置在:“C:ProgramDataMicrosoftAndroidNDK”,或其他地方,然后修改注册表:“HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftVisualStudio14.0SetupVSSecondaryInstallerAndroidNDK”(没有则新建),然后新建项:“NDK_HOME”,设置值为 NDK 的安装路径即可完成。再次编译 NDK 工程则不会出现 "NDK_ROOT" 未定义的情况。

      最简单的办法是:在安装时不勾选 Android SDK,NDK,自己单独下载,安装 vs2015 完毕后,在 工具 -> 选项 -> Cross Platform -> C++ -> Android 一栏修改路径即可。

      使用 vs2015 编译 Android 版本 slua 需要注意的几个地方:

    • 目前主流的 ARM 处理器都是带浮点处理单元的,即:“armeabi-v7a”,需要在 ARM 架构的配置中加入宏定义:“__ARM_ARCH_7A__”(实际在 vs2015 中编译的最低版本也是 armv7,不显式指定此宏也可以)
    • 目前 支持 c99 的 NDK 至少为:“Jelly Bean 4.3.x,(android-18)”(属性页中的目标 API 级别),如果想兼容更低版本的 api,需要添加宏定义:“LUA_USE_C89”,否则会出现 error : undefined reference to 'log2' 错误,(属性页-> C/C++ -> 语言 -> C语言标准,不需要设置成 -std=c89,保持默认值:“默认”,可能依然导致编译错误。);(此处注意:一旦使用 LUA_USE_C89,那么 Lua_Number 和 Lua_Integer 就会被编译为32位,具体请参考 luaconf.h 中的代码,slua 中 lua_pushinteger 导出接口的定义默认使用的是 Int64,所以存在一个类型转换和溢出问题,你会发现无论你怎么调用 lua_pushinteger 到了 lua 端,数据都是错的,很可能是一个大的负整数,这就是我找了好几天才发现的错误,一个大坑。当然,你也可以在 slua 的 luadll.cs 中将 lua_pushinteger 导出接口的定义改为 Int32 应该也能修复,不过我没有试验并强烈建议使用 64 位整形的 Lua。)(2017-07-09更新:后来查看了 XLua 的工程编译并知道了,其实 log2 是 c99 的新函数,在 c98 中 lua 是通过两步运算模拟的,c99 中直接使用 log2 运算效率更高,所以如果为了支持 Android api 更低级别,只需要删除 math_log 中
      #if !defined(LUA_USE_C89)
          if (base == 2.0) res = l_mathop(log2)(x); else
      #endif

      这一小段代码即可,影响就是在 log2 的运算中,效率稍低,但是兼容性更好了。)

    • 可能编译 Lua 会出现错误:error : no member named 'decimal_point' in 'struct lconv',你可以修改 luaconf.h 中将
      #define lua_getlocaledecpoint()        (localeconv()->decimal_point[0])

      修改为:

      #define lua_getlocaledecpoint()        ('.')

      但是这样修改了源文件会影响其他平台,所以更好的方式是,在工程属性页 -> C/C++ -> 命令行 -> 其他选项 中加入:-D "lua_getlocaledecpoint()=('.')" ,(引号也是内容一部分),这样修改仅限于 Android 平台编译;

    • 如果出现各种连接错误:error : undefined reference to 'xxx',xxx 为各种数学函数 sin, cos 等等,需要给连接器增加 -lm 选项,动态查找链接接口:工程属性页 -> 链接器 -> 命令行 -> 其它选项 中加入:-lm 即可。
    • 同时需要在工程 Debug 配置中加入宏定义:"LPEG_DEBUG"
    • Mac 版本编译 Debug 版本,由于代码的一些书写(函数定义和使用)不符合 c99 书写标准,需要修改才能编译通过;
    • Mac 版本编译的额外链接选项 Other Linker Flags 需要加入:“-undefined dynamic_lookup”;
    • 默认 Lua 的异常使用 longjmp,如果编译为 c++ 会自动转换为 try-catch,如果在c++工程中编译 c 代码,由于已经定义 _cplusplus,LUAI_THROW 会被展开为 try,出现编译错误的话可以考虑添加宏:LUA_USE_LONGJMP。

      编译工程 SLua + Lua 5.3.2 + LPeg 1.0.0 + sproto 的 GitHub 地址:https://github.com/yaukeywang/slua-503-build

      后续:由于 premake5 目前对 vs2015 的支持还不完整,打算利用业余时间扩展 premake5,同时将改工程修改为 premake5 工程并提交到 github。

  • 相关阅读:
    LeetCode "Median of Two Sorted Arrays"
    LeetCode "Distinct Subsequences"
    LeetCode "Permutation Sequence"

    LeetCode "Linked List Cycle II"
    LeetCode "Best Time to Buy and Sell Stock III"
    LeetCode "4Sum"
    LeetCode "3Sum closest"
    LeetCode "3Sum"
    LeetCode "Container With Most Water"
  • 原文地址:https://www.cnblogs.com/yaukey/p/slua-530-compile-project.html
Copyright © 2011-2022 走看看