2012-03-06 79 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

希望它會很有幫助。

相關問題