diff options
| author | Ângelo Andrade Cirino <[email protected]> | 2022-01-10 10:23:17 -0300 |
|---|---|---|
| committer | Ângelo Andrade Cirino <[email protected]> | 2022-01-10 10:23:17 -0300 |
| commit | ed0c0c5e0249aa966ea7061b30710abdd0b09d87 (patch) | |
| tree | 2a51c869a3aea1a093ed569e749bdf0465634a6c /xmake/modules/utils | |
| parent | 885d00da8caf74aeed758d030b9a1b50d9078e1f (diff) | |
| parent | 2431dd7e6142ff98b55741cfd4de4d2e69f4f8b5 (diff) | |
Merged from upstream/master
Diffstat (limited to 'xmake/modules/utils')
| -rw-r--r-- | xmake/modules/utils/archive/extension.lua | 3 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/extract.lua | 77 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/merge_staticlib.lua | 73 | ||||
| -rw-r--r-- | xmake/modules/utils/progress.lua | 139 |
4 files changed, 241 insertions, 51 deletions
diff --git a/xmake/modules/utils/archive/extension.lua b/xmake/modules/utils/archive/extension.lua index 3a8554efd..fe33a395f 100644 --- a/xmake/modules/utils/archive/extension.lua +++ b/xmake/modules/utils/archive/extension.lua @@ -23,7 +23,6 @@ import("core.base.hashset") -- get the archive extension function main(archivefile) - local extension = "" local filename = path.filename(archivefile) local extensionset = hashset.from({".zip", ".7z", ".gz", ".xz", ".tgz", ".bz2", ".tar", ".tar.gz", ".tar.xz", ".tar.bz2"}) @@ -33,5 +32,5 @@ function main(archivefile) if p and extensionset:has(filename:sub(p)) then i = p end extension = filename:sub(i) end - return extension + return extensionset:has(extension) and extension or "" end diff --git a/xmake/modules/utils/archive/extract.lua b/xmake/modules/utils/archive/extract.lua index 4e54bc4dc..d4a41e542 100644 --- a/xmake/modules/utils/archive/extract.lua +++ b/xmake/modules/utils/archive/extract.lua @@ -43,16 +43,23 @@ function _extract_using_tar(archivefile, outputdir, extension, opt) return false end - -- on msys2/cygwin? we need translate input path to cygwin-like path - if is_subhost("msys", "cygwin") and program:gsub("\\", "/"):find("/usr/bin") then - archivefile = path.cygwin_path(archivefile) - end - -- init argv local argv = {} - if is_subhost("windows") then + if is_host("windows") then -- force "x:\\xx" as local file - table.insert(argv, "--force-local") + local force_local = _g.force_local + if force_local == nil then + force_local = try {function () + local result = os.iorunv(program, {"--help"}) + if result and result:find("--force-local", 1, true) then + return true + end + end} + _g.force_local = force_local or false + end + if force_local then + table.insert(argv, "--force-local") + end end table.insert(argv, option.get("verbose") and "-xvf" or "-xf") table.insert(argv, archivefile) @@ -78,14 +85,10 @@ function _extract_using_tar(archivefile, outputdir, extension, opt) -- extract it if is_host("windows") then - local oldir = os.cd(outputdir) - os.vrunv(program, argv) - os.cd(oldir) + os.vrunv(program, argv, {curdir = outputdir}) else os.vrunv(program, argv) end - - -- ok return true end @@ -98,6 +101,12 @@ function _extract_using_7z(archivefile, outputdir, extension, opt) return false end + -- p7zip cannot extract other archive format on msys/cygwin + -- https://github.com/xmake-io/xmake/issues/1575#issuecomment-898205462 + if is_subhost("msys", "cygwin") and extension ~= ".7z" and program:startswith("sh ") then + return false + end + -- extract to *.tar file first local outputdir_old = nil if extension:startswith(".tar.") or extension == ".tgz" then @@ -140,7 +149,7 @@ function _extract_using_7z(archivefile, outputdir, extension, opt) -- remove unused pax_global_header file after extracting .tar file if extension == ".tar" then os.tryrm(path.join(outputdir, "pax_global_header")) - os.tryrm(path.join(outputdir, "PaxHeaders.*")) + os.tryrm(path.join(outputdir, "PaxHeaders*")) os.tryrm(path.join(outputdir, "@PaxHeader")) end @@ -151,8 +160,6 @@ function _extract_using_7z(archivefile, outputdir, extension, opt) return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt) end end - - -- ok return true end @@ -192,14 +199,8 @@ function _extract_using_gzip(archivefile, outputdir, extension, opt) os.cp(archivefile, tmpfile) end - -- enter outputdir - local oldir = os.cd(outputdir) - -- extract it - os.vrunv(program, argv) - - -- leave outputdir - os.cd(oldir) + os.vrunv(program, argv, {curdir = outputdir}) -- continue to extract *.tar file if outputdir_old then @@ -208,8 +209,6 @@ function _extract_using_gzip(archivefile, outputdir, extension, opt) return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt) end end - - -- ok return true end @@ -249,14 +248,8 @@ function _extract_using_xz(archivefile, outputdir, extension, opt) os.cp(archivefile, tmpfile) end - -- enter outputdir - local oldir = os.cd(outputdir) - -- extract it - os.vrunv(program, argv) - - -- leave outputdir - os.cd(oldir) + os.vrunv(program, argv, {curdir = outputdir}) -- continue to extract *.tar file if outputdir_old then @@ -265,8 +258,6 @@ function _extract_using_xz(archivefile, outputdir, extension, opt) return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt) end end - - -- ok return true end @@ -320,8 +311,6 @@ function _extract_using_unzip(archivefile, outputdir, extension, opt) return _extract(tarfile, outputdir_old, ".tar", {_extract_using_tar, _extract_using_7z}, opt) end end - - -- ok return true end @@ -366,14 +355,8 @@ function _extract_using_bzip2(archivefile, outputdir, extension, opt) os.cp(archivefile, tmpfile) end - -- enter outputdir - local oldir = os.cd(outputdir) - -- extract it - os.vrunv(program, argv) - - -- leave outputdir - os.cd(oldir) + os.vrunv(program, argv, {curdir = outputdir}) -- continue to extract *.tar file if outputdir_old then @@ -382,22 +365,16 @@ function _extract_using_bzip2(archivefile, outputdir, extension, opt) return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt) end end - - -- ok return true end -- extract archive file using extractors function _extract(archivefile, outputdir, extension, extractors, opt) - - -- extract it for _, extract in ipairs(extractors) do if extract(archivefile, outputdir, extension, opt) then return true end end - - -- failed return false end @@ -417,7 +394,7 @@ function main(archivefile, outputdir, opt) -- init extractors local extractors - if is_host("windows") then + if is_subhost("windows") then -- we use 7z first, becase xmake package has builtin 7z program on windows -- tar/windows can not extract .bz2 ... extractors = @@ -432,6 +409,7 @@ function main(archivefile, outputdir, opt) , [".tar.gz"] = {_extract_using_7z, _extract_using_gzip} , [".tar.xz"] = {_extract_using_7z, _extract_using_xz} , [".tar.bz2"] = {_extract_using_7z, _extract_using_bzip2} + , [".tar.lz"] = {_extract_using_7z} } else extractors = @@ -446,6 +424,7 @@ function main(archivefile, outputdir, opt) , [".tar.gz"] = {_extract_using_tar, _extract_using_7z, _extract_using_gzip} , [".tar.xz"] = {_extract_using_tar, _extract_using_7z, _extract_using_xz} , [".tar.bz2"] = {_extract_using_tar, _extract_using_7z, _extract_using_bzip2} + , [".tar.lz"] = {_extract_using_tar, _extract_using_7z} } end diff --git a/xmake/modules/utils/archive/merge_staticlib.lua b/xmake/modules/utils/archive/merge_staticlib.lua new file mode 100644 index 000000000..dc0130219 --- /dev/null +++ b/xmake/modules/utils/archive/merge_staticlib.lua @@ -0,0 +1,73 @@ +--!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 merge_staticlib.lua +-- + +-- imports +import("core.base.option") +import("private.tools.vstool") + +-- merge *.a archive libraries for ar +function _merge_for_ar(target, program, outputfile, libraryfiles, opt) + opt = opt or {} + if target:is_plat("macosx", "iphoneos", "watchos", "appletvos") then + os.vrunv("libtool", table.join("-static", "-o", outputfile, libraryfiles)) + else + local tmpfile = os.tmpfile() + local mrifile = io.open(tmpfile, "w") + mrifile:print("create %s", outputfile) + for _, libraryfile in ipairs(libraryfiles) do + mrifile:print("addlib %s", libraryfile) + end + mrifile:print("save") + mrifile:print("end") + mrifile:close() + os.vrunv(program, {"-M"}, {stdin = tmpfile}) + os.rm(tmpfile) + end +end + +-- merge *.a archive libraries for msvc/lib.exe +function _merge_for_msvclib(target, program, outputfile, libraryfiles, opt) + opt = opt or {} + vstool.runv(program, table.join("-nologo", "-out:" .. outputfile, libraryfiles), {envs = opt.runenvs}) +end + +-- merge *.a archive libraries +function main(target, outputfile, libraryfiles) + local program, toolname = target:tool("ar") + if program and toolname then + if toolname:find("ar") then + _merge_for_ar(target, program, outputfile, libraryfiles) + elseif toolname == "link" and target:is_plat("windows") then + local msvc + for _, toolchain_inst in ipairs(target:toolchains()) do + if toolchain_inst:name() == "msvc" then + msvc = toolchain_inst + break + end + end + _merge_for_msvclib(target, (program:gsub("link%.exe", "lib.exe")), outputfile, libraryfiles, {runenvs = msvc and msvc:runenvs()}) + else + raise("cannot merge (%s): unknown ar tool %s!", table.concat(libraryfiles, ", "), toolname) + end + else + raise("cannot merge (%s): ar not found!", table.concat(libraryfiles, ", ")) + end +end + diff --git a/xmake/modules/utils/progress.lua b/xmake/modules/utils/progress.lua new file mode 100644 index 000000000..074046a69 --- /dev/null +++ b/xmake/modules/utils/progress.lua @@ -0,0 +1,139 @@ +--!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 OpportunityLiu +-- @file progress.lua +-- + +-- imports +import("core.base.option") +import("core.base.object") +import("core.base.colors") +import("core.base.tty") +import("core.theme.theme") + +-- define module +local process = process or object { _init = { "_RUNNING", "_INDEX", "_STREAM", "_OPT" } } + +-- stop the progress indicator, clear written frames +function process:stop() + if self._RUNNING ~= 0 then + self:clear() + self._RUNNING = 0 + self._INDEX = 0 + end +end + +function process:_clear() + if self._RUNNING == 1 then + tty.erase_line_to_end() + self._RUNNING = 2 + return true + end +end + +-- clear previous frame of the progress indicator +function process:clear() + if self:_clear() then + self._STREAM:flush() + end +end + +-- write next frame of the progress indicator +function process:write() + local chars = self._OPT.chars[self._INDEX % #self._OPT.chars + 1] + tty.cursor_and_attrs_save() + self._STREAM:write(chars) + self._STREAM:flush() + tty.cursor_and_attrs_restore() + self._INDEX = self._INDEX + 1 + self._RUNNING = 1 +end + +-- check if the progress indicator is running +function process:running() + return self._RUNNING and true or false +end + +-- showing progress line without scroll? +function showing_without_scroll() + return _g.showing_without_scroll +end + +-- show the message with process +function show(progress, format, ...) + progress = math.floor(progress) + local progress_prefix = "${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} " + if option.get("verbose") then + cprint(progress_prefix .. "${dim}" .. format, progress, ...) + else + local is_scroll = _g.is_scroll + if is_scroll == nil then + is_scroll = theme.get("text.build.progress_style") == "scroll" + _g.is_scroll = is_scroll + end + if is_scroll then + cprint(progress_prefix .. format, progress, ...) + else + tty.erase_line_to_start().cr() + local msg = vformat(progress_prefix .. format, progress, ...) + local msg_plain = colors.translate(msg, {plain = true}) + local maxwidth = os.getwinsize().width + if #msg_plain <= maxwidth then + cprintf(msg) + else + -- windows width is too small? strip the partial message in middle + local partlen = math.floor(maxwidth / 2) - 3 + local sep = msg_plain:sub(partlen + 1, #msg_plain - partlen - 1) + local split = msg:split(sep, {plain = true, strict = true}) + cprintf(table.concat(split, "...")) + end + if math.floor(progress) == 100 then + print("") + _g.showing_without_scroll = false + else + _g.showing_without_scroll = true + end + io.flush() + end + end +end + +-- get the message text with process +function text(progress, format, ...) + progress = math.floor(progress) + local progress_prefix = "${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} " + if option.get("verbose") then + return string.format(progress_prefix .. "${dim}" .. format, progress, ...) + else + return string.format(progress_prefix .. format, progress, ...) + end +end + +-- build a progress indicator +-- @params stream - stream to write to, will use io.stdout if not provided +-- @params opt - options +-- - chars - an array of chars for progress indicator +function new(stream, opt) + + -- set default values + stream = stream or io.stdout + opt = opt or {} + if opt.chars == nil or #opt.chars == 0 then + opt.chars = theme.get("text.spinner.chars") + end + return process {_OPT = opt, _STREAM = stream, _RUNNING = 0, _INDEX = 0} +end |
