summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-08-20 23:52:53 +0800
committerruki <[email protected]>2019-08-20 17:17:24 +0800
commitb4aaf6ec3aa7d2d9d6f21f267a46869d25275d16 (patch)
tree4ffca303046f223ec92a2d7938d13d4ac3622ada
parentda11852ee8510e46ba0436ab125d0d89d6c1f728 (diff)
rewrite vs unicode output
-rw-r--r--xmake/core/base/os.lua1
-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
7 files changed, 149 insertions, 13 deletions
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 5626c0c5d..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
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..ba0ec8edc
--- /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 = io.readfile(outpath)
+ local errdata = io.readfile(errpath)
+ 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 = io.readfile(outpath)
+ local errdata = io.readfile(errpath)
+
+ -- 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
+