Can you make valid Makefiles without tab characters?

MakefileTabsWhitespaceSpaces

Makefile Problem Overview


target: dependencies
	command1
	command2

On my system (Mac OS X), make seems to require that that Makefiles have a tab character preceding the the content of each command line, or it throws a syntax error.

This is an annoyance when creating or editing Makefiles because I have my editor set up to be all-spaces-all-the-time.

Can you make valid Makefiles without tab characters?

Makefile Solutions


Solution 1 - Makefile

This is a syntax oddity/requirement of make, it has nothing to do with Mac OS X. Unfortunately, there's nothing you can do about it if you are going to use make.

Edit: GNU Make now supports a custom recipe prefix. See this answer.

You are not the first one to dislike this aspect of make. To quote Unix Haters' Handbook:

> The problem with Dennis’s Makefile is that when he added the comment line, he inadvertently inserted a space before the tab character at the beginning of line 2. The tab character is a very important part of the syntax of Makefiles. All command lines (the lines beginning with cc in our example) must start with tabs. After he made his change, line 2 didn’t, hence the error. > > “So what?” you ask, “What’s wrong with that?” > > There is nothing wrong with it, by itself. It’s just that when you consider how other programming tools work in Unix, using tabs as part of the syntax is like one of those pungee stick traps in The Green Berets: the poor kid from Kansas is walking point in front of John Wayne and doesn’t see the trip wire. After all, there are no trip wires to watch out for in Kansas corn fields. WHAM!

Solution 2 - Makefile

In the time since this question was originally asked, a version of GNU Make has been released that allows you to use something other than Tab as the prefix character. From the mailing list announcement:

> New special variable: .RECIPEPREFIX allows you to reset the recipe > introduction character from the default (TAB) to something else. The > first character of this variable value is the new recipe introduction > character. If the variable is set to the empty string, TAB is used again. > It can be set and reset at will; recipes will use the value active when > they were first parsed. To detect this feature check the value of $(.RECIPEPREFIX).

This feature was added in GNU Make 3.82, released in July 2010 (six months after this question's original ask date). Since it has in turn been three years and change since that, it's likely that other Make flavors have followed GNU Make.

Solution 3 - Makefile

There is a convoluted way of have a valid makefile without tabs.

If you change your makefile to read:

target: dependencies; command1; command2

If will work. If you want it on more than one line, then you can do:

target: dependencies; \
command1; \
command2

Messy, but it works.

Solution 4 - Makefile

If you have a vimrc in your profile you can add this line to prevent vim from changing to spaces:

autocmd FileType make setlocal noexpandtab

I too was struggling with this, and this fixed it for me. Spread the good word!

Solution 5 - Makefile

This does it for me if you would like to use spaces

.RECIPEPREFIX +=

Example

Solution 6 - Makefile

If you are using EditorConfig, you can add the following lines to your .editorconfig file to force your IDE to use tab for indentation instead of spaces in Makefile:

[Makefile]
indent_style = tab

Solution 7 - Makefile

In vim's insert mode, one can use Ctrl-v <TAB> to insert a literal tab, even if you have set the tab key to insert spaces. This doesn't answer your question, of course, but might be an alternative to the methods available to avoid needing literal tabs.

Solution 8 - Makefile

Until GNU Make 4.2

Steven Penny's answer works.

.RECIPEPREFIX +=

The reason why this works is described in my comment.


Since GNU Make 4.3 (released on 19 Jan 2020)

Behavior of += operator has been changed in a backward-incompatible way. If the left operand has an empty value, a space is no longer added.

You can instead use

.RECIPEPREFIX := $(.RECIPEPREFIX)<space>

, where <space> is a single space. Although $(.RECIPEPREFIX) is expanded as an empty value, this is needed not to let GNU Make ignore <space>. Note this code works even on GNU Make older than version 4.3.

Solution 9 - Makefile

in ubuntu: vi Makefiles replace space by tab (or anything else you want):

:%s/<space chars>/^I/g

For ex replace 8 spaces by tab:

:%s/        /^I/g

Be attention: ^I insert with tab key, not ^ and I characters :D

Solution 10 - Makefile

Not portably. Certain flavours of make absolutely require tab characters. Yet another reason for preferring tabs over spaces :-)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionxyzView Question on Stackoverflow
Solution 1 - MakefileAlok SinghalView Answer on Stackoverflow
Solution 2 - MakefileBrighid McDonnellView Answer on Stackoverflow
Solution 3 - MakefileGeorgeView Answer on Stackoverflow
Solution 4 - MakefilePericoloView Answer on Stackoverflow
Solution 5 - MakefileZomboView Answer on Stackoverflow
Solution 6 - Makefileiver56View Answer on Stackoverflow
Solution 7 - MakefilePatrick SananView Answer on Stackoverflow
Solution 8 - MakefileynnView Answer on Stackoverflow
Solution 9 - Makefilenobjta_9x_tqView Answer on Stackoverflow
Solution 10 - MakefileanonView Answer on Stackoverflow