summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-02-24 23:51:29 +0800
committerGitHub <[email protected]>2025-02-24 23:51:29 +0800
commit4577f235397d28436948a5366d3cebe8b032a2b2 (patch)
tree6a99722c1291f2f6dc0f34d8163eae4f1b377ea0
parent8ebd43d4cea3fc9e9d559e5d3069c08f20c2981c (diff)
parent532cb13b86bc77ebcbfb48a7144a8770bd42750e (diff)
Merge pull request #6168 from 24bit-xjkp/dev
feat(utils.archive): Add zstd support for utils.archive
-rw-r--r--xmake/modules/detect/tools/find_zstd.lua54
-rw-r--r--xmake/modules/utils/archive/extension.lua4
-rw-r--r--xmake/modules/utils/archive/extract.lua96
3 files changed, 115 insertions, 39 deletions
diff --git a/xmake/modules/detect/tools/find_zstd.lua b/xmake/modules/detect/tools/find_zstd.lua
new file mode 100644
index 000000000..fbfcefb4e
--- /dev/null
+++ b/xmake/modules/detect/tools/find_zstd.lua
@@ -0,0 +1,54 @@
+--!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 24bit-xjkp
+-- @file find_xz.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find zstd
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local zstd = find_zstd()
+-- local zstd, version = find_zstd({version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "zstd", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/utils/archive/extension.lua b/xmake/modules/utils/archive/extension.lua
index bee957f65..e2b5bf568 100644
--- a/xmake/modules/utils/archive/extension.lua
+++ b/xmake/modules/utils/archive/extension.lua
@@ -27,9 +27,9 @@ function main(archivefile)
local filename = path.filename(archivefile)
local extensionset = hashset.from({
".xmz", -- xmake compression format
- ".zip", ".7z", ".gz", ".xz", ".tgz",
+ ".zip", ".7z", ".gz", ".xz", ".zst", ".tgz",
".bz2", ".tar", ".tar.gz", ".tar.xz",
- ".tar.bz2", ".tar.Z"})
+ ".tar.zst", ".tar.bz2", ".tar.Z"})
local i = filename:lastof(".", true)
if i then
local p = filename:sub(1, i - 1):lastof(".", true)
diff --git a/xmake/modules/utils/archive/extract.lua b/xmake/modules/utils/archive/extract.lua
index 269c3cd59..75c64405a 100644
--- a/xmake/modules/utils/archive/extract.lua
+++ b/xmake/modules/utils/archive/extract.lua
@@ -23,6 +23,7 @@ import("core.base.option")
import("lib.detect.find_file")
import("lib.detect.find_tool")
import("detect.tools.find_xz")
+import("detect.tools.find_zstd")
import("detect.tools.find_7z")
import("detect.tools.find_tar")
import("detect.tools.find_gzip")
@@ -171,13 +172,7 @@ function _extract_using_7z(archivefile, outputdir, extension, opt)
os.tryrm(path.join(outputdir, "*.paxheader"))
end
- -- continue to extract *.tar file
- if outputdir_old then
- local tarfile = find_file("**.tar", outputdir)
- if tarfile and os.isfile(tarfile) then
- return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
- end
- end
+ _extract_uncompressed_tar(outputdir_old, outputdir, opt)
return true
end
@@ -220,13 +215,7 @@ function _extract_using_gzip(archivefile, outputdir, extension, opt)
-- extract it
os.vrunv(program, argv, {curdir = outputdir})
- -- continue to extract *.tar file
- if outputdir_old then
- local tarfile = find_file("**.tar", outputdir)
- if tarfile and os.isfile(tarfile) then
- return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
- end
- end
+ _extract_uncompressed_tar(outputdir_old, outputdir, opt)
return true
end
@@ -269,13 +258,50 @@ function _extract_using_xz(archivefile, outputdir, extension, opt)
-- extract it
os.vrunv(program, argv, {curdir = outputdir})
- -- continue to extract *.tar file
- if outputdir_old then
- local tarfile = find_file("**.tar", outputdir)
- if tarfile and os.isfile(tarfile) then
- return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
- end
+ _extract_uncompressed_tar(outputdir_old, outputdir, opt)
+ return true
+end
+
+-- extract archivefile using zstd
+function _extract_using_zstd(archivefile, outputdir, extension, opt)
+
+ -- find zstd
+ local program = find_zstd()
+ if not program then
+ return false
+ end
+
+ -- extract to *.tar file first
+ local outputdir_old = nil
+ if extension:startswith(".tar.") then
+ outputdir_old = outputdir
+ outputdir = os.tmpfile({ramdisk = false}) .. ".tar"
+ end
+
+ -- init temporary archivefile
+ local tmpfile = path.join(outputdir, path.filename(archivefile))
+
+ -- init argv
+ local argv = {"-d"}
+ if not option.get("verbose") then
+ table.insert(argv, "-q")
end
+ table.insert(argv, tmpfile)
+
+ -- ensure output directory
+ if not os.isdir(outputdir) then
+ os.mkdir(outputdir)
+ end
+
+ -- copy archivefile to outputdir first
+ if path.absolute(archivefile) ~= path.absolute(tmpfile) then
+ os.cp(archivefile, tmpfile)
+ end
+
+ -- extract it
+ os.vrunv(program, argv, {curdir = outputdir})
+
+ _extract_uncompressed_tar(outputdir_old, outputdir, opt)
return true
end
@@ -322,13 +348,7 @@ function _extract_using_unzip(archivefile, outputdir, extension, opt)
-- extract it
os.vrunv(program, argv)
- -- continue to extract *.tar file
- if outputdir_old then
- local tarfile = find_file("**.tar", outputdir)
- if tarfile and os.isfile(tarfile) then
- return _extract(tarfile, outputdir_old, ".tar", {_extract_using_tar, _extract_using_7z}, opt)
- end
- end
+ _extract_uncompressed_tar(outputdir_old, outputdir, opt)
return true
end
@@ -361,13 +381,7 @@ function _extract_using_powershell(archivefile, outputdir, extension, opt)
local argv = {"-ExecutionPolicy", "Bypass", "-File", scriptfile, archivefile, outputdir}
os.vrunv(powershell.program, argv)
- -- continue to extract *.tar file
- if outputdir_old then
- local tarfile = find_file("**.tar", outputdir)
- if tarfile and os.isfile(tarfile) then
- return _extract(tarfile, outputdir_old, ".tar", {_extract_using_tar, _extract_using_7z}, opt)
- end
- end
+ _extract_uncompressed_tar(outputdir_old, outputdir, opt)
return true
end
@@ -416,14 +430,18 @@ function _extract_using_bzip2(archivefile, outputdir, extension, opt)
-- extract it
os.vrunv(program, argv, {curdir = outputdir})
- -- continue to extract *.tar file
+ _extract_uncompressed_tar(outputdir_old, outputdir, opt)
+ return true
+end
+
+-- extract *.tar after decompress
+function _extract_uncompressed_tar(outputdir_old, outputdir, opt)
if outputdir_old then
local tarfile = find_file("**.tar", outputdir)
if tarfile and os.isfile(tarfile) then
return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
end
end
- return true
end
-- extract archive file using extractors
@@ -464,18 +482,21 @@ function main(archivefile, outputdir, opt)
if is_subhost("windows") then
-- we use 7z first, becase xmake package has builtin 7z program on windows
-- tar/windows can not extract .bz2 ...
+ -- 7z doesn't support zstd by default
extractors =
{
[".zip"] = {_extract_using_7z, _extract_using_unzip, _extract_using_tar, _extract_using_powershell}
, [".7z"] = {_extract_using_7z}
, [".gz"] = {_extract_using_7z, _extract_using_gzip, _extract_using_tar}
, [".xz"] = {_extract_using_7z, _extract_using_xz, _extract_using_tar}
+ , [".zst"] = {_extract_using_zstd, _extract_using_tar}
, [".tgz"] = {_extract_using_7z, _extract_using_tar}
, [".bz2"] = {_extract_using_7z, _extract_using_bzip2}
, [".tar"] = {_extract_using_7z, _extract_using_tar}
-- @see https://github.com/xmake-io/xmake/issues/5538
, [".tar.gz"] = {_extract_using_tar, _extract_using_7z, _extract_using_gzip}
, [".tar.xz"] = {_extract_using_7z, _extract_using_xz}
+ , [".tar.zst"] = {_extract_using_zstd}
, [".tar.bz2"] = {_extract_using_7z, _extract_using_bzip2}
, [".tar.lz"] = {_extract_using_7z}
, [".tar.Z"] = {_extract_using_7z}
@@ -489,11 +510,13 @@ function main(archivefile, outputdir, opt)
, [".7z"] = {_extract_using_7z}
, [".gz"] = {_extract_using_gzip, _extract_using_tar, _extract_using_7z}
, [".xz"] = {_extract_using_xz, _extract_using_tar, _extract_using_7z}
+ , [".zst"] = {_extract_using_zstd, _extract_using_tar}
, [".tgz"] = {_extract_using_tar, _extract_using_7z}
, [".bz2"] = {_extract_using_bzip2, _extract_using_tar, _extract_using_7z}
, [".tar"] = {_extract_using_tar, _extract_using_7z}
, [".tar.gz"] = {_extract_using_tar, _extract_using_7z, _extract_using_gzip}
, [".tar.xz"] = {_extract_using_tar, _extract_using_7z, _extract_using_xz}
+ , [".tar.zst"] = {_extract_using_tar, _extract_using_zstd}
, [".tar.bz2"] = {_extract_using_tar, _extract_using_7z, _extract_using_bzip2}
, [".tar.lz"] = {_extract_using_tar, _extract_using_7z}
, [".tar.Z"] = {_extract_using_tar, _extract_using_7z}
@@ -507,4 +530,3 @@ function main(archivefile, outputdir, opt)
-- extract it
return _extract(archivefile, outputdir, extension, extractors[extension], opt)
end
-