One of the most confusing things about C/C++ projects is that there is no single “default” build system. This is not the case for many other programming languages (Python: pip, Rust: cargo, Lua: luarocks, etc.). While this is true for C++, it’s actually not the case for C. C does have a build system, and even an environment, and that environment is UNIX. On UNIX, the default build system is, of course, make(1).
Make is a UNIX utility and it is standardized by POSIX, but programmers often treat GNU make (gmake) as if it’s the standard. They use GNU-specific options even when it isn’t necessary, and assume that’s how make “should” work. Almost everyone does this: most popular YouTube tutorials teach GNU make, and even in very professional projects programmers use gmake even when POSIX make would have been perfectly fine. GNU make is the “default” on GNU/Linux systems, but it is not the standard, so if you want your build system to be portable you should stick to POSIX make. POSIX make is much simpler, every make implementation can run it, and it does not add another build dependency to your projects because every UNIX system should have it installed.
GNU make becomes a problem on non-GNU systems, and it can also make it harder for package maintainers to determine the correct build dependency. If you must use GNU make (because it has more features), don’t name your file Makefile name it GNUmakefile instead. Also keep in mind that by using gmake you are adding another build dependency. GNU make will automatically read GNUmakefile as well as a normal Makefile, and the name makes it clearer what you’re actually using.
If you decide to use POSIX make, put .POSIX: at the beginning of your Makefile. If you’re using a BSD implementation it’s generally obvious, since BSD make isn’t commonly used outside of BSD-centric projects, but it’s still better to include a short comment specifying the expected implementation.
You can use pdpmake to check whether your Makefile uses any non-standard extensions.