summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-12-03 21:01:49 +0800
committerruki <[email protected]>2025-12-03 21:01:49 +0800
commit9c78a7642714f89dab6077eb9ecbc683e5551967 (patch)
tree59e774aa0452a51f5efa1ed25b930f43ff7c5458
parent13eda469fbca1407d7948191f2a7f04949ba392e (diff)
improve syntax check
-rw-r--r--xmake/core/project/policy.lua2
-rw-r--r--xmake/modules/core/tools/cl.lua13
-rw-r--r--xmake/modules/core/tools/gcc.lua12
-rw-r--r--xmake/modules/private/check/checkers/syntax.lua26
-rw-r--r--xmake/rules/c++/config/main.lua4
-rw-r--r--xmake/rules/c++/config/syntax_only.lua55
6 files changed, 41 insertions, 71 deletions
diff --git a/xmake/core/project/policy.lua b/xmake/core/project/policy.lua
index ba005f16e..1cecfd01a 100644
--- a/xmake/core/project/policy.lua
+++ b/xmake/core/project/policy.lua
@@ -110,8 +110,6 @@ function policy.policies()
["build.c++.msvc.runtime"] = {description = "Set the default vs runtime.", type = "string", values = {"MT", "MD"}},
-- Enable C++ Dynamic Debugging for MSVC (requires MSVC toolset 14.44+, x64 only, incompatible with LTCG/PGO/OPT-ICF).
["build.c++.dynamic_debugging"] = {description = "Enable C++ Dynamic Debugging for MSVC (requires MSVC toolset 14.44+, x64 only, incompatible with LTCG/PGO/OPT-ICF).", type = "boolean"},
- -- Enable syntax-only check for C/C++ building.
- ["build.c++.syntax_only"] = {description = "Enable syntax-only check for C/C++ building.", type = "boolean"},
-- Enable cuda device link
["build.cuda.devlink"] = {description = "Enable Cuda devlink.", type = "boolean"},
-- Enable linker output, e.g. show -Wl,--print-memory-usage output for gcc/g++
diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua
index de64df3da..0cf33d16b 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.base.global")
import("core.base.hashset")
+import("core.cache.memcache")
import("core.project.project")
import("core.project.policy")
import("core.language.language")
@@ -93,6 +94,11 @@ function init(self)
})
end
+-- is syntax check enabled?
+function _is_syntax_check()
+ return memcache.get("syntax_check", "enabled") or false
+end
+
-- make the symbol flags
function nf_symbols(self, levels, opt)
local flags = nil
@@ -654,6 +660,7 @@ end
-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags, opt)
+ opt = opt or {}
-- precompiled header?
local extension = path.extension(sourcefile)
@@ -661,6 +668,12 @@ function compargv(self, sourcefile, objectfile, flags, opt)
return _compargv_pch(self, sourcefile, objectfile, flags)
end
+ -- if syntax-only, add /Zs and skip -c and -Fo
+ if _is_syntax_check() then
+ table.insert(flags, "/Zs")
+ return self:program(), (opt and opt.rawargs) and flags or winos.cmdargv(flags, sourcefile)
+ end
+
-- suppress clang-cl warnings
-- clang-cl: warning: argument unused during compilation: '-c' [-Wunused-command-line-argument]
--
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index 4a920a233..c1a98b752 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -73,6 +73,11 @@ function _is_cosmocc(self)
return is_cosmocc
end
+-- is syntax check enabled?
+function _is_syntax_check()
+ return memcache.get("syntax_check", "enabled") or false
+end
+
-- get `-MMD -MF depfile.d` flags, some old gcc does not support it at same time
function _get_depfile_flags(self)
local depfile_flags = _g._DEPFILE_FLAGS
@@ -965,6 +970,7 @@ end
-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags, opt)
+ opt = opt or {}
-- is precompiled header or module files? remove the force includes.
local extension = path.extension(sourcefile)
@@ -974,6 +980,12 @@ function compargv(self, sourcefile, objectfile, flags, opt)
flags = _translate_flags_for_mpp(self, flags)
end
+ -- if syntax-only, add -fsyntax-only and skip -c and -o
+ if _is_syntax_check() then
+ table.insert(flags, "-fsyntax-only")
+ return self:program(), table.join(flags, sourcefile)
+ end
+
local argv = table.join("-c", flags, "-o", objectfile, sourcefile)
return self:program(), argv
end
diff --git a/xmake/modules/private/check/checkers/syntax.lua b/xmake/modules/private/check/checkers/syntax.lua
index 439e03835..163e2be55 100644
--- a/xmake/modules/private/check/checkers/syntax.lua
+++ b/xmake/modules/private/check/checkers/syntax.lua
@@ -21,6 +21,7 @@
-- imports
import("core.base.option")
import("core.base.task")
+import("core.cache.memcache")
import("core.project.project")
import("actions.build.build_files", {rootdir = os.programdir(), alias = "build_files"})
import("actions.build.build", {rootdir = os.programdir(), alias = "build"})
@@ -65,8 +66,8 @@ function _check_compiler_support(target)
return has_support
end
--- validate targets before checking
-function _validate_targets(opt)
+-- validate targets and enable syntax-only
+function _validate_and_enable_targets(opt)
opt = opt or {}
local targets = {}
if opt.targets then
@@ -84,22 +85,28 @@ function _validate_targets(opt)
end
end
- -- check if any target has C++ rules
- local has_cpp_target = false
+ -- check if any target has C++ rules and enable syntax-only
+ local cpp_targets = {}
for _, target in ipairs(targets) do
if _has_cpp_rules(target) then
- has_cpp_target = true
-- check if compiler supports syntax-only check
if not _check_compiler_support(target) then
wprint("target(%s): current compiler does not support syntax-only check", target:name())
+ else
+ table.insert(cpp_targets, target)
end
else
wprint("target(%s): syntax check currently only supports C/C++ targets", target:name())
end
end
+ -- enable syntax-only via memcache
+ if #cpp_targets > 0 then
+ memcache.set("syntax_check", "enabled", true)
+ end
+
-- if no C++ target found, return false to skip checking
- if not has_cpp_target then
+ if #cpp_targets == 0 then
return false
end
return true
@@ -140,15 +147,14 @@ function main(argv)
-- config it first
task.run("config", {}, {disable_dump = true})
- -- enable syntax-only policy and disable ccache
- project.policy_set("build.c++.syntax_only", true)
+ -- disable ccache after config
project.policy_set("build.ccache", false)
-- enter project directory
local oldir = os.cd(project.directory())
- -- validate targets before checking
- if _validate_targets(args) then
+ -- validate targets and enable syntax-only
+ if _validate_and_enable_targets(args) then
_check(args)
end
diff --git a/xmake/rules/c++/config/main.lua b/xmake/rules/c++/config/main.lua
index bde849965..68bf5a064 100644
--- a/xmake/rules/c++/config/main.lua
+++ b/xmake/rules/c++/config/main.lua
@@ -21,7 +21,6 @@
-- imports
import("rules.c++.config.basic", {rootdir = os.programdir(), alias = "config_basic"})
import("rules.c++.config.dynamic_debugging", {rootdir = os.programdir(), alias = "config_dynamic_debugging"})
-import("rules.c++.config.syntax_only", {rootdir = os.programdir(), alias = "config_syntax_only"})
import("rules.c++.config.optimization", {rootdir = os.programdir(), alias = "config_optimization"})
import("rules.c++.config.sanitizer", {rootdir = os.programdir(), alias = "config_sanitizer"})
@@ -34,9 +33,6 @@ function main(target, sourcekind)
-- config dynamic debugging configs (must be before optimization to disable incompatible flags)
config_dynamic_debugging(target, sourcekind)
- -- config syntax only configs (must be before optimization to disable incompatible flags)
- config_syntax_only(target, sourcekind)
-
-- config optimization configs
config_optimization(target, sourcekind)
diff --git a/xmake/rules/c++/config/syntax_only.lua b/xmake/rules/c++/config/syntax_only.lua
deleted file mode 100644
index 4f0045192..000000000
--- a/xmake/rules/c++/config/syntax_only.lua
+++ /dev/null
@@ -1,55 +0,0 @@
---!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, Xmake Open Source Community.
---
--- @author ruki
--- @file syntax_only.lua
---
-
--- imports
-import("core.project.project")
-
--- add syntax-only check support
--- @see https://github.com/mesonbuild/meson/issues/12228
-function main(target, sourcekind)
- -- check if syntax-only is enabled
- local enabled = target:policy("build.c++.syntax_only")
- if enabled == nil then
- enabled = project.policy("build.c++.syntax_only")
- end
- if not enabled then
- return
- end
-
- -- get flag name for sourcekind
- local flagnames = {
- cc = "cflags",
- cxx = "cxxflags",
- mm = "mflags",
- mxx = "mxxflags"
- }
- local cflag = flagnames[sourcekind] or (sourcekind == "cxx" and "cxxflags" or "cflags")
-
- -- check compiler and add appropriate flag
- local toolname = sourcekind == "cxx" and "cxx" or "cc"
- if target:has_tool(toolname, "gcc", "gxx", "clang", "clangxx") then
- -- gcc/clang: -fsyntax-only
- target:add(cflag, "-fsyntax-only", {force = true})
- elseif target:has_tool(toolname, "cl") then
- -- MSVC: /Zs (syntax check only)
- target:add(cflag, "/Zs", {force = true})
- end
-end
-