From 91d1145e61c44aa7b450648506981a5e5a1d658a Mon Sep 17 00:00:00 2001 From: David Lannan Date: Sat, 16 Nov 2024 18:42:47 +1030 Subject: [PATCH] working on builder --- examples/samples/nuklear_sapp.lua | 23 +++---- tools/build/rbuilder/utils/build.lua | 77 ++++++++++++++++++++++ tools/build/rbuilder/utils/combine.lua | 74 +++++++++++++++++++++ tools/build/rbuilder/utils/hash_loader.lua | 46 +++++++++++++ 4 files changed, 209 insertions(+), 11 deletions(-) create mode 100644 tools/build/rbuilder/utils/build.lua create mode 100644 tools/build/rbuilder/utils/combine.lua create mode 100644 tools/build/rbuilder/utils/hash_loader.lua diff --git a/examples/samples/nuklear_sapp.lua b/examples/samples/nuklear_sapp.lua index e802aac..ff1a648 100644 --- a/examples/samples/nuklear_sapp.lua +++ b/examples/samples/nuklear_sapp.lua @@ -98,6 +98,8 @@ local date_selected = 0 local sel_time = os.date ("*t") local sel_date = sel_time +local popup_active = ffi.new("int[1]") + -- -------------------------------------------------------------------------------------- local function draw_demo_ui(ctx) @@ -822,7 +824,6 @@ local function draw_demo_ui(ctx) color = ffi.new("struct nk_color[1]", {{255,0,0, 255}}) select = ffi.new("int[4]") - popup_active = ffi.new("int[1]") inp = ctx[0].input bounds = ffi.new("struct nk_rect[1]") @@ -868,10 +869,10 @@ local function draw_demo_ui(ctx) if (nk.nk_contextual_begin(ctx, 0, nk.nk_vec2(350, 60), bounds) == true) then nk.nk_layout_row_dynamic(ctx, 30, 4) - color.r = nk.nk_propertyi(ctx, "#r", 0, color.r, 255, 1, 1) - color.g = nk.nk_propertyi(ctx, "#g", 0, color.g, 255, 1, 1) - color.b = nk.nk_propertyi(ctx, "#b", 0, color.b, 255, 1, 1) - color.a = nk.nk_propertyi(ctx, "#a", 0, color.a, 255, 1, 1) + color[0].r = nk.nk_propertyi(ctx, "#r", 0, color[0].r, 255, 1, 1) + color[0].g = nk.nk_propertyi(ctx, "#g", 0, color[0].g, 255, 1, 1) + color[0].b = nk.nk_propertyi(ctx, "#b", 0, color[0].b, 255, 1, 1) + color[0].a = nk.nk_propertyi(ctx, "#a", 0, color[0].a, 255, 1, 1) nk.nk_contextual_end(ctx) end @@ -881,29 +882,29 @@ local function draw_demo_ui(ctx) nk.nk_label(ctx, "Popup:", nk.NK_TEXT_LEFT) nk.nk_layout_row_push(ctx, 50) if (nk.nk_button_label(ctx, "Popup")) then - popup_active = 1 + popup_active[0] = 1 end nk.nk_layout_row_end(ctx) - if (popup_active == 1) then + if (popup_active[0] == 1) then local s = ffi.new("struct nk_rect[1]",{{20, 100, 220, 90}}) - if (nk.nk_popup_begin(ctx, nk.NK_POPUP_STATIC, "Error", 0, s) == true) then + if (nk.nk_popup_begin(ctx, nk.NK_POPUP_STATIC, "Error", 0, s[0]) == true) then nk.nk_layout_row_dynamic(ctx, 25, 1) nk.nk_label(ctx, "A terrible error as occured", nk.NK_TEXT_LEFT) nk.nk_layout_row_dynamic(ctx, 25, 2) if (nk.nk_button_label(ctx, "OK")) then - popup_active = 0 + popup_active[0] = 0 nk.nk_popup_close(ctx) end if (nk.nk_button_label(ctx, "Cancel")) then - popup_active = 0 + popup_active[0] = 0 nk.nk_popup_close(ctx) end nk.nk_popup_end(ctx) else - popup_active = nk.nk_false + popup_active[0] = nk.nk_false end end diff --git a/tools/build/rbuilder/utils/build.lua b/tools/build/rbuilder/utils/build.lua new file mode 100644 index 0000000..c760133 --- /dev/null +++ b/tools/build/rbuilder/utils/build.lua @@ -0,0 +1,77 @@ +-- A simple build script using lua to make a standalone exe using srlua + +-- Use ffi for arch and os detection +local ffi = require("ffi") + +-- ---------------------------------------------------------------------------------- +local function run_cmd(command) + print(command) + local fh = io.popen( command, "r" ) + if(fh) then + local output = fh:read("*a") + fh:close() + io.write(output) + print("[Success]") + else + print("[Error] Cannot execute command: "..command) + end +end + +-- ---------------------------------------------------------------------------------- +-- srlua and glue for each os +local plaform_cmds = { + ["Windows"] = { + srlua = ".\\tools\\srlua\\win64\\srlua.exe", + glue = ".\\tools\\srlua\\win64\\glue.exe", + ext = ".exe", + sep = "\\", + luajit = ".\\bin\\win64\\luajit.exe", + src_dll = ".\\bin\\win64\\*.dll", + src_cfg = ".\\config", + }, + ["OSX"] = { + srlua = "./tools/srlua/macos/srlua", + glue = "./tools/srlua/macos/glue", + ext = "", + sep = "/", + luajit = "./bin/macos/luajit", + src_dll = "./bin/macos/*.dylib", + src_cfg = "./config", + }, + ["Linux"] = { + srlua = "./tools/srlua/linux/srlua", + glue = "./tools/srlua/linux/glue", + ext = "", + sep = "/", + luajit = "./bin/linux/luajit", + src_dll = "./bin/linux/*.so", + src_cfg = "./config", + }, +} + +local cmds = plaform_cmds[ffi.os] +local outputfolder = "."..cmds.sep.."tools"..cmds.sep.."bin"..cmds.sep..string.lower(ffi.os)..cmds.sep +local outputexe = "minikeybd_"..ffi.os..cmds.ext + +-- Have to build a bytecode "chunk" first. +local buildchunk = cmds.luajit.." ."..cmds.sep.."tools"..cmds.sep.."combine.lua " +buildchunk = buildchunk.."."..cmds.sep.."lua"..cmds.sep.."minikeybd.lua -L " +buildchunk = buildchunk.."."..cmds.sep.."ffi"..cmds.sep.."hidwin.lua " +buildchunk = buildchunk.."."..cmds.sep.."ffi"..cmds.sep.."lusb.lua " +buildchunk = buildchunk.."."..cmds.sep.."lua"..cmds.sep.."mapcodes.lua " +buildchunk = buildchunk.."."..cmds.sep.."lua"..cmds.sep.."wchar_win.lua " +run_cmd(buildchunk) + +-- Build the exe +local command = cmds.glue.." "..cmds.srlua.." luac.out "..outputfolder..outputexe +run_cmd(command) + +local copycmd = "cp -rf "..cmds.src_dll.." "..outputfolder +if(ffi.os == "Windows") then copycmd = "xcopy /C /I /Y "..cmds.src_dll.." "..outputfolder end +-- Copy in the dlls/dylib/sos +run_cmd(copycmd) + +-- Copy in config folder +local copyconfig = "cp -rf "..cmds.src_cfg.." "..outputfolder..cmds.sep.."config" +if(ffi.os == "Windows") then copyconfig = "xcopy /S /E /C /I /Y "..cmds.src_cfg.." "..outputfolder.."config" end +run_cmd(copyconfig) \ No newline at end of file diff --git a/tools/build/rbuilder/utils/combine.lua b/tools/build/rbuilder/utils/combine.lua new file mode 100644 index 0000000..2013ed1 --- /dev/null +++ b/tools/build/rbuilder/utils/combine.lua @@ -0,0 +1,74 @@ +-- usage: lua luac.lua [file.lua]* [-L [module.lua]*] +-- +-- creates a precompiled chunk that preloads all modules listed after +-- -L and then runs all programs listed before -L. +-- +-- assumptions: +-- file xxx.lua contains module xxx +-- '/' is the directory separator (could have used package.config) +-- int and size_t take 4 bytes (could have read sizes from header) +-- does not honor package.path +-- +-- Luiz Henrique de Figueiredo +-- Tue Aug 5 22:57:33 BRT 2008 +-- This code is hereby placed in the public domain. +-- +-- This has been hevily midified to utilize a different method to concatenate the +-- chunks without losing the package module mapping. +-- ref: https://www.lua-users.org/wiki/LuaCompilerInLua + +-- --------------------------------------------------------------------------------------------------- + +local NAME="luac" +local OUTPUT=NAME..".out" + +local n=#arg +local m=n + +-- --------------------------------------------------------------------------------------------------- +-- Load a chunk manually so we can name it +local function loader(filepath) + local data = "" + local fh = io.open(filepath, "r") + if(fh) then + data = fh:read("*a") + fh:close() + end + return data +end + +-- --------------------------------------------------------------------------------------------------- +-- Process args +for i=1,n do + if arg[i]=="-L" then m=i-1 break end +end + +-- --------------------------------------------------------------------------------------------------- +-- Iterate libs to prepend them to the chunk list +local ts = {} +table.insert(ts, 1, "local t=package.preload;") + +for i=m+2,n do + local modulename = string.gsub(arg[i], "^%.[/\\]", "") + modulename = string.gsub(modulename, "[/\\]", "%.") + modulename = string.gsub(modulename, "%.lua", "") + + local loaded_chunk = assert(load( loader(arg[i]),modulename )) + table.insert(ts, ("t['%s']=load(%q);"):format(modulename, string.dump(loaded_chunk)) ) +end + +-- --------------------------------------------------------------------------------------------------- +-- Add core scripts that will be executed +for i=1,m do + table.insert(ts, ("load(%q)(...);"):format(string.dump(assert(loadfile(arg[i])))) ) +end + +-- --------------------------------------------------------------------------------------------------- +-- Assemble chunks into one file to dump. +local chunks = assert(load(table.concat(ts))) +local f=assert(io.open(OUTPUT,"wb")) +local data = string.dump(chunks) +f:write(data) +assert(f:close()) + +-- --------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/tools/build/rbuilder/utils/hash_loader.lua b/tools/build/rbuilder/utils/hash_loader.lua new file mode 100644 index 0000000..95622c3 --- /dev/null +++ b/tools/build/rbuilder/utils/hash_loader.lua @@ -0,0 +1,46 @@ +module(..., package.seeall) + +local crypto = require 'crypto' + +local dtypes = {"md5", "md4", "md2", "sha1", "sha", "sha256", "sha512"} + +local function load(modulename) + -- Find source + local filename + local file,hashfile,hashtype + local errmsg = "" + for path in string.gmatch(package.path..";", "([^;]*);") do + filename = string.gsub(path, "%?", (string.gsub(modulename, "%.", "\\"))) + file = io.open(filename, "rb") + -- If we found a module check if it has a hash file + if file then + for _,dtype in ipairs(dtypes) do + hashfile = io.open(filename.."."..dtype, "rb") + if hashfile then + hashtype = dtype + break + end + end + end + if hashfile then + break + end + errmsg = errmsg.."\n\tno file '"..filename.."' (signed)" + end + if not file then + return errmsg + end + -- Read source file + local source = file:read("*a") + -- Read saved hash + local hash = hashfile:read("*a"):gsub("[^%x]", "") + -- Check that the saved hash match the file hash + assert(crypto.evp.digest(hashtype, source)==hash, + "module "..modulename.." (from file '"..filename.."')" + .." does not match its "..hashtype.." hash") + -- Compile and return the module + return assert(loadstring(source, filename)) +end + +-- Install the loader so that it's called just before the normal Lua loader +table.insert(package.loaders, 2, load) \ No newline at end of file