Hi Magnus,
Is this formalized some place ? If not it would be good to get this
formalized and
posted on a wiki or at http://openjdk.java.net/groups/build/
Thanks
Kumar
On 10/8/2013 12:40 AM, Magnus Ihse Bursie wrote:
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