diff --git a/xmake.lua b/xmake.lua index babc2a1..b15dcaf 100644 --- a/xmake.lua +++ b/xmake.lua @@ -253,3 +253,227 @@ 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"), "BSArch.exe")) then + cprint("${dim}%s missing \"%%XSE_BRANCH_PATH%%\\BSArch.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 {} + 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 + 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.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 + 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) + +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 + + for _, import in ipairs(data.options.imports) do + table.append(imports, import) + end + 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)