Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deb pack #5210

Merged
merged 23 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### New features

* [#4637](https://github.com/xmake-io/xmake/issues/4637): Add mix generator for xpack
* [#5107](https://github.com/xmake-io/xmake/issues/5107): Add deb generator for xpack
* [#5148](https://github.com/xmake-io/xmake/issues/5148): Add on_source in package

### Changes
Expand Down Expand Up @@ -1828,6 +1829,7 @@
### 新特性

* [#4637](https://github.com/xmake-io/xmake/issues/4637): 为 xpack 添加 mix 支持
* [#5107](https://github.com/xmake-io/xmake/issues/5107): 为 xpack 添加 deb 支持
* [#5148](https://github.com/xmake-io/xmake/issues/5148): 为包添加 on_source 配置域

### 改进
Expand Down
10 changes: 5 additions & 5 deletions core/xpack.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ xpack("xmake")
set_title("Xmake build utility ($(arch))")
set_description("A cross-platform build utility based on Lua.")
set_copyright("Copyright (C) 2015-present, TBOOX Open Source Group")
set_author("waruqi@gmail.com")
set_author("ruki <waruqi@gmail.com>")
set_licensefile("../LICENSE.md")
set_formats("nsis", "wix", "zip")
add_targets("demo")
Expand Down Expand Up @@ -81,8 +81,8 @@ xpack("xmakesrc")
set_title("Xmake build utility ($(arch))")
set_description("A cross-platform build utility based on Lua.")
set_copyright("Copyright (C) 2015-present, TBOOX Open Source Group")
set_author("waruqi@gmail.com")
set_formats("srczip", "srctargz", "runself", "srpm")
set_author("ruki <waruqi@gmail.com>")
set_formats("srczip", "srctargz", "runself", "srpm", "deb")
set_basename("xmake-v$(version)")
set_prefixdir("xmake-$(version)")
set_license("Apache-2.0")
Expand Down Expand Up @@ -115,7 +115,7 @@ xpack("xmakesrc")

on_buildcmd(function (package, batchcmds)
local format = package:format()
if format == "srpm" then
if format == "srpm" or format == "deb" then
batchcmds:runv("./configure")
batchcmds:runv("make")
end
Expand All @@ -125,7 +125,7 @@ xpack("xmakesrc")
local format = package:format()
if format == "runself" then
batchcmds:runv("./scripts/get.sh", {"__local__"})
elseif format == "srpm" then
elseif format == "srpm" or format == "deb" then
batchcmds:runv("make", {"install", path(package:install_rootdir(), function (p) return "PREFIX=" .. p end)})
end
end)
6 changes: 3 additions & 3 deletions tests/plugins/pack/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ target("foo")
add_packages("zlib")

xpack("test")
set_formats("nsis", "srpm", "rpm", "zip", "targz", "srczip", "srctargz", "runself", "wix")
set_formats("nsis", "srpm", "rpm", "deb", "zip", "targz", "srczip", "srctargz", "runself", "wix")
set_title("hello")
set_author("ruki")
set_author("ruki <waruqi@gmail.com>")
set_description("A test installer.")
set_homepage("https://xmake.io")
set_license("Apache-2.0")
Expand All @@ -34,7 +34,7 @@ xpack("test")
add_components("LongPath")

on_load(function (package)
if package:from_source() then
if package:with_source() then
package:set("basename", "test-$(plat)-src-v$(version)")
else
package:set("basename", "test-$(plat)-$(arch)-v$(version)")
Expand Down
4 changes: 2 additions & 2 deletions xmake/plugins/pack/batchcmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
259 changes: 259 additions & 0 deletions xmake/plugins/pack/deb/main.lua
Original file line number Diff line number Diff line change
@@ -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 <unknown@unknown.com>"
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
4 changes: 2 additions & 2 deletions xmake/plugins/pack/nsis/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions xmake/plugins/pack/runself/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions xmake/plugins/pack/srpm/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions xmake/plugins/pack/wix/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading
Loading