diff options
| author | ruki <[email protected]> | 2023-02-21 09:54:49 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-02-21 09:54:49 +0800 |
| commit | 8ea58baa753ebcbfce5cd434a92e3dd369da0e0d (patch) | |
| tree | 70a852b2c674ea283b873732dbbb44969a47d987 /xmake/modules | |
| parent | 775cc38c761e02fa3ff4825eabca344b98c75b78 (diff) | |
| parent | 0fc0959c413b6cb1900f59fee403502f7b8ae2e8 (diff) | |
Merge pull request #3397 from xmake-io/check
Improve check and add devlink checker
Diffstat (limited to 'xmake/modules')
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 + |
