Was there any thought given to using this GNU Make feature to get rid of significant tab characters, or is it not even possible in all the supported build environments? Some of the legacy systems I deal with don't handle tab characters well.
From: http://www.gnu.org/software/make/manual/make.html#Special-Variables .RECIPEPREFIX The first character of the value of this variable is used as the character make assumes is introducing a recipe line. If the variable is empty (as it is by default) that character is the standard tab character. For example, this is a valid makefile: .RECIPEPREFIX = > all: > @echo Hello, world The value of .RECIPEPREFIX can be changed multiple times; once set it stays in effect for all rules parsed until it is modified. Tom Salter Unisys ------------------------------ Date: Tue, 08 Oct 2013 09:40:28 +0200 From: Magnus Ihse Bursie <magnus.ihse.bur...@oracle.com> Subject: Code conventions for the build system To: build-dev <build-dev@openjdk.java.net> Message-ID: <5253b6ec.9020...@oracle.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Whitespace and indentation in makefiles is a more problematic area than for other languages. Even while most of the time whitespace is not significant, sometimes is is. This might be considered a design flaw in make, but that's not something we can do anything about. In particular, initial tabs signify make rule recipes, and in make string manipulation, sometimes spaces matter. Probably partly due to this, there is little editor/IDE/tooling support for automatically formatting makefiles. This in turns makes keeping sane whitespace usage and indentation a "manual" task. When we started writing the new build system, we didn't set up a set of coding conventions to regulate whitespace and indentation (which we regret now). So the existing code varies wildly in style and indentation. All too often, proper indentation is completely missing, making it hard to read and understand the code. So, we created a set of rules for indention and whitespace usage. We tried to stay close to the Java code conventions, but Makefiles are not Java source code. We have then started to transform the code base according to these conventions. A webrev will shortly follow, with the whitespace changes resulting from this work. But first, let us present the set of rules. Indentation: 1) The basic level of indentation is two spaces. Use this for "logical" indentation (if blocks, function definitions etc). 2) If a line must be broken, use four spaces for indentation. 3) Recipes in makefile rules must start with a tab (per definition). 4) If a single tab (interpreted as 8 spaces wide) is not enough to put the recipe clearly indented (meaning at least 4 spaces difference) from the code around it, use additional tabs. 5) Non-shell commands in a recipe (e.g. comments and make directives like ifdef) must not start with tab, but should instead be indented to the same level as the surrounding shell commands using spaces (with tabs interpreted as 8 spaces wide). 6) Additional indentation in recipes should be done using space after the tab(s), as in normal makefile lines. 7) Partial recipes (macro definitions that are supposed to be inlined into a recipe) should be treaded like a recipe and start with tabs as well. Whitespace, required: 8) Trailing whitespaces is never allowed. 9) Do not use tabs, only spaces (except for in recipes, as stated by rule 3-7). Whitespace, recommended: 10) There should be no whitespace between the list of targets and the : at the start of a rule. 11) There should be an empty line before and after each rule. 12) Avoid empty lines inside the recipe. 13) Broken lines should end with a backslash, and a single space before the backslash (" \"). 14) A single space should separate a comma from the next argument in a function call. 15) A single space should be used before and after assignment operators (e.g. :=, =, +=). These recommendations are not always possible to follow, since whitespace might have semantic meaning. If an exception from these recommendations is required by make, it should ideally be pointed out by a comment. Especially spacing around commas might be sensitive, so beware. Style recommentations: 16) Use := (direct assignment) instead of = (recursive macro definition), unless you really need the recursive definition. 17) In long lists, do not let the first and last element have different form. For instance, start the first element on a new line rather than after a :=, and end the list with an empty comment (#) to be able to have a trailing backslash on the last line. 18) Avoid padding internally in a line with spaces to try to align some feature into columns with surrounding lines. 19) For multiple commands run by the shell, separated by "&& \" or similar, all commands should start at the same indention level. Rationales (to some of the rules): 1-2) This is in contrast to Java, which has twice as long indentations (4 space logical indentation, 8 spaces for wrapped lines). But since all indentation needs to be done basically by repeatedly pressing space, and since wrapped lines are fairly common, we felt it important to keep the indentation level short. Otherwise a wrapped line two levels in would needed 16 presses on the space bar. 9-12) Tabs are required in recipes, but for the sake of sanity, this is the only accepted use of tabs. The makefile syntax does not make it easy to spot rules in complex makefiles, and everything that helps in distinguishing rules from non-rules is needed. 16) Recursive macro definition (= instead of :=) slows down make and can have surprising effects. Typically this is not what you mean. 17-18) A very typical use case of makefile changes is to add things (files, compiler directives, etc) to a list. These rules help making such changes easy and context free. Otherwise the developer must modify several lines that are unrelated to the actual change. Chances are that a nicely padded grid will not be updated and start deteriorating from the very first change. 19) Separating multiple shell commands (e.g. after a shell "if" command) should not be considered a broken line which needs to be indenting, but a way to specify a list of commands on the same indentation levels. This is after all the intent; the && is merely a roundabout device to get this to work properly in makefiles. /Magnus