Code conventions for the build system

Kumar Srinivasan kumar.x.srinivasan at
Wed Dec 18 18:08:18 UTC 2013

Hi Magnus,

Is this formalized some place ? If not it would be good to get this 
formalized and
posted on a wiki or at


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

More information about the build-dev mailing list