I recently released my first set of linter checks for POSIX makefiles: https://github.com/mcandre/unmake
Pre-compiled binaries are available in the latest release page, or you can compile manually with Rust. Things like := assignment, late .POSIX declarations, ambiguous include lines, and assignment to the SHELL macro, now enjoy mechanical detection suitable for CI/CD pipelines and local development workflows. I figure if a spec deems something UB, it's worth detecting by machine, reducing the risk of accidents. Maybe the GNU or BSD implementations also check for some of these? There's some gray area in between universal UB and ordinary implementation-defined behavior. This linter specifically intends to target strict POSIX makefiles, so when the spec says something is implementation defined, then the linter treats it essentially as a portability concern. If you simply adore gmake or bmake or whatever, this tool may not be for you. The linter is somewhat opinionated. For example, it recommends naming files like *.include.mk if they don't present the .POSIX: special target. (I don't think include files are allowed to use this target, right?) But most of the warnings are chosen with a balance in mind between strict POSIX portability on the one hand, and flexibility on the other. As much as I'd like to insist that targets named "uninstall" or "clean..." receive .IGNORE treatment, for idempotence, there's plenty enough reason to leave decisions like that up to the attentive makefile author. The linter's makefile grammar doesn't support multiline instructions in places other than commands and macro definitions. That's a tricky enough area of parsing that I would want to dedicate more time and testing some day. This is my first published AST, so I'm going slowly and methodically, adding linter support features incrementally. Of course, vendor-specific files like GNUmakefile / BSDmakefile are skipped from POSIX linting. And machine-generated makefiles should be skipped, too: autotools, cmake, gyp, Perl. Regardless, I thought I would share my progress. I'm still (heh) learning new things about make as I study the D3 spec in more detail. Any word on when the spec will crystallize into a fixed year release?