summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-08-23 15:31:08 +0800
committerGitHub <[email protected]>2024-08-23 15:31:08 +0800
commit087a64198d997df8d6ab64720d47a55c1b1b3817 (patch)
treeaae7bed97934c6517aa1868ff51dfcbfa62e7591
parent3d7af5a90d3bc60a68dfde16d12cb3e79bceb8cf (diff)
parent3b013f036b7e7bc449d635992bb7b7e24c62b0c2 (diff)
Merge pull request #5491 from xmake-io/archive
Add cli.archive and .xmz archive format
-rw-r--r--.github/workflows/cosmocc.yml19
-rw-r--r--core/src/xmake/engine.c211
-rw-r--r--core/src/xmake/xmake.lua14
-rw-r--r--core/xmake.lua7
-rw-r--r--tests/run.lua2
-rw-r--r--xmake/modules/cli/archive.lua53
-rw-r--r--xmake/modules/cli/extract.lua50
-rw-r--r--xmake/modules/utils/archive/archive.lua10
-rw-r--r--xmake/modules/utils/archive/archive_xmz.lua72
-rw-r--r--xmake/modules/utils/archive/extension.lua6
-rw-r--r--xmake/modules/utils/archive/extract.lua11
-rw-r--r--xmake/modules/utils/archive/extract_xmz.lua76
-rw-r--r--xmake/repository/xmake.lua3
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")