diff options
| author | ruki <[email protected]> | 2023-11-24 23:09:46 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-24 23:09:46 +0800 |
| commit | 51efaa718683a9bf18cd6859e60f1d5240c10c5d (patch) | |
| tree | 0ae3485ef5434f8acfc70210b6910356aa5adfc5 /xmake/plugins/pack | |
| parent | 16f74fe53b4c240c8bee69e1d06dc821067f2817 (diff) | |
| parent | 43ac546cbd551bf06ae37a8211c8a65d9eadbb0b (diff) | |
Merge pull request #4415 from xmake-io/makeself
pack runself
Diffstat (limited to 'xmake/plugins/pack')
| -rw-r--r-- | xmake/plugins/pack/archive.lua | 28 | ||||
| -rw-r--r-- | xmake/plugins/pack/batchcmds.lua | 6 | ||||
| -rw-r--r-- | xmake/plugins/pack/main.lua | 56 | ||||
| -rw-r--r-- | xmake/plugins/pack/nsis/main.lua | 2 | ||||
| -rw-r--r-- | xmake/plugins/pack/runself/main.lua | 185 | ||||
| -rw-r--r-- | xmake/plugins/pack/srctargz/main.lua | 26 | ||||
| -rw-r--r-- | xmake/plugins/pack/srczip/main.lua | 26 | ||||
| -rw-r--r-- | xmake/plugins/pack/xmake.lua | 2 | ||||
| -rw-r--r-- | xmake/plugins/pack/xpack.lua | 82 | ||||
| -rw-r--r-- | xmake/plugins/pack/xpack_component.lua | 21 |
10 files changed, 395 insertions, 39 deletions
diff --git a/xmake/plugins/pack/archive.lua b/xmake/plugins/pack/archive.lua index 818404345..dd1861ca4 100644 --- a/xmake/plugins/pack/archive.lua +++ b/xmake/plugins/pack/archive.lua @@ -26,16 +26,32 @@ import("batchcmds") -- pack archive package function _pack_archive(package) - -- do install - batchcmds.get_installcmds(package):runcmds() - for _, component in table.orderpairs(package:components()) do - if component:get("default") ~= false then - batchcmds.get_installcmds(component):runcmds() + -- archive source files + if package:from_source() then + local srcfiles, dstfiles = package:sourcefiles() + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) + end + for _, component in table.orderpairs(package:components()) do + if component:get("default") ~= false then + local srcfiles, dstfiles = component:sourcefiles() + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) + end + end + end + else + -- archive binary files + batchcmds.get_installcmds(package):runcmds() + for _, component in table.orderpairs(package:components()) do + if component:get("default") ~= false then + batchcmds.get_installcmds(component):runcmds() + end end end -- archive install files - local rootdir = package:rootdir() + local rootdir = package:from_source() and package:source_rootdir() or package:install_rootdir() local oldir = os.cd(rootdir) local archivefiles = os.files("**") os.cd(oldir) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 1b3023283..af55cc707 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -363,6 +363,9 @@ end -- on install command function _on_installcmd(package, batchcmds_) + if not package:from_binary() then + return + end local srcfiles, dstfiles = package:installfiles() for idx, srcfile in ipairs(srcfiles) do batchcmds_:cp(srcfile, dstfiles[idx]) @@ -374,6 +377,9 @@ end -- on uninstall command function _on_uninstallcmd(package, batchcmds_) + if not package:from_binary() then + return + end local _, dstfiles = package:installfiles() for _, dstfile in ipairs(dstfiles) do batchcmds_:rm(dstfile, {emptydirs = true}) diff --git a/xmake/plugins/pack/main.lua b/xmake/plugins/pack/main.lua index 3f145cf86..c9576774f 100644 --- a/xmake/plugins/pack/main.lua +++ b/xmake/plugins/pack/main.lua @@ -26,6 +26,28 @@ import("private.service.remote_build.action", {alias = "remote_build_action"}) import("actions.build.main", {rootdir = os.programdir(), alias = "build_action"}) import("xpack") +-- get packages +function _get_packages() + + -- get need formats + local formats_need = option.get("formats") + if formats_need then + formats_need = formats_need:split(",") + if formats_need[1] == "all" then + formats_need = nil + end + end + + local packages = {} + for _, package in ipairs(xpack.packages()) do + if not formats_need or table.contains(formats_need, package:format()) then + table.insert(packages, package) + end + end + return packages +end + +-- load package function _load_package(package) -- ensure build and output directories @@ -39,50 +61,42 @@ function _load_package(package) end end +-- pack the given package function _on_package(package) import(package:format())(package) end function _pack_package(package) - -- get need formats - local formats_need = option.get("formats") - if formats_need then - formats_need = formats_need:split(",") - if formats_need[1] == "all" then - formats_need = nil - end - end - -- do pack local scripts = { package:script("package_before"), package:script("package", _on_package), package:script("package_after") } - if not formats_need or table.contains(formats_need, package:format()) then - _load_package(package) - for i = 1, 3 do - local script = scripts[i] - if script ~= nil then - script(package) - end + _load_package(package) + for i = 1, 3 do + local script = scripts[i] + if script ~= nil then + script(package) end end end function _pack_packages() - for _, package in ipairs(xpack.packages()) do + for _, package in ipairs(_get_packages()) do _pack_package(package) end end function _build_targets() local targetnames = {} - for _, package in ipairs(xpack.packages()) do - local targets = package:get("targets") - if targets then - table.join2(targetnames, targets) + for _, package in ipairs(_get_packages()) do + if package:from_binary() then + local targets = package:get("targets") + if targets then + table.join2(targetnames, targets) + end end end if #targetnames > 0 then diff --git a/xmake/plugins/pack/nsis/main.lua b/xmake/plugins/pack/nsis/main.lua index d7d69fdef..b8f6d4dc4 100644 --- a/xmake/plugins/pack/nsis/main.lua +++ b/xmake/plugins/pack/nsis/main.lua @@ -88,7 +88,7 @@ end -- translate the file path function _translate_filepath(package, filepath) - return filepath:replace(package:rootdir(), "$InstDir", {plain = true}) + return filepath:replace(package:install_rootdir(), "$InstDir", {plain = true}) end -- get command string diff --git a/xmake/plugins/pack/runself/main.lua b/xmake/plugins/pack/runself/main.lua new file mode 100644 index 000000000..8f25c3e80 --- /dev/null +++ b/xmake/plugins/pack/runself/main.lua @@ -0,0 +1,185 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki +-- @file main.lua +-- + +-- imports +import("core.base.option") +import("core.base.semver") +import("lib.detect.find_tool") +import("private.action.require.impl.packagenv") +import("private.action.require.impl.install_packages") +import(".batchcmds") + +-- get the makeself +function _get_makeself() + + -- enter the environments of makeself + local oldenvs = packagenv.enter("makeself") + + -- find makeself + local packages = {} + local makeself = find_tool("makeself.sh") + if not makeself then + table.join2(packages, install_packages("makeself")) + end + + -- enter the environments of installed packages + for _, instance in ipairs(packages) do + instance:envs_enter() + end + + -- we need to force detect and flush detect cache after loading all environments + if not makeself then + makeself = find_tool("makeself.sh", {force = true}) + end + assert(makeself, "makeself not found!") + return makeself, oldenvs +end + +-- get specvars +function _get_specvars(package) + local specvars = table.clone(package:specvars()) + return specvars +end + +-- write install command +function _write_installcmd(package, scriptfile, cmd) + local opt = cmd.opt or {} + local kind = cmd.kind + if kind == "cp" then + local srcfiles = os.files(cmd.srcpath) + for _, srcfile in ipairs(srcfiles) do + -- the destination is directory? append the filename + local dstfile = cmd.dstpath + if #srcfiles > 1 or path.islastsep(dstfile) then + if opt.rootdir then + dstfile = path.join(dstfile, path.relative(srcfile, opt.rootdir)) + else + dstfile = path.join(dstfile, path.filename(srcfile)) + end + end + scriptfile:print("cp -p \"%s\" \"%s\"", srcfile, dstfile) + end + elseif kind == "rm" then + local filepath = cmd.filepath + scriptfile:print("rm -f \"%s\"", filepath) + elseif kind == "rmdir" then + local dir = cmd.dir + scriptfile:print("rm -rf \"%s\"", dir) + elseif kind == "mv" then + local srcpath = cmd.srcpath + local dstpath = cmd.dstpath + scriptfile:print("mv \"%s\" \"%s\"", srcfile, dstfile) + elseif kind == "cd" then + local dir = cmd.dir + scriptfile:print("cd \"%s\"", dir) + elseif kind == "mkdir" then + local dir = cmd.dir + scriptfile:print("mkdir -p \"%s\"", dir) + elseif cmd.program then + scriptfile:print("%s", os.args(table.join(cmd.program, cmd.argv))) + end +end + +-- write install commands +function _write_installcmds(package, scriptfile, cmds) + for _, cmd in ipairs(cmds) do + _write_installcmd(package, scriptfile, cmd) + end +end + +-- pack runself package +function _pack_runself(makeself, package) + + -- install the initial specfile + local specfile = package:specfile() + if not os.isfile(specfile) then + local specfile_template = path.join(os.programdir(), "scripts", "xpack", "runself", "makeself.lsm") + os.cp(specfile_template, specfile) + end + + -- replace variables in specfile + local specvars = _get_specvars(package) + local pattern = package:extraconf("specfile", "pattern") or "%${([^\n]-)}" + io.gsub(specfile, "(" .. pattern .. ")", function(_, name) + name = name:trim() + local value = specvars[name] + if type(value) == "function" then + value = value() + end + if value ~= nil then + dprint(" > replace %s -> %s", name, value) + end + if type(value) == "table" then + dprint("invalid variable value", value) + end + return value + end) + + -- archive source files + local srcfiles, dstfiles = package:sourcefiles() + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) + end + for _, component in table.orderpairs(package:components()) do + if component:get("default") ~= false then + local srcfiles, dstfiles = component:sourcefiles() + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) + end + end + end + + -- generate the setup.sh script + local sourcedir = package:sourcedir() + local setupfile = path.join(sourcedir, "__setup__.sh") + os.cp(path.join(os.programdir(), "scripts", "xpack", "runself", "setup.sh"), setupfile) + local scriptfile = io.open(setupfile, "a+") + if scriptfile then + _write_installcmds(package, scriptfile, batchcmds.get_installcmds(package):cmds()) + for _, component in table.orderpairs(package:components()) do + if component:get("default") ~= false then + _write_installcmds(package, scriptfile, batchcmds.get_installcmds(component):cmds()) + end + end + scriptfile:close() + end + + -- make package + os.vrunv(makeself, {"--gzip", "--sha256", "--lsm", specfile, + sourcedir, package:outputfile(), package:basename(), "./__setup__.sh"}) +end + +function main(package) + + if is_subhost("windows") then + return + end + + cprint("packing %s", package:outputfile()) + + -- get makeself + local makeself, oldenvs = _get_makeself() + + -- pack runself package + _pack_runself(makeself.program, package) + + -- done + os.setenvs(oldenvs) +end diff --git a/xmake/plugins/pack/srctargz/main.lua b/xmake/plugins/pack/srctargz/main.lua new file mode 100644 index 000000000..fe511bff9 --- /dev/null +++ b/xmake/plugins/pack/srctargz/main.lua @@ -0,0 +1,26 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki +-- @file main.lua +-- + +-- imports +import(".archive") + +function main(package) + archive(package) +end diff --git a/xmake/plugins/pack/srczip/main.lua b/xmake/plugins/pack/srczip/main.lua new file mode 100644 index 000000000..fe511bff9 --- /dev/null +++ b/xmake/plugins/pack/srczip/main.lua @@ -0,0 +1,26 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki +-- @file main.lua +-- + +-- imports +import(".archive") + +function main(package) + archive(package) +end diff --git a/xmake/plugins/pack/xmake.lua b/xmake/plugins/pack/xmake.lua index 3d7c02ddf..96b0d2070 100644 --- a/xmake/plugins/pack/xmake.lua +++ b/xmake/plugins/pack/xmake.lua @@ -32,7 +32,7 @@ task("pack") "e.g.", " - xmake pack -f nsis,deb,rpm", "values:", - values = {"nsis", "deb", "rpm", "runself", "targz", "zip"}}, + values = {"nsis", "deb", "rpm", "runself", "targz", "zip", "srctargz", "srczip"}}, {}, {nil, "packages", "vs", nil, "The package names."} } diff --git a/xmake/plugins/pack/xpack.lua b/xmake/plugins/pack/xpack.lua index e5829fd45..64e9d77dc 100644 --- a/xmake/plugins/pack/xpack.lua +++ b/xmake/plugins/pack/xpack.lua @@ -225,6 +225,35 @@ function xpack:format() return self._FORMAT end +-- get the input kind +function xpack:inputkind() + local inputkind = self:get("inputkind") + if inputkind == nil then + local inputkinds = { + nsis = "binary", + zip = "binary", + targz = "binary", + srczip = "source", + srctargz = "source", + runself = "source", + deb = "source", + rpm = "source" + } + inputkind = inputkinds[self:format()] or "binary" + end + return inputkind +end + +-- pack from source files? +function xpack:from_source() + return self:inputkind() == "source" +end + +-- pack from binary files? +function xpack:from_binary() + return self:inputkind() == "binary" +end + -- get the build directory function xpack:buildir() return path.join(config.buildir(), ".xpack", self:name()) @@ -244,6 +273,9 @@ function xpack:basename() local basename = option.get("basename") or self:get("basename") if basename == nil then basename = self:name() + if self:from_source() then + basename = basename .. "-src" + end local version = self:version() if version then basename = basename .. "-" .. version @@ -264,6 +296,8 @@ function xpack:specvars() PACKAGE_TITLE = self:title() or "", PACKAGE_DESCRIPTION = self:description() or "", PACKAGE_FILENAME = self:filename(), + PACKAGE_AUTHOR = self:get("author") or "", + PACKAGE_MAINTAINER = self:get("maintainer") or self:get("author") or "", PACKAGE_HOMEPAGE = self:get("homepage") or "", PACKAGE_COPYRIGHT = self:get("copyright") or "", PACKAGE_COMPANY = self:get("company") or "", @@ -336,9 +370,14 @@ function xpack:extension() local extension = self:get("extension") if extension == nil then local extensions = { - nsis = ".exe", - zip = ".zip", - targz = ".tar.gz" + nsis = ".exe", + zip = ".zip", + targz = ".tar.gz", + srczip = ".zip", + srctargz = ".tar.gz", + runself = ".gz.run", + deb = ".deb", + rpm = ".rpm" } extension = extensions[self:format()] or "" end @@ -465,22 +504,51 @@ function xpack:installfiles() return self:_copiedfiles("installfiles", self:installdir()) end --- get the root directory, this is just a temporary sandbox installation path, +-- get the installed root directory, this is just a temporary sandbox installation path, -- we may replace it with the actual installation path in the specfile -function xpack:rootdir() +function xpack:install_rootdir() return path.join(self:buildir(), "installed", self:format()) end -- get the installed directory function xpack:installdir(...) - local installdir = self:rootdir() - local prefixdir = self:get("prefixdir") + local installdir = self:install_rootdir() + local prefixdir = self:prefixdir() if prefixdir then installdir = path.join(installdir, prefixdir) end return path.normalize(path.join(installdir, ...)) end +-- get the source files +function xpack:sourcefiles() + return self:_copiedfiles("sourcefiles", self:sourcedir()) +end + +-- get the source root directory +function xpack:source_rootdir() + return path.join(self:buildir(), "source", self:format()) +end + +-- get the source directory +function xpack:sourcedir(...) + local sourcedir = self:source_rootdir() + local prefixdir = self:prefixdir() + if prefixdir then + sourcedir = path.join(sourcedir, prefixdir) + end + return path.normalize(path.join(sourcedir, ...)) +end + +-- get the prefixdir +function xpack:prefixdir() + local prefixdir = self:get("prefixdir") + if prefixdir then + return filter.handle(prefixdir, self) + end + return prefixdir +end + -- get the binary directory function xpack:bindir() local bindir = self:get("bindir") diff --git a/xmake/plugins/pack/xpack_component.lua b/xmake/plugins/pack/xpack_component.lua index 59d2fae8f..bb0f5f454 100644 --- a/xmake/plugins/pack/xpack_component.lua +++ b/xmake/plugins/pack/xpack_component.lua @@ -240,10 +240,10 @@ function xpack_component:installfiles() return self:_copiedfiles("installfiles", self:package():installdir()) end --- get the root directory, this is just a temporary sandbox installation path, +-- get the installed root directory, this is just a temporary sandbox installation path, -- we may replace it with the actual installation path in the specfile -function xpack_component:rootdir() - return self:package():rootdir() +function xpack_component:install_rootdir() + return self:package():install_rootdir() end -- get the installed directory @@ -251,6 +251,21 @@ function xpack_component:installdir(...) return self:package():installdir(...) end +-- get the source files +function xpack_component:sourcefiles() + return self:_copiedfiles("sourcefiles", self:package():sourcedir()) +end + +-- get the source root directory +function xpack_component:source_rootdir() + return self:package():souece_rootdir() +end + +-- get the source directory +function xpack_component:sourcedir(...) + return self:package():sourcedir(...) +end + -- get the binary directory function xpack_component:bindir() return self:package():bindir() |
