forked from chrisant996/clink
-
Notifications
You must be signed in to change notification settings - Fork 0
/
embed.lua
142 lines (120 loc) · 4.8 KB
/
embed.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
--------------------------------------------------------------------------------
local function exec(str)
-- Premake5 bug (see docs/premake5.lua)
local x = path.normalize
path.normalize = function (y) return y end
os.execute(str)
path.normalize = x
end
--------------------------------------------------------------------------------
local function spairs(t, order)
-- collect the keys
local keys = {}
for k in pairs(t) do keys[#keys+1] = k end
-- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys
if order then
table.sort(keys, function(a,b) return order(t, a, b) end)
else
table.sort(keys)
end
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
--------------------------------------------------------------------------------
local function compare_values(t, a, b)
return t[a] < t[b]
end
--------------------------------------------------------------------------------
local function do_embed(debug_info)
-- Find the Lua compilers.
local archs = {
["64"] = { luac = os.matchfiles(".build/*/bin/final/luac_x64.exe")[1] },
["86"] = { luac = os.matchfiles(".build/*/bin/final/luac_x86.exe")[1] },
}
debug_info = debug_info and "" or " -s"
for name, arch in spairs(archs) do
if not arch.luac then
error("Unable to find Lua compiler binary (x"..name.." final).")
end
arch.luac = arch.luac:gsub("/", "\\")
end
local manifests = os.matchfiles("clink/**/_manifest.lua")
for _, manifest in spairs(manifests, compare_values) do
local root = path.getdirectory(manifest)
out = path.join(root, "lua_scripts.cpp")
print("\n"..out)
out = io.open(out, "w")
out:write("#include \"pch.h\"\n")
out:write("#include <core/embedded_scripts.h>\n")
out:write("#if defined(CLINK_USE_EMBEDDED_SCRIPTS)\n")
-- Write each sanitised script to 'out' as a global variable.
local symbols = {}
local manifest = dofile(manifest)
for _, file in spairs(manifest.files, compare_values) do
local name = path.getname(file)
local symbol = manifest.name .. "_" .. name:gsub("%.", "_") .. "_script"
table.insert(symbols, symbol)
file = path.join(root, file)
print(" "..file)
for name, arch in spairs(archs) do
out:write("#if ARCHITECTURE == "..name.."\n")
-- Compile the input Lua script to binary.
exec(arch.luac..debug_info.." -o .build/embed_temp "..file)
local bin_in = io.open(".build/embed_temp", "rb")
local bin_data = bin_in:read("*a")
bin_in:close()
os.remove(".build/embed_temp")
local crlf_counter = 0
out:write("const unsigned char " .. symbol .. "_[] = {\n")
for byte in string.gmatch(bin_data, ".") do
out:write(string.format("0x%02x, ", byte:byte()))
crlf_counter = crlf_counter + 1
if crlf_counter > 16 then
out:write("\n")
crlf_counter = 0
end
end
out:write("};\n")
out:write("unsigned char const* "..symbol.." = "..symbol.."_;\n")
out:write("int "..symbol.."_len = sizeof("..symbol.."_);\n")
out:write("#endif // ARCHITECTURE == "..name.."\n")
print(" x"..name.." : "..tostring(#bin_data).." bytes")
end
end
-- Some debug stuff so loose files can be loaded in debug builds.
symbols = {}
out:write("#else\n")
for _, file in spairs(manifest.files, compare_values) do
local symbol = path.getname(file):gsub("%.", "_")
symbol = manifest.name .. "_" .. symbol .. "_file"
table.insert(symbols, symbol)
file = file:gsub("\\", "/")
out:write("const char* " .. symbol .. " = CLINK_BUILD_ROOT \"/../../" .. root .. "/" .. file .. "\";\n")
end
out:write("#endif\n")
out:close()
end
end
--------------------------------------------------------------------------------
newaction {
trigger = "embed",
description = "Clink: Update embedded scripts for Clink",
execute = function ()
do_embed()
end
}
--------------------------------------------------------------------------------
newaction {
trigger = "embed_debug",
description = "Clink: Update embedded scripts for Clink with debugging info",
execute = function ()
do_embed(true--[[debug_info]])
end
}