如何将Lua脚本编译成一个单独的可执行文件,同时仍然使用快速的LuaJIT编译器?

45
我如何将我的Lua脚本编译成单一的可执行文件,并获得超快的LuaJIT性能优势?
背景:
- 我的Lua脚本是为我创建的Web应用程序而设计的(例如,托管http://example.com)。 - 我当前的技术栈是NGINX(Web服务器)、Lua/LuaJIT(检索动态内容的语言)。 - 我有大约50个以上的.lua文件构成我的Web应用程序(从Models/Views/Controllers)。 - FreeBSD 9操作系统
为了简化部署,我想将运行我的Web应用程序的所有.lua脚本编译成单个可执行文件。
  1. 这是否可能?如何实现?

    看起来 Lua 官方自带了一个名为 SRLua 的库。

  2. 将我的 .lua 编译成单个可执行文件的缺点有哪些(例如性能是否会变差等)?

这是一个Web应用程序,对吧?这不意味着你要从你的Web浏览器中运行它吗?所以这不是你下载的可执行文件,对吧? - Nicol Bolas
是的,一个网络应用程序。无需下载。这全部在服务器端完成。 - nickb
为了简化服务器端的部署和代码修补等工作,我需要进行一些操作。目前,我的 Web 应用程序需要运行 50 多个 .lua 文件。这意味着我必须在服务器上托管 50 多个 .lua 文件,并确保我拥有所有正确的文件。如果我能够将它们合并成一个编译后的文件,那么服务器维护和版本控制就会变得非常容易。(2) 如果这样做还能带来性能上的好处,那就更好了。 - nickb
1
我知道这不是最佳实践,但将所有文件作为单独的文本文件允许您在现场进行紧急修复,而无需经历整个重建和重新部署周期。如果在部署过程中遇到推送一致的50个文件集到服务器的问题,您可能需要查看部署过程 - 构建统一的可执行文件并不更容易。 - Sean McSomething
2个回答

98

将所有Lua源代码文件翻译为目标文件并将它们放在静态库中:

for f in *.lua; do
    luajit -b $f `basename $f .lua`.o
done
ar rcus libmyluafiles.a *.o

然后使用-Wl,--whole-archive -lmyluafiles -Wl,--no-whole-archive -Wl,-Elibmyluafiles.a库链接到您的主程序中。

这行命令强制链接器包括归档文件中的所有目标文件,并导出所有符号。

例如,现在可以使用local foo = require("foo")从应用程序内部加载名为foo.lua的文件。

有关-b选项的详细信息,请参见运行LuaJIT


26
哇哦!LuaJit的Mike Pall回答了这个问题 :) - nickb
14
非常感谢您在LuaJIT上所做的一切工作!您所完成的工作真是令人难以置信。 - nickb
那个basename命令在Ubuntu 13.04上不能使用。它会用字节码版本覆盖原始的lua文件。 - hookenz
我认为你想要的内容类似于以下代码:for f in *.lua; do luajit -b $f basename $f .lua.o; done - hookenz
1
如果你有两个文件同名,但它们存储在不同的目录下,该怎么办?比如a/foo.lua和b/foo.lua。当我尝试链接生成的.o文件时,会出现重复符号错误(重复符号_luaJIT_BC_foo)。 - Matt Fichman
我的Windows32中有一个使用GCC(TDM SJLJ)构建的Luajit设置... 这个方法适用于我吗? - Josh S

2
对于您当前正在部署为一组相关的 .lua 文件的 Web 应用程序,最简单的解决方案是将它们压缩成一个单一文件。对于简单情况,这通常可以使用 luac 完成。但是,对于混合了模块的复杂应用程序,您需要更聪明的工具。

我个人使用 Mathew Wild 的实用程序 squish 做类似的事情。

运行 squish 后,您将获得一个包含所有 Lua 源代码的单个 .lua 文件,非常方便。你可以直接部署这个单一文件。

如果您还需要打包任何二进制模块,或者打包 Lua 或 LuaJIT 解释器,那么您可以轻松地使用 SRLua 将其与 Lua 解释器一起打包,或类似技术将其与 LuaJIT 一起打包。


所以,这并不像我最初的问题一样编译成单个可执行文件,而是将所有的.lua文件合并成一个单独的.lua文件? - nickb
虽然你可以一直进行到可执行文件,并且也可以使用Squish来简化收集依赖项以链接到该可执行文件中,但是你也可以停留在单个“.lua”文件。Mike Pall 提供了一个很好的配方,将LuaJIT与“.lua”文件捆绑在一起。 - RBerteig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接