2012-03-06 80 views
14

我已经将lua与一个字节码块一起嵌入到用C编写的项目中。 现在,当我通过添加.lua文件扩展我的lua代码库时,是否有办法将此代码保存在单个字节码块中?将所有内容保存在单个lua字节码块中?

(我知道如何加载多个字节块,但使其加载一个单一的块,然后忘掉胶水代码将似乎只是舒服。)

我试图用文字列入,但似乎没有关键字为此在Lua中。 “Require”和“dofile”在运行时查看文件,因此运行“lua -b ...”后生成的字节码将不包含这些文件的代码。

而且没有办法组合字节码文件,是吗?我的意思是,在创建字节码文件时,“require”命令会将所有这些文件的代码添加到一个字节码文件中。

PS:Michal Kottman的答案适用于Lua,这就是我所要求的。我以为Lua和LuaJIT会以同样的方式工作。他们不。要多.lua文件到一个LuaJIT字节码文件,应在

  • 使用 “LuaJIT -B”(似乎不工作)
  • 编译Lua的luac.c与LuaJIT来源
  • 效仿luac.c与lua命令(没有C API)?
+0

这是一个可能在主题和有帮助的答案。 http://stackoverflow.com/questions/8936369/compile-lua-code-store-bytecode-then-load-and-execute-it – 2012-12-16 22:53:30

回答

11

您可以使用luac将多个文件合并到一个文件中。

$ echo "x=1"   > l1.lua 
$ echo "y=2"   > l2.lua 
$ echo "print(x, y)" > l3.lua 
$ luac -o run.luac l1.lua l2.lua l3.lua 
$ lua run.luac 
1 2 

可以将此文件在C使用luaL_loadfile加载到Lua中,这将依赖于顶部的功能:运行时,所有从源文件中的数据块在它们被添加到编译的文件的顺序执行堆栈如果成功加载。然后,您可以使用lua_call运行此功能来运行所有组合的编译文件。

请注意,您可以将编译文件的内容作为字符串嵌入到项目中,无需将其保存在外部文件中。

更新LuaJIT 2

正如你已经发现,可以使用Lua Compiler in Lua获得可如前所述被加载组合文件。这是一个简化版本,它输出到标准输出:

$ luajit combine.lua l1.lua l2.lua l3.lua > out.ljc 
$ luajit out.ljc 
1 2 
+0

非常感谢!很好,与原来的Lua一起工作。我试图用luaJIT实现同样的功能,使用“luajit -b”和几个文件,但是无法在那里完成。 luaJIT中没有luac.c和字节码格式不同,所以我想知道这种方式是否也可以与luaJIT一起使用。也许通过像这里http://lua-users.org/wiki/LuaCompilerInLua一样模拟luac。 – John 2012-03-06 10:45:13

+0

根据这个http://lua-users.org/lists/lua-l/2005-12/msg00209.html luac.c也将与luaJIT一起工作。 – John 2012-03-06 11:07:32

+0

请注意,它是LuaJIT 1,它能够读取标准的Lua字节码。较新的LuaJIT 2具有不兼容的字节码。 – 2012-03-06 13:20:19

0

loadstring是你的需求。它需要一个字符串并加载(如果需要的话在编译为字节代码之后)。它会产生一个可以执行的函数,以便随后运行包含的代码。

如果你还需要更多的东西一般,看看load它可以让你指定一个函数在喂大块。

两个函数可以处理的Lua源代码和编译字节码。

+0

我试了一下,我看它是如何工作的,但不是我如何创建一个单一的包含加载块和加载块的块。你能给个例子吗?我正在寻找类似于(使用C时)从对象文件创建单个库文件的东西,因此您无需链接每个对象文件。就像这样,但对于Lua来说,我只需要将一个资源嵌入到我的可执行文件中。 – John 2012-03-06 10:06:49

+0

我明白了。也许这个链接可以进一步帮助你:[Lua编译器在Lua](http://lua-users.org/wiki/LuaCompilerInLua) – jpjacobs 2012-03-06 10:16:38

+0

非常感谢,这可能是luaJIT的唯一方法,因为没有luac。 – John 2012-03-06 10:54:38

4

另一种方法是使用像马修野生的squish一个工具来收集:

-- http://lua-users.org/wiki/LuaCompilerInLua 
-- compile the input file(s) passed as arguments and output them combined to stdout 
local chunk = {} 
for _, file in ipairs(arg) do 
    chunk[#chunk + 1] = assert(loadfile(file)) 
end 
if #chunk == 1 then 
    chunk = chunk[1] 
else 
    -- combine multiple input files into a single chunk 
    for i, func in ipairs(chunk) do 
    chunk[i] = ("loadstring%q(...);"):format(string.dump(func)) 
    end 
    chunk = assert(loadstring(table.concat(chunk))) 
end 
io.write(string.dump(chunk)) 

对于前面的示例,您可以按如下方式使用它把你所有的Lua源码放入一个.lua文件中。压扁的一个很好的功能是它支持多种过滤器来帮助使压扁的包比源文件的总数小。

应用压扁后,可以通过luac运行结果来获取字节码。但是,字节码通常比源代码大,如果在挤压中使用更具侵略性的过滤器(如gzip),则字节码几乎可以确定更大。

如果您的字节码文件与可执行文件分开存储(或者更糟糕的是,通过网络传输),我还会提出与字节码相关的安全问题,这些问题不适用于Lua源代码。但是,链接到应用程序的字节码很难颠覆,因为有害的字节码永远不会是运行luac的结果。

2

在尝试过luac,luajit和squish之后,我发现他们都需要你维护一个文件列表来合并。当在一个包含许多lua文件的项目上工作时,这是令人厌烦的。

所以我写了一个小工具,通过分析require小号

合并LUA文件在这里:https://github.com/yi/node-lua-distiller

希望它会很有帮助。

相关问题