Related
This is my makefile:
all:ll
ll:ll.c
gcc -c -Wall -Werror -02 c.c ll.c -o ll $# $<
clean :
\rm -fr ll
When I try to make clean or make make, I get this error:
:makefile:4: *** missing separator. Stop.
How can I fix it?
make defines a tab is required to start each recipe. All actions of every rule are identified by tabs. If you prefer to prefix your recipes with a character other than tab, you can set the .RECIPEPREFIX variable to an alternate character.
To check, I use the command cat -e -t -v makefile_name.
It shows the presence of tabs with ^I and line endings with $. Both are vital to ensure that dependencies end properly and tabs mark the action for the rules so that they are easily identifiable to the make utility.
Example:
Kaizen ~/so_test $ cat -e -t -v mk.t
all:ll$ ## here the $ is end of line ...
$
ll:ll.c $
^Igcc -c -Wall -Werror -02 c.c ll.c -o ll $# $<$
## the ^I above means a tab was there before the action part, so this line is ok .
$
clean :$
\rm -fr ll$
## see here there is no ^I which means , tab is not present ....
## in this case you need to open the file again and edit/ensure a tab
## starts the action part
On VS Code, just click the "Space: 4" on the downright corner and change it to tab when editing your Makefile.
By default, you should always write command after a Tab and not white space. This can be changed to another character with .RECIPEPREFIX variable.
This applies to gcc line (line #4) in your case. You need to insert tab before gcc.
Also replace \rm -fr ll with rm -fr ll. Insert tabs before this command too.
The solution for PyCharm would be to install a Makefile support plugin:
Open Preferences (cmd + ,)
Go to Plugins -> Marketplace
Search for Makefile support, install and restart the IDE.
This should fix the problem and provide a syntax for a makefile.
TLDR;
makefile syntax can be quirky
if you want a line of code to be interpreted as make code it must only be indented with spaces.
if you want a line of code to be interpreted as bash code it must only be indented with tabs
sometask:
ifeq ($FOO,bar) // this is make code. only spaces
echo "foobar" // this is bash code. only tabs
endif // again, this is make code. only spaces
technically its the leading indentation that dictates the interpreter.
Using .editorconfig to fix the tabs automagically:
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab
Its pretty old question but still I would like say about one more option using vi/vim editor to visualize the tabs. If you have vi/vim installed then open a Makefile (e.g. vim Makefile) and enter :set list. This will show number of tabs inserted as below,
%-linux: force$
^I#if [ "$(GCC_VERSION)" = "2.96" ] ; then \$
^I^Iecho ===== Generating build tree for legacy $# architecture =====; \$
^I^I$(CONFIGURE) $(CWD) $# legacy; \$
^Ielse \$
^I^Iecho ===== Generating build tree for $# architecture =====; \$
^I^I$(CONFIGURE) $(CWD) $#; \$
^Ifi$
^Icd build-$#;make$
You started line 4 with "space,space" instead of "tab" - nothing else.
When you created a Makefile in VSCode, You should set the Tab Size: 4.
If anyone of you are using a product from Intellij, the solution for this it's the following:
Go to Preferences > Editor > Code Style
here you need to select the file type related to your problem. But most probably you need to select Other File Types.
In the tab opened mark the checkbox for Use tab character and be careful, Tab size and Indent values must be 4.
The key point was "HARD TAB"
Check whether you used TAB instead of whitespace
Check your .vimrc for set tabstop=X
If you are using mcedit for makefile edit. you have to see the following mark.
This is because tab is replaced by spaces.
To disable this feature go to
gedit->edit->preferences->editor
and remove check for
"replace tab with space"
If you are here searching how to make the tabs and new lines you added understandable by vim you have to first enable tab in vim.
You can do it using :set noet i.e. (to switch from spaces to TAB) before you make your tab additions.
With this command your tabs will look like the other ones (i.e. ^I) and *** missing separator. Stop. error from make will go away :)
after you make changes you can switch back with :set et
Do yourself a favour and make this a permanent member of your .editorconfig, if your editor/IDE supports it (it probably does!)
[Makefile]
indent_style = tab
If you are editing your Makefile in eclipse:
Windows-> Preferences->General->Editor->Text Editors->Show Whitespace Characters -> Apply
Or use the shortcut shown below.
Tab will be represented by gray ">>" and Space will be represented by gray "." as in figure below.
If someone ever comes across this issue with
*** missing separator. Stop.
during the build, they should double-check their file system path to the sources, it should not contain special characters like "#"
e.g. path
/home/user/#my_sources/
might be invalid
This is my makefile:
all:ll
ll:ll.c
gcc -c -Wall -Werror -02 c.c ll.c -o ll $# $<
clean :
\rm -fr ll
When I try to make clean or make make, I get this error:
:makefile:4: *** missing separator. Stop.
How can I fix it?
make defines a tab is required to start each recipe. All actions of every rule are identified by tabs. If you prefer to prefix your recipes with a character other than tab, you can set the .RECIPEPREFIX variable to an alternate character.
To check, I use the command cat -e -t -v makefile_name.
It shows the presence of tabs with ^I and line endings with $. Both are vital to ensure that dependencies end properly and tabs mark the action for the rules so that they are easily identifiable to the make utility.
Example:
Kaizen ~/so_test $ cat -e -t -v mk.t
all:ll$ ## here the $ is end of line ...
$
ll:ll.c $
^Igcc -c -Wall -Werror -02 c.c ll.c -o ll $# $<$
## the ^I above means a tab was there before the action part, so this line is ok .
$
clean :$
\rm -fr ll$
## see here there is no ^I which means , tab is not present ....
## in this case you need to open the file again and edit/ensure a tab
## starts the action part
On VS Code, just click the "Space: 4" on the downright corner and change it to tab when editing your Makefile.
By default, you should always write command after a Tab and not white space. This can be changed to another character with .RECIPEPREFIX variable.
This applies to gcc line (line #4) in your case. You need to insert tab before gcc.
Also replace \rm -fr ll with rm -fr ll. Insert tabs before this command too.
The solution for PyCharm would be to install a Makefile support plugin:
Open Preferences (cmd + ,)
Go to Plugins -> Marketplace
Search for Makefile support, install and restart the IDE.
This should fix the problem and provide a syntax for a makefile.
TLDR;
makefile syntax can be quirky
if you want a line of code to be interpreted as make code it must only be indented with spaces.
if you want a line of code to be interpreted as bash code it must only be indented with tabs
sometask:
ifeq ($FOO,bar) // this is make code. only spaces
echo "foobar" // this is bash code. only tabs
endif // again, this is make code. only spaces
technically its the leading indentation that dictates the interpreter.
Using .editorconfig to fix the tabs automagically:
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab
Its pretty old question but still I would like say about one more option using vi/vim editor to visualize the tabs. If you have vi/vim installed then open a Makefile (e.g. vim Makefile) and enter :set list. This will show number of tabs inserted as below,
%-linux: force$
^I#if [ "$(GCC_VERSION)" = "2.96" ] ; then \$
^I^Iecho ===== Generating build tree for legacy $# architecture =====; \$
^I^I$(CONFIGURE) $(CWD) $# legacy; \$
^Ielse \$
^I^Iecho ===== Generating build tree for $# architecture =====; \$
^I^I$(CONFIGURE) $(CWD) $#; \$
^Ifi$
^Icd build-$#;make$
You started line 4 with "space,space" instead of "tab" - nothing else.
When you created a Makefile in VSCode, You should set the Tab Size: 4.
If anyone of you are using a product from Intellij, the solution for this it's the following:
Go to Preferences > Editor > Code Style
here you need to select the file type related to your problem. But most probably you need to select Other File Types.
In the tab opened mark the checkbox for Use tab character and be careful, Tab size and Indent values must be 4.
The key point was "HARD TAB"
Check whether you used TAB instead of whitespace
Check your .vimrc for set tabstop=X
If you are using mcedit for makefile edit. you have to see the following mark.
This is because tab is replaced by spaces.
To disable this feature go to
gedit->edit->preferences->editor
and remove check for
"replace tab with space"
If you are here searching how to make the tabs and new lines you added understandable by vim you have to first enable tab in vim.
You can do it using :set noet i.e. (to switch from spaces to TAB) before you make your tab additions.
With this command your tabs will look like the other ones (i.e. ^I) and *** missing separator. Stop. error from make will go away :)
after you make changes you can switch back with :set et
Do yourself a favour and make this a permanent member of your .editorconfig, if your editor/IDE supports it (it probably does!)
[Makefile]
indent_style = tab
If you are editing your Makefile in eclipse:
Windows-> Preferences->General->Editor->Text Editors->Show Whitespace Characters -> Apply
Or use the shortcut shown below.
Tab will be represented by gray ">>" and Space will be represented by gray "." as in figure below.
If someone ever comes across this issue with
*** missing separator. Stop.
during the build, they should double-check their file system path to the sources, it should not contain special characters like "#"
e.g. path
/home/user/#my_sources/
might be invalid
This is my makefile:
all:ll
ll:ll.c
gcc -c -Wall -Werror -02 c.c ll.c -o ll $# $<
clean :
\rm -fr ll
When I try to make clean or make make, I get this error:
:makefile:4: *** missing separator. Stop.
How can I fix it?
make defines a tab is required to start each recipe. All actions of every rule are identified by tabs. If you prefer to prefix your recipes with a character other than tab, you can set the .RECIPEPREFIX variable to an alternate character.
To check, I use the command cat -e -t -v makefile_name.
It shows the presence of tabs with ^I and line endings with $. Both are vital to ensure that dependencies end properly and tabs mark the action for the rules so that they are easily identifiable to the make utility.
Example:
Kaizen ~/so_test $ cat -e -t -v mk.t
all:ll$ ## here the $ is end of line ...
$
ll:ll.c $
^Igcc -c -Wall -Werror -02 c.c ll.c -o ll $# $<$
## the ^I above means a tab was there before the action part, so this line is ok .
$
clean :$
\rm -fr ll$
## see here there is no ^I which means , tab is not present ....
## in this case you need to open the file again and edit/ensure a tab
## starts the action part
On VS Code, just click the "Space: 4" on the downright corner and change it to tab when editing your Makefile.
By default, you should always write command after a Tab and not white space. This can be changed to another character with .RECIPEPREFIX variable.
This applies to gcc line (line #4) in your case. You need to insert tab before gcc.
Also replace \rm -fr ll with rm -fr ll. Insert tabs before this command too.
The solution for PyCharm would be to install a Makefile support plugin:
Open Preferences (cmd + ,)
Go to Plugins -> Marketplace
Search for Makefile support, install and restart the IDE.
This should fix the problem and provide a syntax for a makefile.
TLDR;
makefile syntax can be quirky
if you want a line of code to be interpreted as make code it must only be indented with spaces.
if you want a line of code to be interpreted as bash code it must only be indented with tabs
sometask:
ifeq ($FOO,bar) // this is make code. only spaces
echo "foobar" // this is bash code. only tabs
endif // again, this is make code. only spaces
technically its the leading indentation that dictates the interpreter.
Using .editorconfig to fix the tabs automagically:
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab
Its pretty old question but still I would like say about one more option using vi/vim editor to visualize the tabs. If you have vi/vim installed then open a Makefile (e.g. vim Makefile) and enter :set list. This will show number of tabs inserted as below,
%-linux: force$
^I#if [ "$(GCC_VERSION)" = "2.96" ] ; then \$
^I^Iecho ===== Generating build tree for legacy $# architecture =====; \$
^I^I$(CONFIGURE) $(CWD) $# legacy; \$
^Ielse \$
^I^Iecho ===== Generating build tree for $# architecture =====; \$
^I^I$(CONFIGURE) $(CWD) $#; \$
^Ifi$
^Icd build-$#;make$
You started line 4 with "space,space" instead of "tab" - nothing else.
When you created a Makefile in VSCode, You should set the Tab Size: 4.
If anyone of you are using a product from Intellij, the solution for this it's the following:
Go to Preferences > Editor > Code Style
here you need to select the file type related to your problem. But most probably you need to select Other File Types.
In the tab opened mark the checkbox for Use tab character and be careful, Tab size and Indent values must be 4.
The key point was "HARD TAB"
Check whether you used TAB instead of whitespace
Check your .vimrc for set tabstop=X
If you are using mcedit for makefile edit. you have to see the following mark.
This is because tab is replaced by spaces.
To disable this feature go to
gedit->edit->preferences->editor
and remove check for
"replace tab with space"
If you are here searching how to make the tabs and new lines you added understandable by vim you have to first enable tab in vim.
You can do it using :set noet i.e. (to switch from spaces to TAB) before you make your tab additions.
With this command your tabs will look like the other ones (i.e. ^I) and *** missing separator. Stop. error from make will go away :)
after you make changes you can switch back with :set et
Do yourself a favour and make this a permanent member of your .editorconfig, if your editor/IDE supports it (it probably does!)
[Makefile]
indent_style = tab
If you are editing your Makefile in eclipse:
Windows-> Preferences->General->Editor->Text Editors->Show Whitespace Characters -> Apply
Or use the shortcut shown below.
Tab will be represented by gray ">>" and Space will be represented by gray "." as in figure below.
If someone ever comes across this issue with
*** missing separator. Stop.
during the build, they should double-check their file system path to the sources, it should not contain special characters like "#"
e.g. path
/home/user/#my_sources/
might be invalid
I can't figure where my code is wrong. I'm trying to launch the "make" command on a C++-project in windows prompt (I installed mingw-get-inst-20120426 on my pc) and it gives me back always the same error:
Makefile:672: * missing separator. Stop.
This is the line 672 of my file:
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
I have check for hidden spaces in this line, but there are only tabs: I have no idea where the error is (I'm newbie to makefiles).
Can anybobody help me?
Thanks,
Stefano
You should show the rest of the rule, not just that one line. The problem is not on this line but on the lines before it. I'll make a guess and say that either (a) you've forgotten to add a backslash at the end of the previous line, or (b) you have a backslash but then you've also added some extra whitespace or whatever after the backslash; the backslash must be the last character on the line to be recognized as a continuation character.
It's possible that the variables $(MAKE) $(AM_MAKEFLAGS) include leading or trailing spaces, please post the context of this line in your Makefile, as-well as the values used for those variables.
Edit: I had intended my answer to be: the contents of $(MAKE) $(AM_MAKEFLAGS) likely include a trailing or leading space, thus causing this error.
In my makefile, I have a variable 'NDK_PROJECT_PATH', my question is how can I print it out when it compiles?
I read Make file echo displaying "$PATH" string and I tried:
#echo $(NDK_PROJECT_PATH)
#echo $(value NDK_PROJECT_PATH)
Both gives me
"build-local.mk:102: *** missing separator. Stop."
Any one knows why it is not working for me?
You can print out variables as the makefile is read (assuming GNU make as you have tagged this question appropriately) using this method (with a variable named "var"):
$(info $$var is [${var}])
You can add this construct to any recipe to see what make will pass to the shell:
.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world
Now, what happens here is that make stores the entire recipe ($(info $$var is [${var}])echo Hello world) as a single recursively expanded variable. When make decides to run the recipe (for instance when you tell it to build all), it expands the variable, and then passes each resulting line separately to the shell.
So, in painful detail:
It expands $(info $$var is [${var}])echo Hello world
To do this it first expands $(info $$var is [${var}])
$$ becomes literal $
${var} becomes :-) (say)
The side effect is that $var is [:-)] appears on standard out
The expansion of the $(info...) though is empty
Make is left with echo Hello world
Make prints echo Hello world on stdout first to let you know what it's going to ask the shell to do
The shell prints Hello world on stdout.
As per the GNU Make manual and also pointed by 'bobbogo' in the below answer,
you can use info / warning / error to display text.
$(error text…)
$(warning text…)
$(info text…)
To print variables,
$(error VAR is $(VAR))
$(warning VAR is $(VAR))
$(info VAR is $(VAR))
'error' would stop the make execution, after showing the error string
from a "Mr. Make post"
https://www.cmcrossroads.com/article/printing-value-makefile-variable
Add the following rule to your Makefile:
print-% : ; #echo $* = $($*)
Then, if you want to find out the value of a makefile variable, just:
make print-VARIABLE
and it will return:
VARIABLE = the_value_of_the_variable
If you simply want some output, you want to use $(info) by itself. You can do that anywhere in a Makefile, and it will show when that line is evaluated:
$(info VAR="$(VAR)")
Will output VAR="<value of VAR>" whenever make processes that line. This behavior is very position dependent, so you must make sure that the $(info) expansion happens AFTER everything that could modify $(VAR) has already happened!
A more generic option is to create a special rule for printing the value of a variable. Generally speaking, rules are executed after variables are assigned, so this will show you the value that is actually being used. (Though, it is possible for a rule to change a variable.) Good formatting will help clarify what a variable is set to, and the $(flavor) function will tell you what kind of a variable something is. So in this rule:
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) #true
$* expands to the stem that the % pattern matched in the rule.
$($*) expands to the value of the variable whose name is given by by $*.
The [ and ] clearly delineate the variable expansion.
You could also use " and " or similar.
$(flavor $*) tells you what kind of variable it is. NOTE: $(flavor)
takes a variable name, and not its expansion.
So if you say make print-LDFLAGS, you get $(flavor LDFLAGS),
which is what you want.
$(info text) provides output.
Make prints text on its stdout as a side-effect of the expansion.
The expansion of $(info) though is empty.
You can think of it like #echo,
but importantly it doesn't use the shell,
so you don't have to worry about shell quoting rules.
#true is there just to provide a command for the rule.
Without that,
make will also output print-blah is up to date. I feel #true makes it more clear that it's meant to be a no-op.
Running it, you get
$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]
All versions of make require that command lines be indented with a TAB (not space) as the first character in the line. If you showed us the entire rule instead of just the two lines in question we could give a clearer answer, but it should be something like:
myTarget: myDependencies
#echo hi
where the first character in the second line must be TAB.
#echo $(NDK_PROJECT_PATH) is the good way to do it.
I don't think the error comes from there.
Generally this error appears when you mistyped the intendation : I think you have spaces where you should have a tab.
No need to modify the Makefile.
$ cat printvars.mak
print-%:
#echo '$*=$($*)'
$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE
Run make -n; it shows you the value of the variable..
Makefile...
all:
#echo $(NDK_PROJECT_PATH)
Command:
export NDK_PROJECT_PATH=/opt/ndk/project
make -n
Output:
echo /opt/ndk/project
This makefile will generate the 'missing separator' error message:
all
#echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)
done:
#echo "All done"
There's a tab before the #echo "All done" (though the done: rule and action are largely superfluous), but not before the #echo PATH=$(PATH).
The trouble is that the line starting all should either have a colon : or an equals = to indicate that it is a target line or a macro line, and it has neither, so the separator is missing.
The action that echoes the value of a variable must be associated with a target, possibly a dummy or PHONEY target. And that target line must have a colon on it. If you add a : after all in the example makefile and replace the leading blanks on the next line by a tab, it will work sanely.
You probably have an analogous problem near line 102 in the original makefile. If you showed 5 non-blank, non-comment lines before the echo operations that are failing, it would probably be possible to finish the diagnosis. However, since the question was asked in May 2013, it is unlikely that the broken makefile is still available now (August 2014), so this answer can't be validated formally. It can only be used to illustrate a plausible way in which the problem occurred.
The problem is that echo works only under an execution block. i.e. anything after "xx:"
So anything above the first execution block is just initialization so no execution command can used.
So create a execution blocl
If you don't want to modify the Makefile itself, you can use --eval to add a new target, and then execute the new target, e.g.
make --eval='print-tests:
#echo TESTS $(TESTS)
' print-tests
You can insert the required TAB character in the command line using CTRL-V, TAB
example Makefile from above:
all: do-something
TESTS=
TESTS+='a'
TESTS+='b'
TESTS+='c'
do-something:
#echo "doing something"
#echo "running tests $(TESTS)"
#exit 1
This can be done in a generic way and can be very useful when debugging a complex makefile. Following the same technique as described in another answer, you can insert the following into any makefile:
# if the first command line argument is "print"
ifeq ($(firstword $(MAKECMDGOALS)),print)
# take the rest of the arguments as variable names
VAR_NAMES := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# turn them into do-nothing targets
$(eval $(VAR_NAMES):;#:))
# then print them
.PHONY: print
print:
#$(foreach var,$(VAR_NAMES),\
echo '$(var) = $($(var))';)
endif
Then you can just do "make print" to dump the value of any variable:
$ make print CXXFLAGS
CXXFLAGS = -g -Wall
You could create a vars rule in your make file, like this:
dispvar = echo $(1)=$($(1)) ; echo
.PHONY: vars
vars:
#$(call dispvar,SOMEVAR1)
#$(call dispvar,SOMEVAR2)
There are some more robust ways to dump all variables here: gnu make: list the values of all variables (or "macros") in a particular run.
if you use android make (mka) #echo $(NDK_PROJECT_PATH) will not work and gives you error *** missing separator. Stop."
use this answer if you are trying to print variables in android make
NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))
that worked for me
I usually echo with an error if I wanted to see the variable value.(Only if you wanted to see the value. It will stop execution.)
#echo $(error NDK_PROJECT_PATH= $(NDK_PROJECT_PATH))
The following command does it for me on Windows:
Path | tr ; "\n"