summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-08-21 09:50:12 +0800
committerGitHub <[email protected]>2019-08-21 09:50:12 +0800
commit2c891f5a18aec7d47d3458ef39b9294d7f3b4d59 (patch)
tree5874844f405dc4bff6700dc0869eec5662ae680c
parenta5def1ed021b1b5ba296fe22a7177f00285eaad9 (diff)
parent7ce304f9ee9946471d4ad11e78ea25149a05483f (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.c3
-rw-r--r--core/src/xmake/process/close.c20
-rw-r--r--core/src/xmake/process/open.c116
-rw-r--r--core/src/xmake/process/openv.c119
-rw-r--r--core/src/xmake/process/prefix.h37
-rw-r--r--xmake/core/base/os.lua24
-rw-r--r--xmake/core/sandbox/modules/os.lua4
-rw-r--r--xmake/modules/core/tools/cl.lua6
-rw-r--r--xmake/modules/core/tools/lib.lua7
-rw-r--r--xmake/modules/core/tools/link.lua6
-rw-r--r--xmake/modules/core/tools/ml.lua11
-rw-r--r--xmake/modules/private/tools/vstool.lua127
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
+