@@ -47,10 +47,48 @@ ifeq ($(EMILY_ASAN),1)
4747 LDFLAGS += -fsanitize=address
4848endif
4949
50- .PHONY : all clean bench-native
50+ .PHONY : all clean bench-native cppcheck
5151
5252all : $(NIF_SO ) $(METALLIB )
5353
54+ # ------------------------------------------------------------------
55+ # cppcheck: static analysis of the first-party NIF sources.
56+ #
57+ # Deliberately self-contained: it does NOT need libmlx built or the
58+ # MLX_INCLUDE_DIR / FINE_INCLUDE_DIR / ERTS_INCLUDE_DIR env that the
59+ # real compile relies on, so a developer can just run `make cppcheck`
60+ # from the repo root without a full NIF build (and CI can run it on a
61+ # bare checkout). cppcheck degrades gracefully on the third-party
62+ # headers it can't see — we only feed it our own `-Ic_src` tree and
63+ # suppress the unavoidable missing-include notices for <mlx/...>,
64+ # <fine.hpp>, <erl_nif.h>, etc. Findings are therefore scoped to code
65+ # we actually own.
66+ #
67+ # `passedByValueCallback` is suppressed on purpose: every NIF entry
68+ # point takes its container/aggregate args (std::vector, std::string,
69+ # std::tuple) by value because Fine's FINE_NIF macro decodes each BEAM
70+ # term into a value and passes it in — the signature is dictated by the
71+ # binding, not a stray copy. (Plain helpers still use const& where they
72+ # should.) Use inline `// cppcheck-suppress <id>` for one-off cases.
73+ #
74+ # Install: `brew install cppcheck`.
75+ # ------------------------------------------------------------------
76+ CPPCHECK ?= cppcheck
77+ CPPCHECK_JOBS ?= $(shell sysctl -n hw.ncpu 2>/dev/null || echo 4)
78+ CPPCHECK_FLAGS := --enable=warning,performance,portability \
79+ --std=c++20 --language=c++ \
80+ --inline-suppr \
81+ --error-exitcode=1 \
82+ --quiet -j $(CPPCHECK_JOBS ) \
83+ -Ic_src \
84+ --suppress=missingInclude \
85+ --suppress=missingIncludeSystem \
86+ --suppress=unmatchedSuppression \
87+ --suppress=passedByValueCallback
88+
89+ cppcheck :
90+ $(CPPCHECK ) $(CPPCHECK_FLAGS ) $(SOURCES )
91+
5492# ------------------------------------------------------------------
5593# bench-native: standalone C++ microbenchmarks under bench/native/.
5694#
0 commit comments