>
It is also a bunch of scripts in the one known file, and these can be dependent, programmed (if/for) or included from other sourcesSo it's not just one known file. Big trees can have lots of little makefiles.
> I'll never go into some .sh file to see what happens there, but often open Makefiles to find and tune details of anything.
Thanks for sharing. My own personal preference is such that I will never go into a Visual Basic file, but I will go into a Lisp.
You do know that the recipes in Makefiles are shell scripts? (With a subtle difference: each line implicitly executes in its own subshell, so setting variables or doing "cd" doesn't propagate). In a Makefile you still have to read shell code. It's mixed with make code, and with additional quoting rules and where true multi-line shell scripts that run in a single shell have to be written with backslash escapes; ugh.
(Note by the way that I didn't say anything about specifically using shell scripts for builds; I deliberately used the word "script" without qualification.)
> Not "a lot", but if I need reproducible actions in workdir, then it is Makefile.
If you want irreproducible parallel build problems, that's when you want make.
Sometimes Makefiles depend on execution orders which are not actually encoded as dependencies and these non-asserted orders turn into race conditions in a parallel build. You get a situation where in one out of twenty builds, that "y.tab.h" file out of yacc didn't get generated yet, while the lexical analyzer that wants to #include-s it is already being built. In single threaded mode, it just so happens that the rule which makes "y.tab.h" always runs first.
I once created an embedded Linux distro from scratch (build and packaging system and all). Over the base of supported packages we were pulling in, I saw quite a number of build issues of this type when the distro build would randomly fail to build a package due to race conditions like this.
GNU Make doesn't have any diagnostic ability that I know of to help you uncover where rules have unexpressed dependencies (a recipe refers to an input file which is the output of another rule, and that input file is not named as a prerequisite).