mirror of
https://github.com/SCST-project/scst.git
synced 2026-10-22 14:12:33 +00:00
Expose make cppcheck using freshly captured kernel CHECK commands and real userspace compiler invocations. Keep their include paths and definitions unchanged and analyze kernel and userspace contexts separately. Use the shared source scope without additional input exclusions, project models or diagnostic suppressions. Relevant diffs trigger full configured analysis; KUnit coverage follows the actual build configuration. Retain build logs, compilation databases, native XML and checker coverage. Separate source findings from parser failures, missing inputs and incomplete builds, with isolated report and capture fixtures.
56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Record Kbuild CHECK arguments or successful userspace compiler invocations."""
|
|
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import shlex
|
|
import sys
|
|
import uuid
|
|
|
|
sys.dont_write_bytecode = True
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT / "scripts"))
|
|
from lint_common import entrypoint, run # noqa: E402
|
|
from lint_scope import in_scope # noqa: E402
|
|
|
|
|
|
def source_files(arguments, profile, root):
|
|
if profile == "kernel":
|
|
candidates = arguments[-1:]
|
|
elif "-c" in arguments:
|
|
candidates = [arg for arg in arguments if arg.endswith(".c") and not arg.startswith("-")]
|
|
else:
|
|
return []
|
|
return [Path(arg).resolve() for arg in candidates
|
|
if Path(arg).is_file() and in_scope(Path(arg), root, "cppcheck")]
|
|
|
|
|
|
def main():
|
|
profile, *arguments = sys.argv[1:]
|
|
if profile not in {"kernel", "userspace"}:
|
|
raise ValueError(f"unknown capture profile: {profile}")
|
|
sources = source_files(arguments, profile, ROOT)
|
|
compiler = shlex.split(os.environ.get("SCST_LINT_CC", "cc"))
|
|
if not compiler:
|
|
raise ValueError("empty userspace compiler command")
|
|
# Kernel CHECK receives the real c_flags. It only records; Kbuild still
|
|
# invokes its own compiler. Do not run Sparse or add __CHECKER__ definitions.
|
|
command = (["cc"] if profile == "kernel" else compiler) + arguments
|
|
records = []
|
|
for source in sources:
|
|
path = Path(os.environ["SCST_LINT_RECORDS"]) / f"{uuid.uuid4()}.json"
|
|
record = {"file": str(source), "directory": str(Path.cwd()), "arguments": command,
|
|
"profile": profile, "returncode": 2}
|
|
path.write_text(json.dumps(record) + "\n")
|
|
records.append((path, record))
|
|
status = run(command).returncode if profile == "userspace" else 0
|
|
for path, record in records:
|
|
record["returncode"] = status
|
|
path.write_text(json.dumps(record) + "\n")
|
|
return status
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(entrypoint(main))
|