diff options
| author | ruki <[email protected]> | 2024-08-23 15:31:08 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-08-23 15:31:08 +0800 |
| commit | 087a64198d997df8d6ab64720d47a55c1b1b3817 (patch) | |
| tree | aae7bed97934c6517aa1868ff51dfcbfa62e7591 | |
| parent | 3d7af5a90d3bc60a68dfde16d12cb3e79bceb8cf (diff) | |
| parent | 3b013f036b7e7bc449d635992bb7b7e24c62b0c2 (diff) | |
Merge pull request #5491 from xmake-io/archive
Add cli.archive and .xmz archive format
| -rw-r--r-- | .github/workflows/cosmocc.yml | 19 | ||||
| -rw-r--r-- | core/src/xmake/engine.c | 211 | ||||
| -rw-r--r-- | core/src/xmake/xmake.lua | 14 | ||||
| -rw-r--r-- | core/xmake.lua | 7 | ||||
| -rw-r--r-- | tests/run.lua | 2 | ||||
| -rw-r--r-- | xmake/modules/cli/archive.lua | 53 | ||||
| -rw-r--r-- | xmake/modules/cli/extract.lua | 50 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/archive.lua | 10 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/archive_xmz.lua | 72 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/extension.lua | 6 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/extract.lua | 11 | ||||
| -rw-r--r-- | xmake/modules/utils/archive/extract_xmz.lua | 76 | ||||
| -rw-r--r-- | xmake/repository/xmake.lua | 3 |
13 files changed, 507 insertions, 27 deletions
diff --git a/.github/workflows/cosmocc.yml b/.github/workflows/cosmocc.yml index 44ef30eec..6a2bb9b4b 100644 --- a/.github/workflows/cosmocc.yml +++ b/.github/workflows/cosmocc.yml @@ -37,24 +37,17 @@ jobs: - name: Build run: | cd core - xmake f -p linux --cosmocc=y -y -cvD + xmake f --embed=y -y -cvD xmake -v cd .. - name: Tests run: | - source scripts/srcenv.profile - xmake --version - xmake lua -v -D tests/run.lua - xrepo --version + ls -l core/build/ + core/build/xmake --version + core/build/xmake lua -v -D tests/run.lua - - name: Artifact - run: | - brew install gnu-tar - cd core - xmake pack -y --autobuild=n --basename=xmake -f zip -o ../artifacts xmake - cd .. - uses: actions/upload-artifact@v2 with: - name: xmake-latest.zip - path: artifacts/xmake.zip + name: xmake + path: core/build/xmake diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c index 6ca1d0899..ae41a4d6e 100644 --- a/core/src/xmake/engine.c +++ b/core/src/xmake/engine.c @@ -49,6 +49,20 @@ #ifdef TB_CONFIG_OS_HAIKU # include <image.h> #endif +#ifdef __COSMOPOLITAN__ +# include <sys/utsname.h> +#endif + +// for uid +#ifndef TB_CONFIG_OS_WINDOWS +# include <unistd.h> +# include <errno.h> +#endif + +// for embed files +#ifdef XM_EMBED_ENABLE +# include "lz4/prefix.h" +#endif /* ////////////////////////////////////////////////////////////////////////////////////// * macros @@ -81,6 +95,11 @@ typedef struct __xm_engine_t // the engine name tb_char_t name[64]; +#ifdef XM_EMBED_ENABLE + // the temporary directory + tb_char_t tmpdir[TB_PATH_MAXN]; +#endif + }xm_engine_t; /* ////////////////////////////////////////////////////////////////////////////////////// @@ -584,6 +603,13 @@ static luaL_Reg const g_package_functions[] = // the lua global instance for signal handler static lua_State* g_lua = tb_null; +// the xmake script files data +#ifdef XM_EMBED_ENABLE +static tb_byte_t g_xmake_xmz_data[] = { + #include "xmake.xmz.h" +}; +#endif + /* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ @@ -631,7 +657,7 @@ static tb_bool_t xm_engine_save_arguments(xm_engine_t* engine, tb_int_t argc, tb return tb_true; } -static tb_size_t xm_engine_get_program_file(xm_engine_t* engine, tb_char_t* path, tb_size_t maxn) +static tb_size_t xm_engine_get_program_file(xm_engine_t* engine, tb_char_t** argv, tb_char_t* path, tb_size_t maxn) { // check tb_assert_and_check_return_val(engine && path && maxn, tb_false); @@ -722,6 +748,16 @@ static tb_size_t xm_engine_get_program_file(xm_engine_t* engine, tb_char_t* path } #endif + if (!ok && argv) + { + tb_char_t const* p = argv[0]; + if (p && tb_file_info(p, tb_null)) + { + tb_strlcpy(path, p, maxn); + ok = tb_true; + } + } + } while (0); // ok? @@ -737,16 +773,42 @@ static tb_size_t xm_engine_get_program_file(xm_engine_t* engine, tb_char_t* path return ok; } +#ifdef XM_EMBED_ENABLE +static tb_bool_t xm_engine_get_temporary_directory(tb_char_t* path, tb_size_t maxn, tb_char_t const* name, tb_char_t const* version_cstr) +{ + tb_char_t data[TB_PATH_MAXN] = {0}; + if (tb_directory_temporary(data, sizeof(data))) + { + // get euid + tb_int_t euid = 0; +#ifndef TB_CONFIG_OS_WINDOWS + euid = geteuid(); +#endif + + tb_snprintf(path, maxn, "%s/.%s%d/%s", data, name, euid, version_cstr); + return tb_true; + } + return tb_false; +} +#endif + static tb_bool_t xm_engine_get_program_directory(xm_engine_t* engine, tb_char_t* path, tb_size_t maxn, tb_char_t const* programfile) { // check tb_assert_and_check_return_val(engine && path && maxn, tb_false); tb_bool_t ok = tb_false; + tb_char_t data[TB_PATH_MAXN] = {0}; do { +#ifdef XM_EMBED_ENABLE + // get it from the temporary directory + tb_strlcpy(path, engine->tmpdir, maxn); + ok = tb_true; + break; +#endif + // get it from the environment variable first - tb_char_t data[TB_PATH_MAXN] = {0}; if (tb_environment_first("XMAKE_PROGRAM_DIR", data, sizeof(data)) && tb_path_absolute(data, path, maxn)) { ok = tb_true; @@ -899,7 +961,18 @@ static tb_void_t xm_engine_init_host(xm_engine_t* engine) // init system host tb_char_t const* syshost = tb_null; -#if defined(TB_CONFIG_OS_WINDOWS) +#if defined(__COSMOPOLITAN__) + struct utsname buffer; + if (uname(&buffer) == 0) + { + if (tb_strstr(buffer.sysname, "Darwin")) + syshost = "macosx"; + else if (tb_strstr(buffer.sysname, "Linux")) + syshost = "linux"; + else if (tb_strstr(buffer.sysname, "Windows")) + syshost = "windows"; + } +#elif defined(TB_CONFIG_OS_WINDOWS) syshost = "windows"; #elif defined(TB_CONFIG_OS_MACOSX) syshost = "macosx"; @@ -980,7 +1053,22 @@ static tb_void_t xm_engine_init_arch(xm_engine_t* engine) // init system architecture tb_char_t const* sysarch = tb_null; -#if defined(TB_CONFIG_OS_WINDOWS) && !defined(TB_COMPILER_LIKE_UNIX) +#if defined(__COSMOPOLITAN__) + struct utsname buffer; + if (uname(&buffer) == 0) + { + sysarch = buffer.machine; + if (tb_strstr(buffer.sysname, "Windows")) + { + if (!tb_strcmp(buffer.machine, "x86_64")) + sysarch = "x64"; + else if (!tb_strcmp(buffer.machine, "i686") || !tb_strcmp(buffer.machine, "i386")) + sysarch = "x86"; + } + else if (!tb_strcmp(buffer.machine, "aarch64")) + sysarch = "arm64"; + } +#elif defined(TB_CONFIG_OS_WINDOWS) && !defined(TB_COMPILER_LIKE_UNIX) // the GetNativeSystemInfo function type typedef void (WINAPI *GetNativeSystemInfo_t)(LPSYSTEM_INFO); @@ -1090,6 +1178,109 @@ static tb_pointer_t xm_engine_lua_realloc(tb_pointer_t udata, tb_pointer_t data, } #endif +#ifdef XM_EMBED_ENABLE +static tb_bool_t xm_engine_extract_programfiles(xm_engine_t* engine, tb_char_t const* programdir) +{ + tb_file_info_t info = {0}; + if (tb_file_info(programdir, &info)) return tb_true; + + tb_byte_t const* data = g_xmake_xmz_data; + tb_size_t size = sizeof(g_xmake_xmz_data); + + // do decompress + tb_bool_t ok = tb_false; + LZ4F_errorCode_t code; + LZ4F_decompressionContext_t ctx = tb_null; + tb_buffer_t result; + do + { + tb_buffer_init(&result); + + code = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION); + if (LZ4F_isError(code)) break; + + tb_byte_t buffer[8192]; + tb_bool_t failed = tb_false; + while (1) + { + size_t advance = (size_t)size; + size_t buffer_size = sizeof(buffer); + code = LZ4F_decompress(ctx, buffer, &buffer_size, data, &advance, tb_null); + if (LZ4F_isError(code)) + { + failed = tb_true; + break; + } + + if (buffer_size == 0) break; + data += advance; + size -= advance; + + tb_buffer_memncat(&result, buffer, buffer_size); + } + tb_assert_and_check_break(!failed && tb_buffer_size(&result)); + + ok = tb_true; + } while (0); + + // extract files to programdir + if (ok) + { + data = tb_buffer_data(&result); + size = tb_buffer_size(&result); + tb_byte_t const* p = data; + tb_byte_t const* e = data + size; + tb_size_t n = 0; + tb_char_t filepath[TB_PATH_MAXN]; + tb_int_t pos = tb_snprintf(filepath, sizeof(filepath), "%s/", programdir); + while (p < e) + { + // get filepath + n = (tb_size_t)tb_bits_get_u16_be(p); + p += 2; + tb_assert_and_check_break(pos + n + 1 < sizeof(filepath)); + tb_strncpy(filepath + pos, (tb_char_t const*)p, n); + filepath[pos + n] = '\0'; + p += n; + + // get filedata + n = (tb_size_t)tb_bits_get_u32_be(p); + p += 4; + + // write file + tb_trace_d("extracting %s, %lu bytes ..", filepath, n); + tb_stream_ref_t stream = tb_stream_init_from_file(filepath, TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_TRUNC); + tb_assert_and_check_break(stream); + + if (tb_stream_open(stream)) + { + tb_stream_bwrit(stream, p, n); + tb_stream_exit(stream); + } + + p += n; + } + ok = (p == e); + if (!ok) + { + tb_trace_e("extract program files failed"); + } + } + else + { + tb_trace_e("decompress program files failed, %s", LZ4F_getErrorName(code)); + } + + if (ctx) + { + LZ4F_freeDecompressionContext(ctx); + ctx = tb_null; + } + tb_buffer_exit(&result); + return ok; +} +#endif + /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ @@ -1208,6 +1399,12 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c lua_pushstring(engine->lua, version_cstr); lua_setglobal(engine->lua, "_VERSION"); +#ifdef XM_EMBED_ENABLE + // init the temporary directory + if (!xm_engine_get_temporary_directory(engine->tmpdir, sizeof(engine->tmpdir), name, version_cstr)) + break; +#endif + // init short version string tb_snprintf(version_cstr, sizeof(version_cstr), "%u.%u.%u", version->major, version->minor, version->alter); lua_pushstring(engine->lua, version_cstr); @@ -1294,11 +1491,15 @@ tb_int_t xm_engine_main(xm_engine_ref_t self, tb_int_t argc, tb_char_t** argv, t if (!xm_engine_get_project_directory(engine, path, sizeof(path))) return -1; // get the program file - if (!xm_engine_get_program_file(engine, path, sizeof(path))) return -1; + if (!xm_engine_get_program_file(engine, argv, path, sizeof(path))) return -1; // get the program directory if (!xm_engine_get_program_directory(engine, path, sizeof(path), path)) return -1; +#ifdef XM_EMBED_ENABLE + if (!xm_engine_extract_programfiles(engine, path)) return -1; +#endif + // append the main script path tb_strcat(path, "/core/_xmake_main.lua"); diff --git a/core/src/xmake/xmake.lua b/core/src/xmake/xmake.lua index af0bfd877..f5f2d9699 100644 --- a/core/src/xmake/xmake.lua +++ b/core/src/xmake/xmake.lua @@ -55,3 +55,17 @@ target("xmake") add_defines("UNICODE", "_UNICODE") end + -- embed all script files + add_rules("utils.bin2c", {linewidth = 16, extensions = ".xmz"}) + on_config(function (target) + import("utils.archive.archive") + if has_config("embed") then + local archivefile = path.join(target:autogendir(), "bin2c", "xmake.xmz") + print("archiving %s ..", archivefile) + os.tryrm(archivefile) + local rootdir = path.normalize(path.join(os.projectdir(), "..", "xmake")) + archive(archivefile, rootdir, {recurse = true, curdir = rootdir}) + target:add("files", archivefile) + target:add("defines", "XM_EMBED_ENABLE=1") + end + end) diff --git a/core/xmake.lua b/core/xmake.lua index 28bf4f22b..45fd9b2c1 100644 --- a/core/xmake.lua +++ b/core/xmake.lua @@ -55,8 +55,11 @@ if has_config("cosmocc") then set_policy("build.ccache", false) end --- the cosmocc option -option("cosmocc", {default = false, category = "option", description = "Use cosmocc toolchain to build once and run anywhere."}) +-- use cosmocc toolchain +option("cosmocc", {default = false, description = "Use cosmocc toolchain to build once and run anywhere."}) + +-- embed all script files +option("embed", {default = false, description = "Embed all script files."}) -- the runtime option option("runtime") diff --git a/tests/run.lua b/tests/run.lua index ff6158ab2..a252b445c 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -11,7 +11,7 @@ if option.get("diagnosis") then table.insert(params, "-D") end function _run_test(script) assert(script:endswith("test.lua")) - os.execv("xmake", table.join("lua", params, path.join(os.scriptdir(), "runner.lua"), script)) + os.execv(os.programfile(), table.join("lua", params, path.join(os.scriptdir(), "runner.lua"), script)) end -- run test with the given name diff --git a/xmake/modules/cli/archive.lua b/xmake/modules/cli/archive.lua new file mode 100644 index 000000000..578e6df76 --- /dev/null +++ b/xmake/modules/cli/archive.lua @@ -0,0 +1,53 @@ +--!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 archive.lua +-- + +-- imports +import("core.base.option") +import("utils.archive.archive") + +-- the options +local options = { + {nil, "compress", "kv", nil, "Set the compress algorithm.", values = {"fastest", "faster", "default", "better", "best"}}, + {'r', "recurse", "k", nil, "Enable recursive pattern."}, + {'w', "workdir", "kv", nil, "Set the working directory."}, + {nil, "excludes", "kv", nil, "Set the excludes patterns.", + "e.g.", + " - xmake l cli.archive --excludes=\"*/dir/*|dir/*\" -o archivefile inputfiles"}, + {'o', "archivefile","kv", nil, "The output archive file."}, + {nil, "inputfiles", "vs", nil, "The input files."} +} + +function main(...) + local argv = table.pack(...) + local args = option.parse(argv, options, "Archive file.", + "", + "Usage: xmake l cli.archive [options]") + local archivefile = assert(args.archivefile, "please set output file!") + local inputfiles = assert(args.inputfiles, "please set input files!") + + local opt = {} + opt.recurse = args.recurse + opt.compress = args.compress + opt.curdir = args.workdir + if args.excludes then + opt.excludes = args.excludes:split("|") + end + archive(archivefile, inputfiles, opt) +end diff --git a/xmake/modules/cli/extract.lua b/xmake/modules/cli/extract.lua new file mode 100644 index 000000000..e21258bc0 --- /dev/null +++ b/xmake/modules/cli/extract.lua @@ -0,0 +1,50 @@ +--!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 extract.lua +-- + +-- imports +import("core.base.option") +import("utils.archive.extract") + +-- the options +local options = { + {'w', "workdir", "kv", nil, "Set the working directory."}, + {nil, "excludes", "kv", nil, "Set the excludes patterns.", + "e.g.", + " - xmake l cli.extract --excludes=\"*/dir/*|dir/*\" -o outputdir archivefile"}, + {'o', "outputdir", "kv", nil, "The output directory."}, + {nil, "archivefile","v", nil, "The archive file."} +} + +function main(...) + local argv = table.pack(...) + local args = option.parse(argv, options, "Extract file.", + "", + "Usage: xmake l cli.extract [options]") + local archivefile = assert(args.archivefile, "please set archive file!") + local outputdir = assert(args.outputdir, "please set output directory!") + + local opt = {} + opt.recurse = args.recurse + opt.curdir = args.workdir + if args.excludes then + opt.excludes = args.excludes:split("|") + end + extract(archivefile, outputdir, opt) +end diff --git a/xmake/modules/utils/archive/archive.lua b/xmake/modules/utils/archive/archive.lua index f91aa9d7f..804229638 100644 --- a/xmake/modules/utils/archive/archive.lua +++ b/xmake/modules/utils/archive/archive.lua @@ -22,8 +22,15 @@ import("core.base.option") import("lib.detect.find_file") import("lib.detect.find_tool") +import("archive_xmz") import("extension", {alias = "get_archive_extension"}) +-- archive archivefile using xmake compress module +function _archive_using_xmz(archivefile, inputfiles, extension, opt) + archive_xmz(archivefile, inputfiles, opt) + return true +end + -- archive archivefile using zip function _archive_using_zip(archivefile, inputfiles, extension, opt) @@ -312,7 +319,7 @@ function _archive_tarfile(archivefile, tarfile, opt) return _archive(archivefile, tarfile, extension, archivers[extension], opt) end --- archive archive file +-- archive file -- -- @param archivefile the archive file. e.g. *.tar.gz, *.zip, *.7z, *.tar.bz2, .. -- @param inputfiles the input file or directory or list @@ -334,6 +341,7 @@ function main(archivefile, inputfiles, opt) , [".tar"] = {_archive_using_tar} , [".tar.gz"] = {_archive_using_tar, _archive_using_gzip} , [".tar.xz"] = {_archive_using_tar, _archive_using_xz} + , [".xmz"] = {_archive_using_xmz} } -- get extension diff --git a/xmake/modules/utils/archive/archive_xmz.lua b/xmake/modules/utils/archive/archive_xmz.lua new file mode 100644 index 000000000..74ccc4c92 --- /dev/null +++ b/xmake/modules/utils/archive/archive_xmz.lua @@ -0,0 +1,72 @@ +--!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 archive_xmz.lua +-- + +-- imports +import("core.base.option") +import("core.base.bytes") +import("core.compress.lz4") + +-- archive files +function _archive_files(archivefile, inputfiles, opt) + local curdir = opt.curdir + local outputfile = io.open(archivefile, "wb") + for _, inputfile in ipairs(inputfiles) do + local filepath = inputfile + if curdir then + filepath = path.relative(filepath, curdir) + end + outputfile:write(bytes(2):u16be_set(1, #filepath)) + outputfile:write(filepath) + local data = io.readfile(inputfile, {encoding = "binary"}) + vprint("archiving %s, %d bytes", inputfile, data and #data or 0) + outputfile:write(bytes(4):u32be_set(1, #data)) + outputfile:write(data) + end + outputfile:close() +end + +-- compress file +function _compress_file(archivefile, outputfile, opt) + lz4.compress_file(archivefile, outputfile) +end + +-- archive file +-- +-- @param archivefile the archive file. e.g. *.tar.gz, *.zip, *.7z, *.tar.bz2, .. +-- @param inputfiles the input file or directory or list +-- @param options the options, e.g.. {curdir = "/tmp", recurse = true, compress = "fastest|faster|default|better|best", excludes = {"*/dir/*", "dir/*"}} +-- +function main(archivefile, inputfiles, opt) + opt = opt or {} + local files = {} + for _, inputfile in ipairs(inputfiles) do + if os.isdir(inputfile) then + table.join2(files, os.files(path.join(inputfile, opt.recurse and "**" or "*"))) + elseif os.isfile(inputfile) then + table.insert(files, inputfile) + end + end + inputfiles = files + + local archivefile_tmp = os.tmpfile({ramdisk = false}) + _archive_files(archivefile_tmp, inputfiles, opt) + _compress_file(archivefile_tmp, archivefile, opt) + os.tryrm(archivefile_tmp) +end diff --git a/xmake/modules/utils/archive/extension.lua b/xmake/modules/utils/archive/extension.lua index 188631164..bee957f65 100644 --- a/xmake/modules/utils/archive/extension.lua +++ b/xmake/modules/utils/archive/extension.lua @@ -25,7 +25,11 @@ import("core.base.hashset") 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", ".tar.Z"}) + local extensionset = hashset.from({ + ".xmz", -- xmake compression format + ".zip", ".7z", ".gz", ".xz", ".tgz", + ".bz2", ".tar", ".tar.gz", ".tar.xz", + ".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 604899300..3bb69ee1a 100644 --- a/xmake/modules/utils/archive/extract.lua +++ b/xmake/modules/utils/archive/extract.lua @@ -27,8 +27,15 @@ import("detect.tools.find_tar") import("detect.tools.find_gzip") import("detect.tools.find_unzip") import("detect.tools.find_bzip2") +import("extract_xmz") import("extension", {alias = "get_archive_extension"}) +-- extract archivefile using xmake decompress module +function _extract_using_xmz(archivefile, outputdir, extension, opt) + extract_xmz(archivefile, outputdir, opt) + return true +end + -- extract archivefile using tar function _extract_using_tar(archivefile, outputdir, extension, opt) @@ -394,7 +401,7 @@ function _extract(archivefile, outputdir, extension, extractors, opt) raise("cannot extract %s, %s!", path.filename(archivefile), errors or "extractors not found!") end --- extract archive file +-- extract file -- -- @param archivefile the archive file. e.g. *.tar.gz, *.zip, *.7z, *.tar.bz2, .. -- @param outputdir the output directory @@ -423,6 +430,7 @@ function main(archivefile, outputdir, opt) , [".tar.bz2"] = {_extract_using_7z, _extract_using_bzip2} , [".tar.lz"] = {_extract_using_7z} , [".tar.Z"] = {_extract_using_7z} + , [".xmz"] = {_extract_using_xmz} } else extractors = @@ -440,6 +448,7 @@ function main(archivefile, outputdir, opt) , [".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} + , [".xmz"] = {_extract_using_xmz} } end diff --git a/xmake/modules/utils/archive/extract_xmz.lua b/xmake/modules/utils/archive/extract_xmz.lua new file mode 100644 index 000000000..1b09c0679 --- /dev/null +++ b/xmake/modules/utils/archive/extract_xmz.lua @@ -0,0 +1,76 @@ +--!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 extract_xmz.lua +-- + +-- imports +import("core.base.option") +import("core.base.bytes") +import("core.compress.lz4") + +-- extract files +function _extract_files(archivefile, outputdir, opt) + local inputfile = io.open(archivefile, "rb") + local filesize = inputfile:size() + local readsize = 0 + while readsize < filesize do + local data = inputfile:read(2) + local size = bytes(data):u16be(1) + local filepath + if size > 0 then + filepath = inputfile:read(size) + end + readsize = readsize + 2 + size + data = inputfile:read(4) + size = bytes(data):u32be(1) + local filedata + if size > 0 then + filedata = inputfile:read(size) + end + readsize = readsize + 4 + size + if filepath then + vprint("extracting %s, %d bytes", filepath, filedata and #filedata or 0) + if filedata then + io.writefile(path.join(outputdir, filepath), filedata, {encoding = "binary"}) + else + os.touch(filepath) + end + end + end + inputfile:close() +end + +-- decompress file +function _decompress_file(archivefile, outputfile, opt) + lz4.decompress_file(archivefile, outputfile) +end + +-- extract file +-- +-- @param archivefile the archive file. e.g. *.tar.gz, *.zip, *.7z, *.tar.bz2, .. +-- @param outputdir the output directory +-- @param options the options, e.g.. {excludes = {"*/dir/*", "dir/*"}} +-- +function main(archivefile, outputdir, opt) + opt = opt or {} + + local archivefile_tmp = os.tmpfile({ramdisk = false}) + _decompress_file(archivefile, archivefile_tmp, opt) + _extract_files(archivefile_tmp, outputdir, opt) + os.tryrm(archivefile_tmp) +end diff --git a/xmake/repository/xmake.lua b/xmake/repository/xmake.lua deleted file mode 100644 index 01c381ed3..000000000 --- a/xmake/repository/xmake.lua +++ /dev/null @@ -1,3 +0,0 @@ - --- set repository description -set_description("The official builtin package repository of xmake") |
