summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-06-25 23:32:07 +0800
committerGitHub <[email protected]>2026-06-25 23:32:07 +0800
commit9f54e096b92c27f3e382b5450061d0afa1297886 (patch)
tree6258a0f781f4aa4765d7780ee1f62417d110447e
parentc8eecb9e08362dc1cbd1686a74f23e38c7c21bc4 (diff)
parentd4e1c04ca90958fa0fc618f3660975e1b6a07c8d (diff)
Merge pull request #7620 from xmake-io/vs2015
use vstool.iorunv in has_flags
-rw-r--r--core/src/xmake/hash/xxhash.c16
-rw-r--r--xmake/modules/core/tools/cl/has_flags.lua36
2 files changed, 41 insertions, 11 deletions
diff --git a/core/src/xmake/hash/xxhash.c b/core/src/xmake/hash/xxhash.c
index 77bf32dfe..4edcddb59 100644
--- a/core/src/xmake/hash/xxhash.c
+++ b/core/src/xmake/hash/xxhash.c
@@ -138,7 +138,7 @@ tb_int_t xm_hash_xxhash(lua_State *lua) {
}
// compuate hash
- tb_byte_t const *buffer;
+ tb_byte_t const *buffer = tb_null;
tb_uint32_t value32;
XXH64_hash_t value64;
XXH128_hash_t value128;
@@ -154,14 +154,14 @@ tb_int_t xm_hash_xxhash(lua_State *lua) {
buffer = (tb_byte_t const *)&value32;
}
- // make xxhash string
- tb_char_t s[256];
- tb_size_t n = mode >> 3;
- tb_size_t len = xm_hash_make_cstr(s, buffer, n);
+ if (buffer) {
+ tb_char_t s[256];
+ tb_size_t n = mode >> 3;
+ tb_size_t len = xm_hash_make_cstr(s, buffer, n);
- // save result
- lua_pushlstring(lua, s, len);
- ok = tb_true;
+ lua_pushlstring(lua, s, len);
+ ok = tb_true;
+ }
}
// exit stream
diff --git a/xmake/modules/core/tools/cl/has_flags.lua b/xmake/modules/core/tools/cl/has_flags.lua
index dfef0e1c2..bb430c40b 100644
--- a/xmake/modules/core/tools/cl/has_flags.lua
+++ b/xmake/modules/core/tools/cl/has_flags.lua
@@ -22,6 +22,7 @@
import("core.language.language")
import("core.cache.global_detectcache")
import("core.tools.cl.check_knownargs")
+import("private.tools.vstool")
-- attempt to check it from the argument list
function _check_from_arglist(flags, opt)
@@ -30,7 +31,8 @@ function _check_from_arglist(flags, opt)
local allflags = global_detectcache:get2(key, flagskey)
if not allflags then
allflags = {}
- local arglist = os.iorunv(opt.program, {"-?"}, {envs = opt.envs})
+ -- @see https://github.com/xmake-io/xmake/issues/7610
+ local arglist = vstool.iorunv(opt.program, {"-?"}, {envs = opt.envs})
if arglist then
for arg in arglist:gmatch("(/[%-%a%d]+)%s+") do
allflags[arg:gsub("/", "-")] = true
@@ -47,6 +49,33 @@ function _get_extension(opt)
return opt.flagkind == "cxxflags" and ".cpp" or (table.wrap(language.sourcekinds()[opt.toolkind or "cc"])[1] or ".c")
end
+-- get the warning/error output from cl, ignoring the source filename echo
+--
+-- when vstool.iorunv enables VS_UNICODE_OUTPUT, cl will write all its diagnostics
+-- (including the D9002 warning for unknown flags, whose exit code is still 0) to
+-- stdout instead of stderr, so we only need to check outdata here. and the hard
+-- errors (non-zero exit) will be raised by vstool.iorunv and handled by the catch.
+--
+-- but cl also echoes the source filename to stdout on every compile (even on success,
+-- since -nologo only suppresses the banner), so we need to filter it out, the rest is
+-- the real warnings/errors for unsupported flags.
+--
+-- e.g.
+-- cl_has_flags_xxx.c <-- the filename echo, skip it
+-- cl : Command line warning D9002 : ignoring unknown option '-xx' <-- a real diagnostic
+--
+function _get_output(outdata, sourcefile)
+ local filename = path.filename(sourcefile)
+ local output = {}
+ for _, line in ipairs((outdata or ""):split("\n", {plain = true})) do
+ line = line:rtrim()
+ if #line > 0 and not line:endswith(filename) then
+ table.insert(output, line)
+ end
+ end
+ return #output > 0 and table.concat(output, "\n") or nil
+end
+
-- try running to check flags
function _check_try_running(flags, opt)
@@ -67,12 +96,13 @@ function _check_try_running(flags, opt)
tmpfile = os.tmpfile()
nuldev = tmpfile
end
- local _, errs = os.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. nuldev, sourcefile),
+ local outdata = vstool.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. nuldev, sourcefile),
{envs = opt.envs, curdir = tmpdir}) -- we need to switch to tmpdir to avoid generating some tmp files, e.g. /Zi -> vc140.pdb
if tmpfile then
os.tryrm(tmpfile)
end
- if errs and #errs:trim() > 0 then
+ local errs = _get_output(outdata, sourcefile)
+ if errs then
return false, errs
end
return true