diff options
| author | ruki <[email protected]> | 2021-03-02 00:32:14 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2021-03-02 00:32:14 +0800 |
| commit | 8f0fee2899d3fdbca259f32acb068b3a4a45bec6 (patch) | |
| tree | 5810513c8ffd13fcced87dbfecbbf6b0bb1b8497 | |
| parent | cbaf212c6befb4e8974aa49be12a99a9fe316f46 (diff) | |
improve to find_7z and add bzip2
| -rw-r--r-- | xmake/core/base/os.lua | 14 | ||||
| -rw-r--r-- | xmake/core/base/path.lua | 10 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/lib/detect/find_program.lua | 62 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_7z.lua | 2 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_bzip2.lua | 55 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/extract.lua | 83 |
6 files changed, 187 insertions, 39 deletions
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index ff79aeb96..5f116c35a 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -817,15 +817,17 @@ function os.isexec(filepath) -- TODO -- check permission - -- is *.exe for windows? + -- check executable program exist + if os.isfile(filepath) then + return true + end if os.host() == "windows" then - if not filepath:endswith(".exe") and not filepath:endswith(".cmd") and not filepath:endswith(".bat") then - filepath = filepath .. ".exe" + for _, suffix in ipairs({".exe", ".cmd", ".bat"}) do + if os.isfile(filepath .. suffix) then + return true + end end end - - -- file exists? - return os.isfile(filepath) end -- get system host diff --git a/xmake/core/base/path.lua b/xmake/core/base/path.lua index 494961c09..aa0cd571a 100644 --- a/xmake/core/base/path.lua +++ b/xmake/core/base/path.lua @@ -197,5 +197,15 @@ function path.pattern(pattern) return pattern end +-- get cygwin-style path on msys2/cygwin, e.g. "c:\xxx" -> "/c/xxx" +function path.cygwin_path(p) + p = p:gsub("\\", "/") + local pos = p:find(":/") + if pos == 2 then + return "/" .. p:sub(1, 1) .. p:sub(3) + end + return p +end + -- return module: path return path diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua index 6fe7d845f..01b423f10 100644 --- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua +++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua @@ -39,19 +39,12 @@ local scheduler = require("sandbox/modules/import/core/base/scheduler") -- globals local checking = nil --- check program -function sandbox_lib_detect_find_program._check(program, opt) - - -- is *.exe for windows? - if os.host() == "windows" then - if not program:endswith(".exe") and not program:endswith(".cmd") and not program:endswith(".bat") then - program = program .. ".exe" - end - end +-- do check +function sandbox_lib_detect_find_program._do_check(program, opt) -- do not attempt to run program? check it fastly if opt.norun then - return os.isfile(program) + return os.isfile(program) and program or nil end -- no check script? attempt to run it directly @@ -60,7 +53,7 @@ function sandbox_lib_detect_find_program._check(program, opt) if not ok and option.get("verbose") and option.get("diagnosis") then utils.cprint("${color.warning}checkinfo: ${clear dim}" .. errors) end - return ok + return ok and program or nil end -- check it @@ -76,7 +69,21 @@ function sandbox_lib_detect_find_program._check(program, opt) if not ok and option.get("verbose") and option.get("diagnosis") then utils.cprint("${color.warning}checkinfo: ${clear dim}" .. errors) end - return ok + return ok and program or nil +end + +-- check program +function sandbox_lib_detect_find_program._check(program, opt) + if os.subhost() == "windows" then + if not program:endswith(".exe") and not program:endswith(".cmd") and not program:endswith(".bat") then + program = program .. ".exe" + end + elseif os.subhost() == "msys" and os.isfile(program) and os.filesize(program) < 256 then + -- only a sh script on msys2? e.g. c:/msys64/usr/bin/7z + -- we need use sh to wrap it, otherwise os.exec cannot run it + program = "sh " .. program + end + return sandbox_lib_detect_find_program._do_check(program, opt) end -- find program from the given paths @@ -114,9 +121,9 @@ function sandbox_lib_detect_find_program._find_from_paths(name, paths, opt) -- the program path if program_path and (os.isexec(program_path) or os.isexec(program_path:split("%s")[1])) then - -- check it - if sandbox_lib_detect_find_program._check(program_path, opt) then - return program_path + local program_path_real = sandbox_lib_detect_find_program._check(program_path, opt) + if program_path_real then + return program_path_real end end end @@ -174,11 +181,11 @@ function sandbox_lib_detect_find_program._find(name, paths, opt) end program_path = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" .. program_name) if program_path then - -- check it program_path = program_path:trim() if os.isexec(program_path) then - if sandbox_lib_detect_find_program._check(program_path, opt) then - return program_path + local program_path_real = sandbox_lib_detect_find_program._check(program_path, opt) + if program_path_real then + return program_path_real end end end @@ -186,18 +193,20 @@ function sandbox_lib_detect_find_program._find(name, paths, opt) -- attempt to find it use `which program` command local ok, program_path = os.iorunv("which", {name}) if ok and program_path then - -- check it program_path = program_path:trim() - if os.isexec(program_path) then - if sandbox_lib_detect_find_program._check(program_path, opt) then - return program_path - end + local program_path_real = sandbox_lib_detect_find_program._check(program_path, opt) + if program_path_real then + return program_path_real end end end - -- attempt to find it from the some default system directories + -- attempt to find it from the some default $PATH and system directories local syspaths = {} + local envpaths = os.getenv("PATH") + if envpaths then + table.join2(syspaths, path.splitenv(envpaths)) + end if os.host() ~= "windows" then table.insert(syspaths, "/usr/local/bin") table.insert(syspaths, "/usr/bin") @@ -213,8 +222,9 @@ function sandbox_lib_detect_find_program._find(name, paths, opt) -- -- @note must be detected at the end, because full path is more accurate -- - if sandbox_lib_detect_find_program._check(name, opt) then - return name + local program_path_real = sandbox_lib_detect_find_program._check(name, opt) + if program_path_real then + return program_path_real end end diff --git a/xmake/modules/detect/tools/find_7z.lua b/xmake/modules/detect/tools/find_7z.lua index a53ba4dc1..b441c2200 100644 --- a/xmake/modules/detect/tools/find_7z.lua +++ b/xmake/modules/detect/tools/find_7z.lua @@ -60,7 +60,5 @@ function main(opt) if program and opt and opt.version then version = find_programver(program, opt) end - - -- ok? return program, version end diff --git a/xmake/modules/detect/tools/find_bzip2.lua b/xmake/modules/detect/tools/find_bzip2.lua new file mode 100644 index 000000000..a1544dd4a --- /dev/null +++ b/xmake/modules/detect/tools/find_bzip2.lua @@ -0,0 +1,55 @@ +--!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 find_bzip2.lua +-- + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") + +-- find bzip2 +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local bzip2 = find_bzip2() +-- local bzip2, version = find_bzip2({version = true}) +-- +-- @endcode +-- +function main(opt) + + -- init options + opt = opt or {} + opt.check = opt.check or "--help" + opt.command = opt.command or "--help" + opt.parse = "(%d+%.?%d*)%s" + + -- find program + local program = find_program(opt.program or "bzip2", opt) + + -- find program version + local version = nil + if program and opt and opt.version then + version = find_programver(program, opt) + end + return program, version +end diff --git a/xmake/modules/utils/archive/extract.lua b/xmake/modules/utils/archive/extract.lua index d94d67cc5..4e54bc4dc 100644 --- a/xmake/modules/utils/archive/extract.lua +++ b/xmake/modules/utils/archive/extract.lua @@ -26,6 +26,7 @@ import("detect.tools.find_7z") import("detect.tools.find_tar") import("detect.tools.find_gzip") import("detect.tools.find_unzip") +import("detect.tools.find_bzip2") import("extension", {alias = "get_archive_extension"}) -- extract archivefile using tar @@ -42,6 +43,11 @@ 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 @@ -99,6 +105,11 @@ function _extract_using_7z(archivefile, outputdir, extension, opt) outputdir = os.tmpfile({ramdisk = false}) .. ".tar" 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 = {"x", "-y", archivefile} @@ -314,6 +325,68 @@ function _extract_using_unzip(archivefile, outputdir, extension, opt) return true end +-- extract archivefile using bzip2 +function _extract_using_bzip2(archivefile, outputdir, extension, opt) + + -- find bzip2 + local program = find_bzip2() + 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 + + -- 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 temporary archivefile + local tmpfile = path.join(outputdir, path.filename(archivefile)) + + -- init argv + local argv = {"-d", "-f"} + 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 + + -- enter outputdir + local oldir = os.cd(outputdir) + + -- extract it + os.vrunv(program, argv) + + -- leave outputdir + os.cd(oldir) + + -- 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 + + -- ok + return true +end + -- extract archive file using extractors function _extract(archivefile, outputdir, extension, extractors, opt) @@ -346,6 +419,7 @@ function main(archivefile, outputdir, opt) local extractors if is_host("windows") then -- we use 7z first, becase xmake package has builtin 7z program on windows + -- tar/windows can not extract .bz2 ... extractors = { [".zip"] = {_extract_using_7z, _extract_using_unzip, _extract_using_tar} @@ -353,12 +427,11 @@ function main(archivefile, outputdir, opt) , [".gz"] = {_extract_using_7z, _extract_using_gzip, _extract_using_tar} , [".xz"] = {_extract_using_7z, _extract_using_xz, _extract_using_tar} , [".tgz"] = {_extract_using_7z, _extract_using_tar} - , [".bz2"] = {_extract_using_7z, _extract_using_tar} + , [".bz2"] = {_extract_using_7z, _extract_using_bzip2} , [".tar"] = {_extract_using_7z, _extract_using_tar} - -- tar/windows can not extract .tar.bz2 ... , [".tar.gz"] = {_extract_using_7z, _extract_using_gzip} , [".tar.xz"] = {_extract_using_7z, _extract_using_xz} - , [".tar.bz2"] = {_extract_using_7z} + , [".tar.bz2"] = {_extract_using_7z, _extract_using_bzip2} } else extractors = @@ -368,11 +441,11 @@ function main(archivefile, outputdir, opt) , [".gz"] = {_extract_using_gzip, _extract_using_tar, _extract_using_7z} , [".xz"] = {_extract_using_xz, _extract_using_tar, _extract_using_7z} , [".tgz"] = {_extract_using_tar, _extract_using_7z} - , [".bz2"] = {_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.bz2"] = {_extract_using_tar, _extract_using_7z} + , [".tar.bz2"] = {_extract_using_tar, _extract_using_7z, _extract_using_bzip2} } end |
