summaryrefslogtreecommitdiff
path: root/xmake/modules
diff options
context:
space:
mode:
authorruki <[email protected]>2023-02-21 09:54:49 +0800
committerGitHub <[email protected]>2023-02-21 09:54:49 +0800
commit8ea58baa753ebcbfce5cd434a92e3dd369da0e0d (patch)
tree70a852b2c674ea283b873732dbbb44969a47d987 /xmake/modules
parent775cc38c761e02fa3ff4825eabca344b98c75b78 (diff)
parent0fc0959c413b6cb1900f59fee403502f7b8ae2e8 (diff)
Merge pull request #3397 from xmake-io/check
Improve check and add devlink checker
Diffstat (limited to 'xmake/modules')
-rw-r--r--xmake/modules/private/check/checker.lua105
-rw-r--r--xmake/modules/private/check/checkers/api/api_checker.lua158
-rw-r--r--xmake/modules/private/check/checkers/api/target/asflags.lua34
-rw-r--r--xmake/modules/private/check/checkers/api/target/cflags.lua34
-rw-r--r--xmake/modules/private/check/checkers/api/target/configfiles.lua33
-rw-r--r--xmake/modules/private/check/checkers/api/target/cxflags.lua34
-rw-r--r--xmake/modules/private/check/checkers/api/target/cxxflags.lua34
-rw-r--r--xmake/modules/private/check/checkers/api/target/exceptions.lua27
-rw-r--r--xmake/modules/private/check/checkers/api/target/files.lua33
-rw-r--r--xmake/modules/private/check/checkers/api/target/fpmodels.lua27
-rw-r--r--xmake/modules/private/check/checkers/api/target/frameworkdirs.lua32
-rw-r--r--xmake/modules/private/check/checkers/api/target/headerfiles.lua34
-rw-r--r--xmake/modules/private/check/checkers/api/target/includedirs.lua32
-rw-r--r--xmake/modules/private/check/checkers/api/target/installfiles.lua34
-rw-r--r--xmake/modules/private/check/checkers/api/target/kind.lua27
-rw-r--r--xmake/modules/private/check/checkers/api/target/languages.lua41
-rw-r--r--xmake/modules/private/check/checkers/api/target/ldflags.lua36
-rw-r--r--xmake/modules/private/check/checkers/api/target/linkdirs.lua32
-rw-r--r--xmake/modules/private/check/checkers/api/target/optimize.lua27
-rw-r--r--xmake/modules/private/check/checkers/api/target/packages.lua33
-rw-r--r--xmake/modules/private/check/checkers/api/target/shflags.lua36
-rw-r--r--xmake/modules/private/check/checkers/api/target/strip.lua27
-rw-r--r--xmake/modules/private/check/checkers/api/target/symbols.lua34
-rw-r--r--xmake/modules/private/check/checkers/api/target/vectorexts.lua27
-rw-r--r--xmake/modules/private/check/checkers/api/target/version.lua42
-rw-r--r--xmake/modules/private/check/checkers/api/target/warnings.lua27
-rw-r--r--xmake/modules/private/check/checkers/clang/tidy.lua179
-rw-r--r--xmake/modules/private/check/checkers/cuda/devlink.lua54
28 files changed, 1273 insertions, 0 deletions
diff --git a/xmake/modules/private/check/checker.lua b/xmake/modules/private/check/checker.lua
new file mode 100644
index 000000000..9396f825f
--- /dev/null
+++ b/xmake/modules/private/check/checker.lua
@@ -0,0 +1,105 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file checker.lua
+--
+
+-- imports
+import("core.base.option")
+
+-- get all checkers
+function checkers()
+ local checkers = _g._CHECKERS
+ if not checkers then
+ checkers = {
+ -- target api checkers
+ ["api.target.version"] = {description = "Check version configuration in target."},
+ ["api.target.kind"] = {description = "Check kind configuration in target.", timely = true},
+ ["api.target.strip"] = {description = "Check strip configuration in target.", timely = true},
+ ["api.target.optimize"] = {description = "Check optimize configuration in target.", timely = true},
+ ["api.target.symbols"] = {description = "Check symbols configuration in target.", timely = true},
+ ["api.target.fpmodels"] = {description = "Check fpmodels configuration in target.", timely = true},
+ ["api.target.warnings"] = {description = "Check warnings configuration in target.", timely = true},
+ ["api.target.languages"] = {description = "Check languages configuration in target.", timely = true},
+ ["api.target.vectorexts"] = {description = "Check vectorexts configuration in target.", timely = true},
+ ["api.target.exceptions"] = {description = "Check exceptions configuration in target.", timely = true},
+ ["api.target.packages"] = {description = "Check packages configuration in target."},
+ ["api.target.files"] = {description = "Check files configuration in target."},
+ ["api.target.headerfiles"] = {description = "Check header files configuration in target."},
+ ["api.target.installfiles"] = {description = "Check install files configuration in target."},
+ ["api.target.configfiles"] = {description = "Check config files configuration in target."},
+ ["api.target.linkdirs"] = {description = "Check linkdirs configuration in target.", timely = true},
+ ["api.target.includedirs"] = {description = "Check includedirs configuration in target.", timely = true},
+ ["api.target.frameworkdirs"] = {description = "Check frameworkdirs configuration in target.", timely = true},
+ ["api.target.cflags"] = {description = "Check c compiler flags configuration in target."},
+ ["api.target.cxflags"] = {description = "Check c/c++ compiler flags configuration in target."},
+ ["api.target.cxxflags"] = {description = "Check c++ compiler flags configuration in target."},
+ ["api.target.asflags"] = {description = "Check assembler flags configuration in target."},
+ ["api.target.ldflags"] = {description = "Check binary linker flags configuration in target."},
+ ["api.target.shflags"] = {description = "Check shared library linker flags configuration in target."},
+ -- cuda checkers
+ ["cuda.devlink"] = {description = "Check devlink for targets."},
+ -- clang tidy checker
+ ["clang.tidy"] = {description = "Check project code using clang-tidy.", showstats = false}
+ }
+ _g._CHECKERS = checkers
+ end
+ return checkers
+end
+
+-- complete checkers
+function complete(complete, opt)
+ return try
+ {
+ function ()
+ local list = {}
+ local groupstats = {}
+ for name, _ in table.orderpairs(checkers()) do
+ local groupname = name:split(".", {plain = true})[1]
+ groupstats[groupname] = (groupstats[groupname] or 0) + 1
+ if not complete then
+ local limit = 16
+ if groupstats[groupname] < limit then
+ table.insert(list, name)
+ elseif groupstats[groupname] == limit then
+ table.insert(list, "...")
+ end
+ elseif name:startswith(complete) then
+ table.insert(list, name)
+ end
+ end
+ return list
+ end
+ }
+end
+
+-- update stats
+function update_stats(level, count)
+ local stats = _g.stats
+ if not stats then
+ stats = {}
+ _g.stats = stats
+ end
+ count = count or 1
+ stats[level] = (stats[level] or 0) + count
+end
+
+-- show stats
+function show_stats()
+ local stats = _g.stats or {}
+ cprint("${bright}%d${clear} notes, ${color.warning}%d${clear} warnings, ${color.error}%d${clear} errors", stats.note or 0, stats.warning or 0, stats.error or 0)
+end
diff --git a/xmake/modules/private/check/checkers/api/api_checker.lua b/xmake/modules/private/check/checkers/api/api_checker.lua
new file mode 100644
index 000000000..79e4809bd
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/api_checker.lua
@@ -0,0 +1,158 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file api_checker.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.hashset")
+import("core.project.project")
+import("..checker")
+
+-- get the most probable value
+function _get_most_probable_value(value, valueset)
+ local result
+ local mindist
+ for v in valueset:keys() do
+ local dist = value:levenshtein(v)
+ if not mindist or dist < mindist then
+ mindist = dist
+ result = v
+ end
+ end
+ return result
+end
+
+function _do_show(str, opt)
+ _g.showed = _g.showed or {}
+ local showed = _g.showed
+ local infostr
+ if str then
+ infostr = string.format("%s: %s: %s", opt.sourcetips, opt.level_tips, str)
+ else
+ infostr = string.format("%s: %s: unknown %s value '%s'", opt.sourcetips, opt.level_tips, opt.apiname, opt.value)
+ end
+ if opt.probable_value then
+ infostr = string.format("%s, it may be '%s'", infostr, opt.probable_value)
+ end
+ if not showed[infostr] then
+ cprint(infostr)
+ showed[infostr] = true
+ return true
+ end
+end
+
+-- show result
+function _show(apiname, value, target, opt)
+ opt = opt or {}
+
+ -- match level? verbose: note/warning/error, default: warning/error
+ local level = opt.level
+ if not option.get("verbose") and level == "note" then
+ return
+ end
+
+ -- get source information
+ local sourceinfo = target:sourceinfo(apiname, value) or {}
+ local sourcetips = sourceinfo.file or ""
+ if sourceinfo.line then
+ sourcetips = sourcetips .. ":" .. (sourceinfo.line or -1)
+ end
+ if #sourcetips == 0 then
+ sourcetips = string.format("target(%s)", target:name())
+ end
+
+ -- get level tips
+ local level_tips = "note"
+ if level == "warning" then
+ level_tips = "${color.warning}${text.warning}${clear}"
+ elseif level == "error" then
+ level_tips = "${color.error}${text.error}${clear}"
+ end
+
+ -- get probable value
+ local probable_value
+ if opt.valueset then
+ probable_value = _get_most_probable_value(value, opt.valueset)
+ end
+
+ if apiname:endswith("s") then
+ apiname = apiname:sub(1, #apiname - 1)
+ end
+
+ -- do show
+ return (opt.show or _do_show)(opt.showstr, {
+ apiname = apiname,
+ sourcetips = sourcetips,
+ level_tips = level_tips,
+ value = value,
+ probable_value = probable_value})
+end
+
+-- check target
+function _check_target(target, apiname, valueset, level, opt)
+ local target_valueset = valueset
+ if type(opt.values) == "function" then
+ local target_values = opt.values(target)
+ if target_values then
+ target_valueset = hashset.from(target_values)
+ end
+ end
+ local values = target:get(apiname)
+ for _, value in ipairs(values) do
+ if opt.check then
+ local ok, errors = opt.check(target, value)
+ if not ok then
+ local reported = _show(apiname, value, target, {
+ show = opt.show,
+ showstr = errors,
+ level = level})
+ if reported then
+ checker.update_stats(level)
+ end
+ end
+ elseif not target_valueset:has(value) then
+ local reported = _show(apiname, value, target, {
+ show = opt.show,
+ valueset = target_valueset,
+ level = level})
+ if reported then
+ checker.update_stats(level)
+ end
+ end
+ end
+end
+
+-- check api configuration in targets
+function check_targets(apiname, opt)
+ opt = opt or {}
+ local level = opt.level or "warning"
+ local valueset
+ if opt.values and type(opt.values) ~= "function" then
+ valueset = hashset.from(opt.values)
+ else
+ valueset = hashset.new()
+ end
+ if opt.target then
+ _check_target(opt.target, apiname, valueset, level, opt)
+ else
+ for _, target in pairs(project.targets()) do
+ _check_target(target, apiname, valueset, level, opt)
+ end
+ end
+end
diff --git a/xmake/modules/private/check/checkers/api/target/asflags.lua b/xmake/modules/private/check/checkers/api/target/asflags.lua
new file mode 100644
index 000000000..07de9c4ec
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/asflags.lua
@@ -0,0 +1,34 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file asflags.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("asflags", table.join(opt, {check = function(target, value)
+ local compinst = target:compiler("as")
+ if not compinst:has_flags(value) then
+ return false, string.format("%s: unknown assembler flag '%s'", compinst:name(), value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/cflags.lua b/xmake/modules/private/check/checkers/api/target/cflags.lua
new file mode 100644
index 000000000..db35a7bcf
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/cflags.lua
@@ -0,0 +1,34 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file cflags.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("cflags", table.join(opt, {check = function(target, value)
+ local compinst = target:compiler("cc")
+ if not compinst:has_flags(value) then
+ return false, string.format("%s: unknown c compiler flag '%s'", compinst:name(), value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/configfiles.lua b/xmake/modules/private/check/checkers/api/target/configfiles.lua
new file mode 100644
index 000000000..a8965eebe
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/configfiles.lua
@@ -0,0 +1,33 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file configfiles.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("configfiles", table.join(opt, {check = function(target, value)
+ local configfiles = os.files(value)
+ if not configfiles or #configfiles == 0 then
+ return false, string.format("configfiles '%s' not found", value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/cxflags.lua b/xmake/modules/private/check/checkers/api/target/cxflags.lua
new file mode 100644
index 000000000..ba09366e0
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/cxflags.lua
@@ -0,0 +1,34 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file cxflags.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("cxflags", table.join(opt, {check = function(target, value)
+ local compinst = target:compiler("cxx")
+ if not compinst:has_flags(value) then
+ return false, string.format("%s: unknown c/c++ compiler flag '%s'", compinst:name(), value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/cxxflags.lua b/xmake/modules/private/check/checkers/api/target/cxxflags.lua
new file mode 100644
index 000000000..84660cfa4
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/cxxflags.lua
@@ -0,0 +1,34 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file cxxflags.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("cxxflags", table.join(opt, {check = function(target, value)
+ local compinst = target:compiler("cxx")
+ if not compinst:has_flags(value) then
+ return false, string.format("%s: unknown c++ compiler flag '%s'", compinst:name(), value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/exceptions.lua b/xmake/modules/private/check/checkers/api/target/exceptions.lua
new file mode 100644
index 000000000..e9570a894
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/exceptions.lua
@@ -0,0 +1,27 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file exceptions.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("exceptions", table.join(opt, {values = {"none", "cxx", "objc", "no-cxx", "no-objc"}}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/files.lua b/xmake/modules/private/check/checkers/api/target/files.lua
new file mode 100644
index 000000000..a523a7413
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/files.lua
@@ -0,0 +1,33 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file files.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("files", table.join(opt, {check = function(target, value)
+ local files = os.files(value)
+ if not files or #files == 0 then
+ return false, string.format("files '%s' not found", value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/fpmodels.lua b/xmake/modules/private/check/checkers/api/target/fpmodels.lua
new file mode 100644
index 000000000..61231109e
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/fpmodels.lua
@@ -0,0 +1,27 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file fpmodels.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("fpmodels", table.join(opt, {values = {"none", "precise", "fast", "strict", "except", "noexcept"}}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/frameworkdirs.lua b/xmake/modules/private/check/checkers/api/target/frameworkdirs.lua
new file mode 100644
index 000000000..088aa7114
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/frameworkdirs.lua
@@ -0,0 +1,32 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file frameworkdirs.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("frameworkdirs", table.join(opt, {check = function(target, value)
+ if not os.isdir(value) then
+ return false, string.format("frameworkdir '%s' not found", value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/headerfiles.lua b/xmake/modules/private/check/checkers/api/target/headerfiles.lua
new file mode 100644
index 000000000..af262b91c
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/headerfiles.lua
@@ -0,0 +1,34 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file headerfiles.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("headerfiles", table.join(opt, {check = function(target, value)
+ value = value:gsub("[()]", "")
+ local headerfiles = os.files(value)
+ if not headerfiles or #headerfiles == 0 then
+ return false, string.format("headerfiles '%s' not found", value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/includedirs.lua b/xmake/modules/private/check/checkers/api/target/includedirs.lua
new file mode 100644
index 000000000..a78431fef
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/includedirs.lua
@@ -0,0 +1,32 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file includedirs.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("includedirs", table.join(opt, {check = function(target, value)
+ if not os.isdir(value) then
+ return false, string.format("includedir '%s' not found", value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/installfiles.lua b/xmake/modules/private/check/checkers/api/target/installfiles.lua
new file mode 100644
index 000000000..7a294f60f
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/installfiles.lua
@@ -0,0 +1,34 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file installfiles.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("installfiles", table.join(opt, {check = function(target, value)
+ value = value:gsub("[()]", "")
+ local installfiles = os.files(value)
+ if not installfiles or #installfiles == 0 then
+ return false, string.format("installfiles '%s' not found", value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/kind.lua b/xmake/modules/private/check/checkers/api/target/kind.lua
new file mode 100644
index 000000000..127f78ad5
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/kind.lua
@@ -0,0 +1,27 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file kind.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("kind", table.join(opt, {values = {"object", "binary", "static", "shared", "headeronly", "phony"}}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/languages.lua b/xmake/modules/private/check/checkers/api/target/languages.lua
new file mode 100644
index 000000000..f01499225
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/languages.lua
@@ -0,0 +1,41 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file languages.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ local values = {
+ "ansi", "c89", "c90", "c99", "c11", "c17", "clatest",
+ "cxx98", "cxx11", "cxx14", "cxx17", "cxx1z", "cxx20", "cxx2a", "cxx23", "cxx2b", "cxxlatest"
+ }
+ local languages = {}
+ for _, value in ipairs(values) do
+ table.insert(languages, value)
+ if value:find("xx", 1, true) then
+ table.insert(languages, (value:gsub("xx", "++")))
+ end
+ if value:startswith("c") then
+ table.insert(languages, "gnu" .. value:sub(2))
+ end
+ end
+ api_checker.check_targets("languages", table.join(opt, {values = languages}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/ldflags.lua b/xmake/modules/private/check/checkers/api/target/ldflags.lua
new file mode 100644
index 000000000..e06d5bb09
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/ldflags.lua
@@ -0,0 +1,36 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file ldflags.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("ldflags", table.join(opt, {check = function(target, value)
+ if target:is_binary() then
+ local linker = target:linker()
+ if not linker:has_flags(value) then
+ return false, string.format("%s: unknown linker flag '%s'", linker:name(), value)
+ end
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/linkdirs.lua b/xmake/modules/private/check/checkers/api/target/linkdirs.lua
new file mode 100644
index 000000000..3f05bfa16
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/linkdirs.lua
@@ -0,0 +1,32 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file linkdirs.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("linkdirs", table.join(opt, {check = function(target, value)
+ if not os.isdir(value) then
+ return false, string.format("linkdir '%s' not found", value)
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/optimize.lua b/xmake/modules/private/check/checkers/api/target/optimize.lua
new file mode 100644
index 000000000..99731ba19
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/optimize.lua
@@ -0,0 +1,27 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file optimize.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("optimize", table.join(opt, {values = {"none", "fast", "faster", "fastest", "smallest", "aggressive"}}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/packages.lua b/xmake/modules/private/check/checkers/api/target/packages.lua
new file mode 100644
index 000000000..994ea5c2a
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/packages.lua
@@ -0,0 +1,33 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file packages.lua
+--
+
+-- imports
+import("core.project.project")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ local packages = {}
+ local requires = project.required_packages()
+ if requires then
+ table.join2(packages, table.orderkeys(requires))
+ end
+ api_checker.check_targets("packages", table.join(opt, {values = packages, level = "note"}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/shflags.lua b/xmake/modules/private/check/checkers/api/target/shflags.lua
new file mode 100644
index 000000000..20b2f6a05
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/shflags.lua
@@ -0,0 +1,36 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file shflags.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("shflags", table.join(opt, {check = function(target, value)
+ if target:is_shared() then
+ local linker = target:linker()
+ if not linker:has_flags(value) then
+ return false, string.format("%s: unknown linker flag '%s'", linker:name(), value)
+ end
+ end
+ return true
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/strip.lua b/xmake/modules/private/check/checkers/api/target/strip.lua
new file mode 100644
index 000000000..c6074bc12
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/strip.lua
@@ -0,0 +1,27 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file strip.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("strip", table.join(opt, {values = {"none", "debug", "all"}}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/symbols.lua b/xmake/modules/private/check/checkers/api/target/symbols.lua
new file mode 100644
index 000000000..839bd0ede
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/symbols.lua
@@ -0,0 +1,34 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file symbols.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("symbols", table.join(opt, {values = function (target)
+ local values = {"none", "debug", "hidden", "hidden_cxx"}
+ if target:is_plat("windows") and (target:has_tool("cc", "cl") or target:has_tool("cxx", "cl")) then
+ table.insert(values, "edit")
+ table.insert(values, "embed")
+ end
+ return values
+ end}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/vectorexts.lua b/xmake/modules/private/check/checkers/api/target/vectorexts.lua
new file mode 100644
index 000000000..77f9ee48c
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/vectorexts.lua
@@ -0,0 +1,27 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file vectorexts.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("vectorexts", table.join(opt, {values = {"none", "sse", "sse2", "sse3", "ssse3", "avx", "avx2", "neon"}}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/version.lua b/xmake/modules/private/check/checkers/api/target/version.lua
new file mode 100644
index 000000000..889864f5b
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/version.lua
@@ -0,0 +1,42 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file version.lua
+--
+
+-- imports
+import("core.base.semver")
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("version", table.join(opt, {check = function(target, value)
+ local errors
+ local ok = try {
+ function()
+ semver.new(value)
+ return true
+ end,
+ catch {
+ function (errs)
+ errors = errs
+ end
+ }
+ }
+ return ok, errors
+ end, level = "error"}))
+end
diff --git a/xmake/modules/private/check/checkers/api/target/warnings.lua b/xmake/modules/private/check/checkers/api/target/warnings.lua
new file mode 100644
index 000000000..4e6cf5794
--- /dev/null
+++ b/xmake/modules/private/check/checkers/api/target/warnings.lua
@@ -0,0 +1,27 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file warnings.lua
+--
+
+-- imports
+import(".api_checker")
+
+function main(opt)
+ opt = opt or {}
+ api_checker.check_targets("warnings", table.join(opt, {values = {"none", "less", "more", "all", "allextra", "everything", "error"}}))
+end
diff --git a/xmake/modules/private/check/checkers/clang/tidy.lua b/xmake/modules/private/check/checkers/clang/tidy.lua
new file mode 100644
index 000000000..9b0d9b21e
--- /dev/null
+++ b/xmake/modules/private/check/checkers/clang/tidy.lua
@@ -0,0 +1,179 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file tidy.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.task")
+import("core.project.config")
+import("core.project.project")
+import("lib.detect.find_tool")
+import("private.async.runjobs")
+import("private.action.require.impl.packagenv")
+import("private.action.require.impl.install_packages")
+
+-- the clang.tidy options
+local options = {
+ {"l", "list", "k", nil, "Show the clang-tidy checks list."},
+ {'j', "jobs", "kv", tostring(os.default_njob()),
+ "Set the number of parallel check jobs."},
+ {nil, "create", "k", nil, "Create a .clang-tidy file."},
+ {nil, "configfile", "kv", nil, "Specify the path of .clang-tidy or custom config file"},
+ {nil, "checks", "kv", nil, "Set the given checks.",
+ "e.g.",
+ " - xmake check clang.tidy --checks=\"*\""},
+ {'f', "files", "v", nil, "Set files path with pattern",
+ "e.g.",
+ " - xmake check clang.tidy -f src/main.c",
+ " - xmake check clang.tidy -f 'src/*.c" .. path.envsep() .. "src/**.cpp'"},
+ {nil, "target", "v", nil, "Check the sourcefiles of the given target.",
+ ".e.g",
+ " - xmake check clang.tidy",
+ " - xmake check clang.tidy [target]"}
+}
+
+-- show checks list
+function _show_list(clang_tidy)
+ os.execv(clang_tidy, {"--list-checks"})
+end
+
+-- create .clang-tidy config file
+function _create_config(clang_tidy, opt)
+ local projectdir = project.directory()
+ local argv = {"--dump-config"}
+ if opt.checks then
+ table.insert(argv, "--checks=" .. opt.checks)
+ end
+ os.execv(clang_tidy, argv, {stdout = path.join(projectdir, ".clang-tidy"), curdir = projectdir})
+end
+
+-- add sourcefiles in target
+function _add_target_files(sourcefiles, target)
+ table.join2(sourcefiles, (target:sourcefiles()))
+end
+
+-- check sourcefile
+function _check_sourcefile(clang_tidy, sourcefile, opt)
+ opt = opt or {}
+ local projectdir = project.directory()
+ local argv = {}
+ if opt.checks then
+ table.insert(argv, "--checks=" .. opt.checks)
+ end
+ if opt.compdbfile then
+ table.insert(argv, "-p")
+ table.insert(argv, opt.compdbfile)
+ end
+ if opt.configfile then
+ table.insert(argv, "--config-file=" .. opt.configfile)
+ end
+ if not path.is_absolute(sourcefile) then
+ sourcefile = path.absolute(sourcefile, projectdir)
+ end
+ table.insert(argv, sourcefile)
+ os.execv(clang_tidy, argv, {curdir = projectdir})
+end
+
+-- do check
+function _check(clang_tidy, opt)
+ opt = opt or {}
+
+ -- generate compile_commands.json first
+ local filename = "compile_commands.json"
+ local filepath = filename
+ if not os.isfile(filepath) then
+ local outputdir = os.tmpfile() .. ".dir"
+ filepath = outputdir and path.join(outputdir, filename) or filename
+ task.run("project", {quiet = true, kind = "compile_commands", lsp = "clangd", outputdir = outputdir})
+ end
+ opt.compdbfile = filepath
+
+ -- get sourcefiles
+ local sourcefiles = {}
+ if opt.files then
+ local files = path.splitenv(opt.files)
+ for _, file in ipairs(files) do
+ for _, filepath in ipairs(os.files(file)) do
+ table.insert(sourcefiles, filepath)
+ end
+ end
+ else
+ local targetname = opt.target
+ if targetname then
+ _add_target_files(sourcefiles, project.target(targetname))
+ else
+ for _, target in ipairs(project.ordertargets()) do
+ _add_target_files(sourcefiles, target)
+ end
+ end
+ end
+
+ -- check files
+ local jobs = tonumber(opt.jobs or "1")
+ runjobs("check_files", function (index)
+ local sourcefile = sourcefiles[index]
+ if sourcefile then
+ _check_sourcefile(clang_tidy, sourcefile, opt)
+ end
+ end, {total = #sourcefiles,
+ comax = jobs,
+ isolate = true})
+end
+
+function main(argv)
+
+ -- parse arguments
+ local args = option.parse(argv or {}, options, "Use clang-tidy to check project code."
+ , ""
+ , "Usage: xmake check clang.tidy [options]")
+
+ -- enter the environments of llvm
+ local oldenvs = packagenv.enter("llvm")
+
+ -- find clang-tidy
+ local packages = {}
+ local clang_tidy = find_tool("clang-tidy")
+ if not clang_tidy then
+ table.join2(packages, install_packages("llvm"))
+ end
+
+ -- enter the environments of installed packages
+ for _, instance in ipairs(packages) do
+ instance:envs_enter()
+ end
+
+ -- we need force to detect and flush detect cache after loading all environments
+ if not clang_tidy then
+ clang_tidy = find_tool("clang-tidy", {force = true})
+ end
+ assert(clang_tidy, "clang-tidy not found!")
+
+ -- list checks
+ if args.list then
+ _show_list(clang_tidy.program)
+ elseif args.create then
+ _create_config(clang_tidy.program, args)
+ else
+ _check(clang_tidy.program, args)
+ end
+
+ -- done
+ os.setenvs(oldenvs)
+end
+
diff --git a/xmake/modules/private/check/checkers/cuda/devlink.lua b/xmake/modules/private/check/checkers/cuda/devlink.lua
new file mode 100644
index 000000000..4281b5a8d
--- /dev/null
+++ b/xmake/modules/private/check/checkers/cuda/devlink.lua
@@ -0,0 +1,54 @@
+--!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, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file devlink.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.project")
+
+-- https://github.com/xmake-io/xmake/issues/1976#issuecomment-1427378799
+function _check_target(target, opt)
+ if target:is_binary() then
+ local sourcebatches = target:sourcebatches()
+ if sourcebatches and not sourcebatches["cuda.build"] then
+ for _, dep in ipairs(target:orderdeps()) do
+ if dep:is_static() then
+ sourcebatches = dep:sourcebatches()
+ if sourcebatches and sourcebatches["cuda.build"] then
+ local devlink = dep:policy("build.cuda.devlink") or dep:values("cuda.build.devlink")
+ if not devlink then
+ wprint('target(%s)${clear}: cuda device link is not performed! specify set_policy("build.cuda.devlink", true) to enable it', dep:name())
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+function main(opt)
+ if opt.target then
+ _check_target(opt.target, opt)
+ else
+ for _, target in pairs(project.targets()) do
+ _check_target(target, opt)
+ end
+ end
+end
+