diff options
| author | ruki <[email protected]> | 2019-08-21 09:50:12 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-08-21 09:50:12 +0800 |
| commit | 2c891f5a18aec7d47d3458ef39b9294d7f3b4d59 (patch) | |
| tree | 5874844f405dc4bff6700dc0869eec5662ae680c | |
| parent | a5def1ed021b1b5ba296fe22a7177f00285eaad9 (diff) | |
| parent | 7ce304f9ee9946471d4ad11e78ea25149a05483f (diff) | |
Merge pull request #542 from xmake-io/vs_unicode
Improve vs unicode output for link link/cl
| -rw-r--r-- | core/src/xmake/io/file_close.c | 3 | ||||
| -rw-r--r-- | core/src/xmake/process/close.c | 20 | ||||
| -rw-r--r-- | core/src/xmake/process/open.c | 116 | ||||
| -rw-r--r-- | core/src/xmake/process/openv.c | 119 | ||||
| -rw-r--r-- | core/src/xmake/process/prefix.h | 37 | ||||
| -rw-r--r-- | xmake/core/base/os.lua | 24 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/os.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/core/tools/cl.lua | 6 | ||||
| -rw-r--r-- | xmake/modules/core/tools/lib.lua | 7 | ||||
| -rw-r--r-- | xmake/modules/core/tools/link.lua | 6 | ||||
| -rw-r--r-- | xmake/modules/core/tools/ml.lua | 11 | ||||
| -rw-r--r-- | xmake/modules/private/tools/vstool.lua | 127 |
12 files changed, 269 insertions, 211 deletions
diff --git a/core/src/xmake/io/file_close.c b/core/src/xmake/io/file_close.c index 5c7d5c75d..6b3efdd98 100644 --- a/core/src/xmake/io/file_close.c +++ b/core/src/xmake/io/file_close.c @@ -66,8 +66,7 @@ tb_int_t xm_io_file_close(lua_State* lua) #endif // close file - if (!tb_stream_clos(file->file_ref)) - xm_io_file_return_error(lua, "failed to close file"); + tb_stream_clos(file->file_ref); file->file_ref = tb_null; // exit fstream diff --git a/core/src/xmake/process/close.c b/core/src/xmake/process/close.c index 94de9b33d..dc1a465a3 100644 --- a/core/src/xmake/process/close.c +++ b/core/src/xmake/process/close.c @@ -48,26 +48,6 @@ tb_int_t xm_process_close(lua_State* lua) tb_process_ref_t process = (tb_process_ref_t)lua_touserdata(lua, 1); tb_check_return_val(process, 0); - // exit subprocess - xm_subprocess_t* subprocess = (xm_subprocess_t*)tb_process_priv(process); - if (subprocess) - { - if (subprocess->outtype == TB_PROCESS_REDIRECT_TYPE_FILE && subprocess->outfile) - { - tb_file_exit(subprocess->outfile); - subprocess->outfile = tb_null; - } - - if (subprocess->errtype == TB_PROCESS_REDIRECT_TYPE_FILE && subprocess->errfile) - { - tb_file_exit(subprocess->errfile); - subprocess->errfile = tb_null; - } - - tb_string_exit(&subprocess->vs_unicode_output); - tb_free(subprocess); - } - // exit process tb_process_exit(process); diff --git a/core/src/xmake/process/open.c b/core/src/xmake/process/open.c index bc1b35607..9d4765e7c 100644 --- a/core/src/xmake/process/open.c +++ b/core/src/xmake/process/open.c @@ -29,6 +29,7 @@ * includes */ #include "prefix.h" +#include "../io/prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation @@ -53,7 +54,8 @@ tb_int_t xm_process_open(lua_State* lua) tb_char_t const* envs[256] = {0}; tb_char_t const* outpath = tb_null; tb_char_t const* errpath = tb_null; - tb_bool_t vs_unicode_output = tb_false; + xm_io_file_t* outfile = tb_null; + xm_io_file_t* errfile = tb_null; if (lua_istable(lua, 2)) { // get outpath @@ -68,77 +70,24 @@ tb_int_t xm_process_open(lua_State* lua) errpath = lua_tostring(lua, -1); lua_pop(lua, 1); - // enable vs_unicode_output? - lua_pushstring(lua, "vs_unicode_output"); - lua_gettable(lua, 2); - vs_unicode_output = lua_toboolean(lua, -1); - lua_pop(lua, 1); - } - - // enable vs_unicode_output? @see https://github.com/xmake-io/xmake/issues/528 - if (vs_unicode_output) - { - xm_subprocess_t* subprocess = tb_malloc0_type(xm_subprocess_t); - if (subprocess) - { - // init vs_unicode_output - tb_string_init(&subprocess->vs_unicode_output); - - // redirect stdout? - if (outpath) - { - // redirect stdout to file - subprocess->outfile = tb_file_init(outpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT); - subprocess->outtype = TB_PROCESS_REDIRECT_TYPE_FILE; - attr.outfile = subprocess->outfile; - attr.outtype = subprocess->outtype; - -#ifdef TB_CONFIG_OS_WINDOWS - /* add environment value of vs_unicode_output - * - * @note we have to set it at the beginning, because opt.envs might also have this value. - */ - if (envn + 1 < tb_arrayn(envs)) - envs[envn++] = tb_string_cstrfcpy(&subprocess->vs_unicode_output, "VS_UNICODE_OUTPUT=%zu", (tb_size_t)subprocess->outfile); -#endif - } - - // redirect stderr? - if (errpath) - { - // redirect stderr to file - subprocess->errfile = tb_file_init(errpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT); - subprocess->errtype = TB_PROCESS_REDIRECT_TYPE_FILE; - attr.errfile = subprocess->errfile; - attr.errtype = subprocess->errtype; - } - attr.priv = subprocess; - } - } - else - { - // redirect stdout? - if (outpath) + // get outfile + if (!outpath) { - // redirect stdout to file - attr.outpath = outpath; - attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; - attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + lua_pushstring(lua, "outfile"); + lua_gettable(lua, 3); + outfile = (xm_io_file_t*)lua_touserdata(lua, -1); + lua_pop(lua, 1); } - // redirect stderr? - if (errpath) + // get errfile + if (!errpath) { - // redirect stderr to file - attr.errpath = errpath; - attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; - attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + lua_pushstring(lua, "errfile"); + lua_gettable(lua, 3); + errfile = (xm_io_file_t*)lua_touserdata(lua, -1); + lua_pop(lua, 1); } - } - // append other environments after setting VS_UNICODE_OUTPUT - if (lua_istable(lua, 2)) - { // get environments lua_pushstring(lua, "envs"); lua_gettable(lua, 2); @@ -182,6 +131,41 @@ tb_int_t xm_process_open(lua_State* lua) lua_pop(lua, 1); } + // redirect stdout? + if (outpath) + { + // redirect stdout to file + attr.outpath = outpath; + attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; + attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + } + else if (outfile && xm_io_file_is_file(outfile)) + { + tb_file_ref_t rawfile = tb_null; + if (tb_stream_ctrl(outfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile) + { + attr.outfile = rawfile; + attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILE; + } + } + + // redirect stderr? + if (errpath) + { + // redirect stderr to file + attr.errpath = errpath; + attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; + attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + } + else if (errfile && xm_io_file_is_file(errfile)) + { + tb_file_ref_t rawfile = tb_null; + if (tb_stream_ctrl(errfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile) + { + attr.errfile = rawfile; + attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILE; + } + } // set the new environments if (envn > 0) attr.envp = envs; diff --git a/core/src/xmake/process/openv.c b/core/src/xmake/process/openv.c index e329f9898..57dbe559d 100644 --- a/core/src/xmake/process/openv.c +++ b/core/src/xmake/process/openv.c @@ -29,12 +29,13 @@ * includes */ #include "prefix.h" +#include "../io/prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ -// p = process.openv(shellname, argv, {outpath = "", errpath = "", envs = {"PATH=xxx", "XXX=yyy"}) +// p = process.openv(shellname, argv, {outpath = "", errpath = "", outfile = , errfile = , envs = {"PATH=xxx", "XXX=yyy"}) tb_int_t xm_process_openv(lua_State* lua) { // check @@ -95,7 +96,8 @@ tb_int_t xm_process_openv(lua_State* lua) tb_char_t const* envs[256] = {0}; tb_char_t const* outpath = tb_null; tb_char_t const* errpath = tb_null; - tb_bool_t vs_unicode_output = tb_false; + xm_io_file_t* outfile = tb_null; + xm_io_file_t* errfile = tb_null; if (lua_istable(lua, 3)) { // get outpath @@ -110,77 +112,24 @@ tb_int_t xm_process_openv(lua_State* lua) errpath = lua_tostring(lua, -1); lua_pop(lua, 1); - // enable vs_unicode_output? - lua_pushstring(lua, "vs_unicode_output"); - lua_gettable(lua, 3); - vs_unicode_output = lua_toboolean(lua, -1); - lua_pop(lua, 1); - } - - // enable vs_unicode_output? @see https://github.com/xmake-io/xmake/issues/528 - if (vs_unicode_output) - { - xm_subprocess_t* subprocess = tb_malloc0_type(xm_subprocess_t); - if (subprocess) - { - // init vs_unicode_output - tb_string_init(&subprocess->vs_unicode_output); - - // redirect stdout? - if (outpath) - { - // redirect stdout to file - subprocess->outfile = tb_file_init(outpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT); - subprocess->outtype = TB_PROCESS_REDIRECT_TYPE_FILE; - attr.outfile = subprocess->outfile; - attr.outtype = subprocess->outtype; - -#ifdef TB_CONFIG_OS_WINDOWS - /* add environment value of vs_unicode_output - * - * @note we have to set it at the beginning, because opt.envs might also have this value. - */ - if (envn + 1 < tb_arrayn(envs)) - envs[envn++] = tb_string_cstrfcpy(&subprocess->vs_unicode_output, "VS_UNICODE_OUTPUT=%zu", (tb_size_t)subprocess->outfile); -#endif - } - - // redirect stderr? - if (errpath) - { - // redirect stderr to file - subprocess->errfile = tb_file_init(errpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT); - subprocess->errtype = TB_PROCESS_REDIRECT_TYPE_FILE; - attr.errfile = subprocess->errfile; - attr.errtype = subprocess->errtype; - } - attr.priv = subprocess; - } - } - else - { - // redirect stdout? - if (outpath) + // get outfile + if (!outpath) { - // redirect stdout to file - attr.outpath = outpath; - attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; - attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + lua_pushstring(lua, "outfile"); + lua_gettable(lua, 3); + outfile = (xm_io_file_t*)lua_touserdata(lua, -1); + lua_pop(lua, 1); } - // redirect stderr? - if (errpath) + // get errfile + if (!errpath) { - // redirect stderr to file - attr.errpath = errpath; - attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; - attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + lua_pushstring(lua, "errfile"); + lua_gettable(lua, 3); + errfile = (xm_io_file_t*)lua_touserdata(lua, -1); + lua_pop(lua, 1); } - } - // append other environments after setting VS_UNICODE_OUTPUT - if (lua_istable(lua, 3)) - { // get environments lua_pushstring(lua, "envs"); lua_gettable(lua, 3); @@ -223,6 +172,42 @@ tb_int_t xm_process_openv(lua_State* lua) } lua_pop(lua, 1); } + + // redirect stdout? + if (outpath) + { + // redirect stdout to file + attr.outpath = outpath; + attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; + attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + } + else if (outfile && xm_io_file_is_file(outfile)) + { + tb_file_ref_t rawfile = tb_null; + if (tb_stream_ctrl(outfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile) + { + attr.outfile = rawfile; + attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILE; + } + } + + // redirect stderr? + if (errpath) + { + // redirect stderr to file + attr.errpath = errpath; + attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT; + attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH; + } + else if (errfile && xm_io_file_is_file(errfile)) + { + tb_file_ref_t rawfile = tb_null; + if (tb_stream_ctrl(errfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile) + { + attr.errfile = rawfile; + attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILE; + } + } // set the new environments if (envn > 0) attr.envp = envs; diff --git a/core/src/xmake/process/prefix.h b/core/src/xmake/process/prefix.h index 3ec32f792..4e3f4b3b4 100644 --- a/core/src/xmake/process/prefix.h +++ b/core/src/xmake/process/prefix.h @@ -26,43 +26,6 @@ */ #include "../prefix.h" -/* ////////////////////////////////////////////////////////////////////////////////////// - * types - */ - -// the subprocess type -typedef struct __xm_subprocess_t -{ - /// the stdout redirect type - tb_uint16_t outtype; - - /// the stderr redirect type - tb_uint16_t errtype; - - union - { - /// the stdout pipe - tb_pipe_file_ref_t outpipe; - - /// the stdout file - tb_file_ref_t outfile; - }; - - union - { - /// the strerr pipe - tb_pipe_file_ref_t errpipe; - - /// the stderr file - tb_file_ref_t errfile; - }; - - // vs unicode output environment variable - tb_string_t vs_unicode_output; - -}xm_subprocess_t; - - #endif diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index 506cd7da2..ad9f37627 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -556,6 +556,7 @@ end -- run command with arguments list function os.runv(program, argv, opt) + -- init options opt = opt or {} -- make temporary log file @@ -638,12 +639,10 @@ function os.execv(program, argv, opt) -- uses the given environments? local envs = nil - if opt.envs or opt.vs_unicode_output then + if opt.envs then local envars = os.getenvs() - if opt.envs then - for k, v in pairs(opt.envs) do - envars[k] = v - end + for k, v in pairs(opt.envs) do + envars[k] = v end envs = {} for k, v in pairs(envars) do @@ -651,9 +650,22 @@ function os.execv(program, argv, opt) end end + -- init open options + local openopt = {envs = envs} + if type(opt.stdout) == "table" then + openopt.outfile = opt.stdout._FILE + else + openopt.outpath = opt.stdout + end + if type(opt.stderr) == "table" then + openopt.errfile = opt.stderr._FILE + else + openopt.errpath = opt.stderr + end + -- open command local ok = -1 - local proc = process.openv(filename, argv, {outpath = opt.stdout, errpath = opt.stderr, envs = envs, vs_unicode_output = opt.vs_unicode_output}) + local proc = process.openv(filename, argv, openopt) if proc ~= nil then -- wait process diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua index 422f0fbf7..348649177 100644 --- a/xmake/core/sandbox/modules/os.lua +++ b/xmake/core/sandbox/modules/os.lua @@ -409,14 +409,16 @@ function sandbox_os.execv(program, argv, opt) io.flush() -- run it + opt = opt or {} local ok = os.execv(program, argv, opt) - if ok ~= 0 then + if ok ~= 0 and not opt.try then if argv ~= nil then os.raise("execv(%s %s) failed(%d)!", program, table.concat(argv, ' '), ok) else os.raise("execv(%s) failed(%d)!", program, ok) end end + return ok end -- match files or directories diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua index 2d55001e3..d09a67e8e 100644 --- a/xmake/modules/core/tools/cl.lua +++ b/xmake/modules/core/tools/cl.lua @@ -22,6 +22,7 @@ import("core.base.option") import("core.project.project") import("core.language.language") +import("private.tools.vstool") -- init it function init(self) @@ -393,9 +394,8 @@ function _compile1(self, sourcefile, objectfile, dependinfo, flags) compflags = table.join(flags, "-showIncludes") end - -- compile and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528 - local program, argv = _compargv1(self, sourcefile, objectfile, compflags) - return os.iorunv(program, argv, {vs_unicode_output = true}) + -- use vstool to compile and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528 + return vstool.iorunv(_compargv1(self, sourcefile, objectfile, compflags)) end, catch { diff --git a/xmake/modules/core/tools/lib.lua b/xmake/modules/core/tools/lib.lua index 0ae9be7fd..1bd54a839 100644 --- a/xmake/modules/core/tools/lib.lua +++ b/xmake/modules/core/tools/lib.lua @@ -18,6 +18,9 @@ -- @file lib.lua -- +-- imports +import("private.tools.vstool") + -- extract the static library to object directory function extract(self, libraryfile, objectdir) @@ -25,7 +28,7 @@ function extract(self, libraryfile, objectdir) os.mkdir(objectdir) -- list object files - local objectfiles = os.iorunv(self:program(), {"-nologo", "-list", libraryfile}, {vs_unicode_output = true}) + local objectfiles = vstool.iorunv(self:program(), {"-nologo", "-list", libraryfile}) -- extrace all object files for _, objectfile in ipairs(objectfiles:split('\n')) do @@ -47,7 +50,7 @@ function extract(self, libraryfile, objectdir) end -- extract it - os.runv(self:program(), {"-nologo", "-extract:" .. objectfile, "-out:" .. outputfile, libraryfile}, {vs_unicode_output = true}) + vstool.runv(self:program(), {"-nologo", "-extract:" .. objectfile, "-out:" .. outputfile, libraryfile}) end end end diff --git a/xmake/modules/core/tools/link.lua b/xmake/modules/core/tools/link.lua index 73d9c246d..5479cb3db 100644 --- a/xmake/modules/core/tools/link.lua +++ b/xmake/modules/core/tools/link.lua @@ -20,6 +20,7 @@ -- imports import("core.project.config") +import("private.tools.vstool") -- init it function init(self) @@ -112,8 +113,7 @@ function link(self, objectfiles, targetkind, targetfile, flags, opt) -- ensure the target directory os.mkdir(path.directory(targetfile)) - -- link and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528 - local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags, opt) - os.runv(program, argv, {vs_unicode_output = true}) + -- use vstool to link and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528 + vstool.runv(linkargv(self, objectfiles, targetkind, targetfile, flags, opt)) end diff --git a/xmake/modules/core/tools/ml.lua b/xmake/modules/core/tools/ml.lua index 6eb7c529d..e14cc4e50 100644 --- a/xmake/modules/core/tools/ml.lua +++ b/xmake/modules/core/tools/ml.lua @@ -18,9 +18,13 @@ -- @file ml.lua -- --- https://docs.microsoft.com/en-us/cpp/assembler/masm/ml-and-ml64-command-line-reference +-- imports +import("private.tools.vstool") -- init it +-- +-- @see https://docs.microsoft.com/en-us/cpp/assembler/masm/ml-and-ml64-command-line-reference +-- function init(self) -- init asflags @@ -103,9 +107,8 @@ function _compile1(self, sourcefile, objectfile, dependinfo, flags) -- ensure the object directory os.mkdir(path.directory(objectfile)) - -- compile it - local program, argv = _compargv1(self, sourcefile, objectfile, flags) - os.runv(program, argv, {vs_unicode_output = true}) + -- use vstool to compile and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528 + vstool.runv(_compargv1(self, sourcefile, objectfile, flags)) end -- make the compile arguments list diff --git a/xmake/modules/private/tools/vstool.lua b/xmake/modules/private/tools/vstool.lua new file mode 100644 index 000000000..05c7a16b6 --- /dev/null +++ b/xmake/modules/private/tools/vstool.lua @@ -0,0 +1,127 @@ +--!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 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file vstool.lua +-- + +-- quietly run command with arguments list +function runv(program, argv, opt) + + -- init options + opt = opt or {} + + -- make temporary output and error file + local outpath = os.tmpfile() + local errpath = os.tmpfile() + local outfile = io.open(outpath, 'w') + + -- enable unicode output for vs toolchains, e.g. cl.exe, link.exe and etc. + -- @see https://github.com/xmake-io/xmake/issues/528 + local envs = {VS_UNICODE_OUTPUT = outfile:rawfd()} + + -- execute it + local ok = os.execv(program, argv, table.join(opt, {try = true, stdout = outfile, stderr = errpath, envs = envs})) + + -- close outfile first + outfile:close() + + -- failed? + if ok ~= 0 then + + -- read errors + local outdata = os.isfile(outpath) and io.readfile(outpath, {encoding = "utf16le"}) or nil + local errdata = os.isfile(errpath) and io.readfile(errpath) or nil + local errors = errdata or "" + if #errors:trim() == 0 then + errors = outdata or "" + end + + -- make the default errors + if not errors or #errors == 0 then + if argv ~= nil then + errors = string.format("vstool.runv(%s %s) failed(%d)!", program, table.concat(argv, ' '), ok) + else + errors = string.format("vstool.runv(%s) failed(%d)!", program, ok) + end + end + + -- remove the files + os.tryrm(outpath) + os.tryrm(errpath) + + -- raise errors + os.raise({errors = errors, stderr = errdata, stdout = outdata}) + end + + -- remove the files + os.tryrm(outpath) + os.tryrm(errpath) +end + +-- run command and return output and error data +function iorunv(program, argv, opt) + + -- init options + opt = opt or {} + + -- make temporary output and error file + local outpath = os.tmpfile() + local errpath = os.tmpfile() + local outfile = io.open(outpath, 'w') + + -- enable unicode output for vs toolchains, e.g. cl.exe, link.exe and etc. + -- @see https://github.com/xmake-io/xmake/issues/528 + local envs = {VS_UNICODE_OUTPUT = outfile:rawfd()} + + -- run command + local ok = os.execv(program, argv, table.join(opt, {try = true, stdout = outfile, stderr = errpath, envs = envs})) + + -- get output and error data + outfile:close() + local outdata = os.isfile(outpath) and io.readfile(outpath, {encoding = "utf16le"}) or nil + local errdata = os.isfile(errpath) and io.readfile(errpath) or nil + + -- remove the temporary output and error file + os.tryrm(outpath) + os.tryrm(errpath) + + -- failed? + if ok ~= 0 then + + -- get errors + local errors = errdata or "" + if #errors:trim() == 0 then + errors = outdata or "" + end + + -- make the default errors + if not errors or #errors == 0 then + if argv ~= nil then + errors = string.format("vstool.iorunv(%s %s) failed(%d)!", program, table.concat(argv, ' '), ok) + else + errors = string.format("vstool.iorunv(%s) failed(%d)!", program, ok) + end + end + + -- raise errors + os.raise({errors = errors, stderr = errdata, stdout = outdata}) + end + + -- ok? + return outdata, errdata +end + |
