From 96a5f790ed0bfd1381afd7b3234010dcb8a843f9 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 <2724172+shad0wshayd3@users.noreply.github.com> Date: Mon, 31 Aug 2026 05:02:39 -0600 Subject: [PATCH 1/4] feat: `commonlib.archive` rule --- xmake.lua | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/xmake.lua b/xmake.lua index 2836576..2ca98f7 100644 --- a/xmake.lua +++ b/xmake.lua @@ -250,3 +250,79 @@ rule("commonlib.plugin", function() end end) end) + +rule("commonlib.archive", function() + on_config(function(target) + target:set("kind", "phony") + + target:set("targetdir", "$(builddir)/archive") + os.mkdir(target:targetdir()) + + if not os.getenv("XSE_BSARCH_PATH") then + cprint("${dim}%s missing env XSE_BSARCH_PATH .. ${color.failure}${text.failure}", target:name()) + return + end + + if not os.exists(path.join(os.getenv("XSE_BSARCH_PATH"), "BSArch64.exe")) then + cprint("${dim}%s missing \"%%XSE_BRANCH_PATH%%\\BSArch64.exe\" .. ${color.failure}${text.failure}", target:name()) + return + end + + target:data_set("commonlib.archive.pass", true) + end) + + on_build(function(target) + import("core.project.project") + + local pass = target:data("commonlib.archive.pass") + if not pass then + cprint("${dim}%s .. failed archive config checks, skipping build", target:name()) + return + end + + local data = target:data("commonlib.archive.config") or {} + local suffix = target:data("commonlib.archive.suffix") or "" + local extension = target:data("commonlib.archive.extension") or ".bsa" + local archivename = (data.name or target:name()) .. suffix .. extension + cprint("${dim}archiving %s .. ", archivename) + + local tempdir = path.join(os.tmpdir(), "archive", project.name() or "", target:name()) + os.tryrm(tempdir) + os.mkdir(tempdir) + + local srcfiles, dstfiles = target:extrafiles(tempdir) + if srcfiles and #srcfiles > 0 and dstfiles and #dstfiles > 0 then + for idx, srcfile in ipairs(srcfiles) do + os.trycp(srcfile, dstfiles[idx]) + end + else + return + end + + local archivedir = path.absolute(target:targetdir()) + local archivefile = path.join(archivedir, archivename) + os.tryrm(archivefile) + + local args = { "pack", tempdir, archivefile, target:data("commonlib.archive.format") } + if data.options then + if data.options.archive_flags then table.append(args, format("-af:%s", tostring(data.options.archive_flags))) end + if data.options.file_flags then table.append(args, format("-ff:%s", tostring(data.options.file_flags))) end + if data.options.compress then table.append(args, "-z") end + if data.options.share then table.append(args, "-share") end + if data.options.multi_threaded then table.append(args, "-mt") end + end + os.vrunv(path.join(os.getenv("XSE_BSARCH_PATH"), "BSArch64.exe"), args) + + if data.install then + local parent = project.target(data.install) + if parent then + parent:add("installfiles", archivefile, { prefixdir = data.installdir or "" }) + end + end + + cprint("${dim}archiving %s to %s ... ${color.success}${text.success}", archivename, archivedir) + end) + + on_install(function(target) + end) +end) From 69d53eff31593bb6e8cb3bf212f1a6e4e370383d Mon Sep 17 00:00:00 2001 From: shad0wshayd3 <2724172+shad0wshayd3@users.noreply.github.com> Date: Mon, 31 Aug 2026 05:03:02 -0600 Subject: [PATCH 2/4] feat: `commonlib.papyrus` rule --- xmake.lua | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/xmake.lua b/xmake.lua index 2ca98f7..63e33b1 100644 --- a/xmake.lua +++ b/xmake.lua @@ -326,3 +326,111 @@ rule("commonlib.archive", function() on_install(function(target) end) end) + +rule("commonlib.papyrus", function() + on_config(function(target) + target:set("kind", "phony") + + target:set("targetdir", "$(builddir)/papyrus") + os.mkdir(target:targetdir()) + + if not os.getenv("XSE_CAPRICA_PATH") then + cprint("${dim}%s missing env XSE_CAPRICA_PATH .. ${color.failure}${text.failure}", target:name()) + return + end + + if not os.exists(path.join(os.getenv("XSE_CAPRICA_PATH"), "Caprica.exe")) then + cprint("${dim}%s missing \"%%XSE_CAPRICA_PATH%%\\Caprica.exe\" .. ${color.failure}${text.failure}", target:name()) + return + end + + target:data_set("commonlib.papyrus.pass", true) + end) + + on_build(function(target) + import("core.project.project") + + local pass = target:data("commonlib.papyrus.pass") + if not pass then + cprint("${dim}%s failed papyrus config checks, skipping build .. ${color.failure}${text.failure}", target:name()) + return + end + + local data = target:data("commonlib.papyrus.config") or {} + if not data.options then data.options = {} end + cprint("${dim}compiling %s .. ", target:name()) + + local tempdir = path.join(os.tmpdir(), "papyrus", project.name() or "", target:name()) + os.tryrm(tempdir) + + local rootdir = path.join(tempdir, "Scripts") + os.mkdir(rootdir) + + local srcfiles, dstfiles = target:extrafiles(rootdir) + if srcfiles and #srcfiles > 0 and dstfiles and #dstfiles > 0 then + for idx, srcfile in ipairs(srcfiles) do + os.trycp(srcfile, dstfiles[idx]) + end + else + return + end + + local args = { tempdir, format("--game=%s", target:data("commonlib.papyrus.game")), "--recurse", "--ignorecwd" } + local imports = { rootdir } + if data.options.imports then + if type(data.options.imports) ~= "table" then + cprint("${dim}%s options.imports is defined, but not a table .. ${color.failure}${text.failure}", target:name()) + return + end + table.join2(imports, data.options.imports) + end + + if not data.options.skip_default_imports then + local gamevar = target:data("commonlib.papyrus.gamevar") + if not os.getenv(gamevar) then + cprint("${dim}%s missing env %s .. ${color.failure}${text.failure}", target:name(), gamevar) + return + end + + local gamepath = os.getenv(gamevar) + local defaults = target:data("commonlib.papyrus.defaults") or {} + for _, default in ipairs(defaults) do + table.append(imports, path.join(gamepath, default)) + end + end + + table.append(args, format("--import=%s", table.concat(imports, ";"))) + table.append(args, format("--flags=%s", target:data("commonlib.papyrus.flags"))) + + local scriptdir = path.absolute(target:targetdir()) + table.append(args, format("--output=%s", scriptdir)) + + if data.options.optimize then table.append(args, "--optimize") end + if data.options.release then table.append(args, "--release") end + if data.options.final then table.append(args, "--final") end + if data.options.anonymize then table.append(args, "--anonymize") end + if data.options.parallel_compile then table.append(args, "--parallel-compile=1") end + if data.options.strict then table.append(args, "--strict") end + if data.options.language_extensions then table.append(args, "--enable-language-extensions=1") end + os.execv(path.join(os.getenv("XSE_CAPRICA_PATH"), "Caprica.exe"), args) + + if data.archive then + local parent = project.target(data.archive) + if parent then + parent:add("extrafiles", format("%s/(**)", scriptdir)) + end + end + + if data.install then + local parent = project.target(data.install) + if parent then + parent:add("installfiles", format("%s/(**)", scriptdir), { prefixdir = data.installdir or "" }) + end + end + + cprint("${dim}compiling %s to %s ... ${color.success}${text.success}", target:name(), scriptdir) + end) + + on_install(function(target) + end) +end) From 055bbe3040f366d0e5a45476556ffce168cbf203 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 <2724172+shad0wshayd3@users.noreply.github.com> Date: Mon, 31 Aug 2026 09:40:06 -0600 Subject: [PATCH 3/4] fix: `BSArch64` is deprecated as of xEdit 4.1.5q all builds going forward are 64-bit --- xmake.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xmake.lua b/xmake.lua index 63e33b1..f82811b 100644 --- a/xmake.lua +++ b/xmake.lua @@ -263,8 +263,8 @@ rule("commonlib.archive", function() return end - if not os.exists(path.join(os.getenv("XSE_BSARCH_PATH"), "BSArch64.exe")) then - cprint("${dim}%s missing \"%%XSE_BRANCH_PATH%%\\BSArch64.exe\" .. ${color.failure}${text.failure}", target:name()) + if not os.exists(path.join(os.getenv("XSE_BSARCH_PATH"), "BSArch.exe")) then + cprint("${dim}%s missing \"%%XSE_BRANCH_PATH%%\\BSArch.exe\" .. ${color.failure}${text.failure}", target:name()) return end @@ -311,7 +311,7 @@ rule("commonlib.archive", function() if data.options.share then table.append(args, "-share") end if data.options.multi_threaded then table.append(args, "-mt") end end - os.vrunv(path.join(os.getenv("XSE_BSARCH_PATH"), "BSArch64.exe"), args) + os.vrunv(path.join(os.getenv("XSE_BSARCH_PATH"), "BSArch.exe"), args) if data.install then local parent = project.target(data.install) From c5e869f86b7c6a1e8b9256a7f33ef5f424bf8cbe Mon Sep 17 00:00:00 2001 From: shad0wshayd3 <2724172+shad0wshayd3@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:36:27 -0600 Subject: [PATCH 4/4] feat: update `BSArch` args --- xmake.lua | 54 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/xmake.lua b/xmake.lua index e0c54e9..b15dcaf 100644 --- a/xmake.lua +++ b/xmake.lua @@ -284,6 +284,14 @@ rule("commonlib.archive", function() end local data = target:data("commonlib.archive.config") or {} + if not data.options then + data.options = { + compress = true, + share = true, + multi_threaded = true + } + end + local suffix = target:data("commonlib.archive.suffix") or "" local extension = target:data("commonlib.archive.extension") or ".bsa" local archivename = (data.name or target:name()) .. suffix .. extension @@ -307,13 +315,42 @@ rule("commonlib.archive", function() os.tryrm(archivefile) local args = { "pack", tempdir, archivefile, target:data("commonlib.archive.format") } - if data.options then - if data.options.archive_flags then table.append(args, format("-af:%s", tostring(data.options.archive_flags))) end - if data.options.file_flags then table.append(args, format("-ff:%s", tostring(data.options.file_flags))) end - if data.options.compress then table.append(args, "-z") end - if data.options.share then table.append(args, "-share") end - if data.options.multi_threaded then table.append(args, "-mt") end + if data.options.compress then + if type(data.options.compress) == "boolean" and data.options.compress == true then + table.append(args, "-z") + elseif data.options.compress == "zlib" then + table.append(args, "-z:zlib") + elseif data.options.compress == "lz4" then + table.append(args, "-z:lz4") + elseif data.options.compress == "lz4f" then + table.append(args, "-z:lz4f") + end + end + + if data.options.share then + if data.options.shared == true then + table.append(args, "-share:yes") + else + table.append(args, "-share:no") + end + end + + if data.options.multi_threaded then + if data.options.multi_threaded == true then + table.append(args, "-mt:yes") + else + table.append(args, "-mt:no") + end + end + + if data.options.archive_flags then + table.append(args, format("-af:%s", tostring(data.options.archive_flags))) + end + + if data.options.file_flags then + table.append(args, format("-ff:%s", tostring(data.options.file_flags))) end + os.vrunv(path.join(os.getenv("XSE_BSARCH_PATH"), "BSArch.exe"), args) if data.install then @@ -385,7 +422,10 @@ rule("commonlib.papyrus", function() cprint("${dim}%s options.imports is defined, but not a table .. ${color.failure}${text.failure}", target:name()) return end - table.join2(imports, data.options.imports) + + for _, import in ipairs(data.options.imports) do + table.append(imports, import) + end end if not data.options.skip_default_imports then