diff options
| author | ruki <[email protected]> | 2024-06-15 08:40:37 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-06-15 08:40:37 +0800 |
| commit | 3a6a8eb2ec47e48793cb0eeb6ad6a39add834ae0 (patch) | |
| tree | 59f414083cc207c56f3bf4a0bea6f235df633efe /xmake/plugins | |
| parent | 48c0ae382d6a424f5f538d9180e913f903356325 (diff) | |
| parent | 1a60da326ee9217d17a27798bb479c72d3072d77 (diff) | |
Merge pull request #5210 from xmake-io/deb
Add deb pack
Diffstat (limited to 'xmake/plugins')
| -rw-r--r-- | xmake/plugins/pack/batchcmds.lua | 4 | ||||
| -rw-r--r-- | xmake/plugins/pack/deb/main.lua | 259 | ||||
| -rw-r--r-- | xmake/plugins/pack/nsis/main.lua | 4 | ||||
| -rw-r--r-- | xmake/plugins/pack/runself/main.lua | 4 | ||||
| -rw-r--r-- | xmake/plugins/pack/srpm/main.lua | 4 | ||||
| -rw-r--r-- | xmake/plugins/pack/wix/main.lua | 4 | ||||
| -rw-r--r-- | xmake/plugins/pack/xpack.lua | 43 |
7 files changed, 298 insertions, 24 deletions
diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 3d9229cce..8091134b2 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -186,13 +186,13 @@ end -- on install source target command function _on_target_installcmd_source(target, batchcmds_, opt) local package = opt.package - batchcmds_:vrunv("xmake", {"install", "-o", path(package:install_rootdir()), target:name()}) + batchcmds_:vrunv("xmake", {"install", "-P", ".", "-y", "-o", path(package:install_rootdir()), target:name()}) end -- on build target command function _on_target_buildcmd(target, batchcmds_, opt) local package = opt.package - batchcmds_:vrunv("xmake", {"build", "-y", target:name()}) + batchcmds_:vrunv("xmake", {"build", "-P", ".", "-y", target:name()}) end -- on install target command diff --git a/xmake/plugins/pack/deb/main.lua b/xmake/plugins/pack/deb/main.lua new file mode 100644 index 000000000..680531ff6 --- /dev/null +++ b/xmake/plugins/pack/deb/main.lua @@ -0,0 +1,259 @@ +--!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("core.base.hashset") +import("lib.detect.find_tool") +import("lib.detect.find_file") +import("utils.archive") +import(".batchcmds") + +-- get the debuild +function _get_debuild() + local debuild = find_tool("debuild", {force = true}) + assert(debuild, "debuild not found!") + return debuild +end + +-- get archive file +function _get_archivefile(package) + return path.absolute(path.join(path.directory(package:sourcedir()), package:name() .. "_" .. package:version() .. ".orig.tar.gz")) +end + +-- translate the file path +function _translate_filepath(package, filepath) + return filepath:replace(package:install_rootdir(), "$(PREFIX)", {plain = true}) +end + +-- get install command +function _get_customcmd(package, installcmds, 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 = _translate_filepath(package, 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 + table.insert(installcmds, string.format("install -Dpm0644 \"%s\" \"%s\"", srcfile, dstfile)) + end + elseif kind == "rm" then + local filepath = _translate_filepath(package, cmd.filepath) + table.insert(installcmds, string.format("rm -f \"%s\"", filepath)) + elseif kind == "rmdir" then + local dir = _translate_filepath(package, cmd.dir) + table.insert(installcmds, string.format("rm -rf \"%s\"", dir)) + elseif kind == "mv" then + local srcpath = _translate_filepath(package, cmd.srcpath) + local dstpath = _translate_filepath(package, cmd.dstpath) + table.insert(installcmds, string.format("mv \"%s\" \"%s\"", srcfile, dstfile)) + elseif kind == "cd" then + local dir = _translate_filepath(package, cmd.dir) + table.insert(installcmds, string.format("cd \"%s\"", dir)) + elseif kind == "mkdir" then + local dir = _translate_filepath(package, cmd.dir) + table.insert(installcmds, string.format("mkdir -p \"%s\"", dir)) + elseif cmd.program then + local argv = {} + for _, arg in ipairs(cmd.argv) do + if path.instance_of(arg) then + arg = arg:clone():set(_translate_filepath(package, arg:rawstr())):str() + elseif path.is_absolute(arg) then + arg = _translate_filepath(package, arg) + end + table.insert(argv, arg) + end + table.insert(installcmds, string.format("%s", os.args(table.join(cmd.program, argv)))) + end +end + +-- get build commands +function _get_buildcmds(package, buildcmds, cmds) + for _, cmd in ipairs(cmds) do + _get_customcmd(package, buildcmds, cmd) + end +end + +-- get install commands +function _get_installcmds(package, installcmds, cmds) + for _, cmd in ipairs(cmds) do + _get_customcmd(package, installcmds, cmd) + end +end + +-- get uninstall commands +function _get_uninstallcmds(package, uninstallcmds, cmds) + for _, cmd in ipairs(cmds) do + _get_customcmd(package, uninstallcmds, cmd) + end +end + +-- get specvars +function _get_specvars(package) + local specvars = table.clone(package:specvars()) + local datestr = os.iorunv("date", {"-u", "+%a, %d %b %Y %H:%M:%S +0000"}, {envs = {LC_TIME = "en_US"}}) + if datestr then + datestr = datestr:trim() + end + specvars.PACKAGE_DATE = datestr or "" + local author = package:get("author") or "unknown <[email protected]>" + specvars.PACKAGE_COPYRIGHT = os.date("%Y") .. " " .. author + specvars.PACKAGE_INSTALLCMDS = function () + local prefixdir = package:get("prefixdir") + package:set("prefixdir", nil) + local installcmds = {} + _get_installcmds(package, installcmds, batchcmds.get_installcmds(package):cmds()) + for _, component in table.orderpairs(package:components()) do + if component:get("default") ~= false then + _get_installcmds(package, installcmds, batchcmds.get_installcmds(component):cmds()) + end + end + package:set("prefixdir", prefixdir) + return table.concat(installcmds, "\n\t") + end + specvars.PACKAGE_UNINSTALLCMDS = function () + local uninstallcmds = {} + _get_uninstallcmds(package, uninstallcmds, batchcmds.get_uninstallcmds(package):cmds()) + for _, component in table.orderpairs(package:components()) do + if component:get("default") ~= false then + _get_uninstallcmds(package, uninstallcmds, batchcmds.get_uninstallcmds(component):cmds()) + end + end + return table.concat(uninstallcmds, "\n\t") + end + specvars.PACKAGE_BUILDCMDS = function () + local buildcmds = {} + _get_buildcmds(package, buildcmds, batchcmds.get_buildcmds(package):cmds()) + return table.concat(buildcmds, "\n\t") + end + specvars.PACKAGE_BUILDREQUIRES = function () + local requires = {} + local buildrequires = package:get("buildrequires") + if buildrequires then + for _, buildrequire in ipairs(buildrequires) do + table.insert(requires, buildrequire) + end + else + local programs = hashset.new() + for _, cmd in ipairs(batchcmds.get_buildcmds(package):cmds()) do + local program = cmd.program + if program then + programs:insert(program) + end + end + local map = { + xmake = "xmake", + cmake = "cmake", + make = "make" + } + for _, program in programs:keys() do + local requirename = map[program] + if requirename then + table.insert(requires, requirename) + end + end + end + return table.concat(requires, ", ") + end + return specvars +end + +-- pack deb package +function _pack_deb(debuild, package) + + -- install the initial debian directory + local sourcedir = package:sourcedir() + local debiandir = path.join(sourcedir, "debian") + if not os.isdir(debiandir) then + local debiandir_template = package:get("specfile") or path.join(os.programdir(), "scripts", "xpack", "deb", "debian") + os.cp(debiandir_template, debiandir) + end + + -- replace variables in specfile + local specvars = _get_specvars(package) + local pattern = package:extraconf("specfile", "pattern") or "%${([^\n]-)}" + for _, specfile in ipairs(os.files(path.join(debiandir, "**"))) do + 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("[%s]: > replace %s -> %s", path.filename(specfile), name, value) + end + if type(value) == "table" then + dprint("invalid variable value", value) + end + return value + end) + 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 + + -- archive install files + local rootdir = package:source_rootdir() + local oldir = os.cd(rootdir) + local archivefiles = os.files("**") + os.cd(oldir) + local archivefile = _get_archivefile(package) + os.tryrm(archivefile) + archive.archive(archivefile, archivefiles, {curdir = rootdir, compress = "best"}) + + -- build package + os.vrunv(debuild, {"-us", "-uc"}, {curdir = sourcedir}) + + -- copy deb file + os.vcp(path.join(path.directory(sourcedir), "*.deb"), package:outputfile()) +end + +function main(package) + if not is_host("linux") then + return + end + + cprint("packing %s", package:outputfile()) + + -- get debuild + local debuild = _get_debuild() + + -- pack deb package + _pack_deb(debuild.program, package) +end diff --git a/xmake/plugins/pack/nsis/main.lua b/xmake/plugins/pack/nsis/main.lua index b8f6d4dc4..c24c718fe 100644 --- a/xmake/plugins/pack/nsis/main.lua +++ b/xmake/plugins/pack/nsis/main.lua @@ -250,9 +250,9 @@ end function _pack_nsis(makensis, package) -- install the initial specfile - local specfile = package:specfile() + local specfile = path.join(package:buildir(), package:basename() .. ".nsi") if not os.isfile(specfile) then - local specfile_template = path.join(os.programdir(), "scripts", "xpack", "nsis", "makensis.nsi") + local specfile_template = package:get("specfile") or path.join(os.programdir(), "scripts", "xpack", "nsis", "makensis.nsi") os.cp(specfile_template, specfile) end diff --git a/xmake/plugins/pack/runself/main.lua b/xmake/plugins/pack/runself/main.lua index 8f25c3e80..eb5c01fb1 100644 --- a/xmake/plugins/pack/runself/main.lua +++ b/xmake/plugins/pack/runself/main.lua @@ -108,9 +108,9 @@ end function _pack_runself(makeself, package) -- install the initial specfile - local specfile = package:specfile() + local specfile = path.join(package:buildir(), package:basename() .. ".lsm") if not os.isfile(specfile) then - local specfile_template = path.join(os.programdir(), "scripts", "xpack", "runself", "makeself.lsm") + local specfile_template = package:get("specfile") or path.join(os.programdir(), "scripts", "xpack", "runself", "makeself.lsm") os.cp(specfile_template, specfile) end diff --git a/xmake/plugins/pack/srpm/main.lua b/xmake/plugins/pack/srpm/main.lua index b6b5467c8..e8630ba58 100644 --- a/xmake/plugins/pack/srpm/main.lua +++ b/xmake/plugins/pack/srpm/main.lua @@ -202,9 +202,9 @@ function _pack_srpm(rpmbuild, package) end -- install the initial specfile - local specfile = package:specfile() + local specfile = path.join(package:buildir(), package:basename() .. ".spec") if not os.isfile(specfile) then - local specfile_template = path.join(os.programdir(), "scripts", "xpack", "srpm", "srpm.spec") + local specfile_template = package:get("specfile") or path.join(os.programdir(), "scripts", "xpack", "srpm", "srpm.spec") os.cp(specfile_template, specfile) end diff --git a/xmake/plugins/pack/wix/main.lua b/xmake/plugins/pack/wix/main.lua index 95b6a4a7f..a99ecdb6e 100644 --- a/xmake/plugins/pack/wix/main.lua +++ b/xmake/plugins/pack/wix/main.lua @@ -258,9 +258,9 @@ end function _pack_wix(wix, package) -- install the initial specfile - local specfile = package:specfile() + local specfile = path.join(package:buildir(), package:basename() .. ".wxs") if not os.isfile(specfile) then - local specfile_template = path.join(os.programdir(), "scripts", "xpack", "wix", "msi.wxs") + local specfile_template = package:get("specfile") or path.join(os.programdir(), "scripts", "xpack", "wix", "msi.wxs") os.cp(specfile_template, specfile) end diff --git a/xmake/plugins/pack/xpack.lua b/xmake/plugins/pack/xpack.lua index 8af36cdd9..89ee5a54b 100644 --- a/xmake/plugins/pack/xpack.lua +++ b/xmake/plugins/pack/xpack.lua @@ -206,6 +206,24 @@ function xpack:inputkind() return inputkind end +-- get the output kind +function xpack:outputkind() + local outputkinds = { + wix = "binary", + nsis = "binary", + zip = "binary", + targz = "binary", + srczip = "source", + srctargz = "source", + runself = "source", + deb = "binary", + srpm = "source", + rpm = "binary" + } + local outputkind = outputkinds[self:format()] or "binary" + return outputkind +end + -- pack from source files? function xpack:from_source() return self:inputkind() == "source" @@ -216,6 +234,16 @@ function xpack:from_binary() return self:inputkind() == "binary" end +-- pack with source files? +function xpack:with_source() + return self:outputkind() == "source" +end + +-- pack with binary files? +function xpack:with_binary() + return self:outputkind() == "binary" +end + -- get the build directory function xpack:buildir() return path.join(config.buildir(), ".xpack", self:name()) @@ -235,7 +263,7 @@ function xpack:basename() local basename = option.get("basename") or self:get("basename") if basename == nil then basename = self:name() - if self:from_source() then + if self:with_source() then basename = basename .. "-src" end local version = self:version() @@ -319,19 +347,6 @@ function xpack:specvars() return specvars end --- get the specfile path -function xpack:specfile() - local extensions = { - wix = ".wxs", - nsis = ".nsi", - srpm = ".spec", - rpm = ".spec", - runself = ".lsm" - } - local extension = extensions[self:format()] or ".spec" - return self:get("specfile") or path.join(self:buildir(), self:basename() .. extension) -end - -- get the extension function xpack:extension() local extension = self:get("extension") |
