diff options
| author | 24bit-xjkp <[email protected]> | 2025-09-21 17:44:10 +0800 |
|---|---|---|
| committer | 24bit-xjkp <[email protected]> | 2025-09-21 17:44:10 +0800 |
| commit | 586e243c43e58399042c863c64ccb7a89a622cbd (patch) | |
| tree | ca6ac46aad3618c37af96b26eb10bd10a909b510 | |
| parent | f9bc475a5ba47b954d23d16c71a4b6bbd4cb6ca4 (diff) | |
feat(clang-tidy): Improve clang-tidy support
1. Improve "compdb" option, supporting the directory containing the json db file. This will shorten the command line since "compile_commands.json" is a long name.
2. Use `opt.compdb` instead of `option.get("compdb")` because `option.get` doesn't work and returns a nil in this scope. I don't know the reason.
3. Motivated by the python script `run-clang-tidy` in llvm project, each clang-tidy subprocess new only processes a source file and use multi-process to implement parallel analysis based on `async.runjobs`
4. Use `os.execv` instead of `os.vrunv` since diagnoses are always wanted in static analysis.
5. Add a timer for check action.
| -rw-r--r-- | xmake/modules/private/check/checkers/clang/tidy.lua | 65 |
1 files changed, 26 insertions, 39 deletions
diff --git a/xmake/modules/private/check/checkers/clang/tidy.lua b/xmake/modules/private/check/checkers/clang/tidy.lua index e9fb9e60b..4a185e705 100644 --- a/xmake/modules/private/check/checkers/clang/tidy.lua +++ b/xmake/modules/private/check/checkers/clang/tidy.lua @@ -33,6 +33,7 @@ import("private.action.require.impl.install_packages") -- the clang.tidy options local options = { {"l", "list", "k", nil, "Show the clang-tidy checks list."}, + {"v", "verbose", "k", nil, "Show verbose output."}, {"j", "jobs", "kv", tostring(os.default_njob()), "Set the number of parallel check jobs."}, {"q", "quiet", "k", nil, "Run clang-tidy in quiet mode."}, @@ -40,8 +41,8 @@ local options = { {nil, "fix_errors", "k", nil, "Apply suggested errors fixes."}, {nil, "fix_notes", "k", nil, "Apply suggested notes fixes."}, {nil, "create", "k", nil, "Create a .clang-tidy file."}, - {nil, "configfile", "kv", nil, "Specify the path of .clang-tidy or custom config file"}, - {nil, "compdb", "kv", nil, "Specify the path of the compile_commands.json file"}, + {nil, "configfile", "kv", nil, "Specify the path of .clang-tidy or custom config file."}, + {nil, "compdb", "kv", nil, "Specify the path of the compile_commands.json file or the directory containing the file."}, {nil, "checks", "kv", nil, "Set the given checks.", "e.g.", " - xmake check clang.tidy --checks=\"*\""}, @@ -83,19 +84,6 @@ function _add_target_files(sourcefiles, target) end end -function _run_clang_tidy(clang_tidy, argv, opt) - -- https://github.com/llvm/llvm-project/pull/120547 - if clang_tidy.version and semver.compare(clang_tidy.version, "19.1.6") > 0 and #argv > 10 then - local argsfile = os.tmpfile() .. ".args.txt" - io.writefile(argsfile, os.args(argv)) - argv = {"@" .. argsfile} - os.vrunv(clang_tidy.program, argv, opt) - os.rm(argsfile) - else - os.vrunv(clang_tidy.program, argv, opt) - end -end - -- check sourcefiles function _check_sourcefiles(clang_tidy, sourcefiles, opt) opt = opt or {} @@ -124,30 +112,24 @@ function _check_sourcefiles(clang_tidy, sourcefiles, opt) table.insert(argv, "--quiet") end - -- split sourcefiles - local arguments_maxn = 32 - local sourcefiles_argv = {} local sourcefiles_jobs = {} for _, sourcefile in ipairs(sourcefiles) do if not path.is_absolute(sourcefile) then sourcefile = path.absolute(sourcefile, projectdir) end - table.insert(sourcefiles_argv, sourcefile) - if #sourcefiles_argv >= arguments_maxn then - table.insert(sourcefiles_jobs, sourcefiles_argv) - sourcefiles_argv = {} - end - end - if #sourcefiles_argv > 0 then - table.insert(sourcefiles_jobs, sourcefiles_argv) + local source_files_argv = table.join(argv, {sourcefile}) + table.insert(sourcefiles_jobs, {sourcefile, source_files_argv}) end + local analyze_time = os.mclock() -- run clang-tidy runjobs("checker.tidy", function (index, total, opt) - local tidy_argv = sourcefiles_jobs[index] - progress.show(index * 100 / total, "clang-tidy.analyzing %s .. %d", tidy_argv[1], #tidy_argv) - _run_clang_tidy(clang_tidy, tidy_argv, {curdir = projectdir}) + local sourcefile, tidy_argv = table.unpack(sourcefiles_jobs[index]) + progress.show(index * 100 / total, "clang-tidy.analyzing %s", sourcefile) + os.execv(clang_tidy.program, tidy_argv, {curdir = projectdir}) end, {total = #sourcefiles_jobs, comax = opt.jobs or os.default_njob()}) + analyze_time = os.mclock() - analyze_time + progress.show(100, "${color.success}clang-tidy.analyzed %d files, spent %.3fs", #sourcefiles_jobs, analyze_time / 1000) end -- do check @@ -155,8 +137,8 @@ function _check(clang_tidy, opt) opt = opt or {} -- generate compile_commands.json first - local filepath = option.get("compdb") - if not filepath then + local db_path = opt.compdb + if not db_path then -- @see https://github.com/xmake-io/xmake/issues/5583#issuecomment-2337696628 local outputdir local extraconf = project.extraconf("target.rules", "plugin.compile_commands.autoupdate") @@ -164,19 +146,25 @@ function _check(clang_tidy, opt) outputdir = extraconf.outputdir end if outputdir then - filepath = path.join(outputdir, "compile_commands.json") + db_path = path.join(outputdir, "compile_commands.json") end end - if not filepath then - filepath = "compile_commands.json" + if not db_path then + db_path = "compile_commands.json" + end + if os.isdir(db_path) then + local db_file_path = path.join(db_path, "compile_commands.json") + if os.isfile(db_file_path) then + db_path = db_file_path + end end - if not os.isfile(filepath) then + if not os.isfile(db_path) then local outputdir = os.tmpfile() .. ".dir" - local filename = path.filename(filepath) - filepath = outputdir and path.join(outputdir, filename) or filename + local filename = path.filename(db_path) + db_path = outputdir and path.join(outputdir, filename) or filename task.run("project", {quiet = true, kind = "compile_commands", lsp = "clangd", outputdir = outputdir}) end - opt.compdbfile = path.absolute(filepath) + opt.compdbfile = path.absolute(db_path) -- get sourcefiles local sourcefiles = {} @@ -243,4 +231,3 @@ function main(argv) end os.setenvs(oldenvs) end - |
