Code conventions for the build system

Volker Simonis volker.simonis at gmail.com
Tue Oct 8 09:24:02 UTC 2013


Hi Magnus,

great work!
I completely agree with all points and especially like the indentation
level of two spaces:)

Thanks,
Volker


On Tue, Oct 8, 2013 at 9:40 AM, Magnus Ihse Bursie
<magnus.ihse.bursie at oracle.com> 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



More information about the build-dev mailing list