This question already has answers here:
Make error: missing separator
(14 answers)
Closed 8 years ago.
I have two .cpp files namely decryptor.cpp and prod-ent.cpp.
I have created a Makefile to for the compilation of both the files in Linux platform.
all: decryptor.cpp prod-ent.cpp
g++ prod-ent.cpp -o prod-ent -g
g++ decryptor.cpp -o decryptor -g -lcryptopp
clean:
rm prod-ent
rm decryptor
Whenever I'm trying to execute the Makefile its showing me the following error:
Makefile:2: * missing separator. Stop.
I am new to create makefiles and cannot figure out my fault. Please help me in correcting the code.
Thanks in advance !!
You need a real tab instead of space in front of g++ and rm commands. If still fails
then your editor is inserting spaces instead, even if you're hitting the tab key on your keyboard. You need to configure your editor to insert hard tabs (09 in ASCII) instead.
Like
all: decryptor.cpp prod-ent.cpp
*****g++ prod-ent.cpp -o prod-ent -g
*****g++ decryptor.cpp -o decryptor -g -lcryptopp
clean:
*****rm prod-ent
*****rm decryptor
Instead ***** replace TAB.
You can check your side by command
cat -e -t -v makefile
It's show line starting by ^I if TAB is given to that line and it end the line by $.
Also you can do by ;
all: decryptor.cpp prod-ent.cpp ; g++ prod-ent.cpp -o prod-ent -g ; g++ decryptor.cpp -o decryptor -g -lcryptopp
clean: ; rm prod-ent ; rm decryptor
Related
I am trying to run some old Fortran code of my project team in ubuntu 16.04. I have not done any modifications to the existing code.
All I have done is installed gfortran, opened a terminal, and went to the file location using "cd" command. Here I have many files, but just consider this three, a script file compile.sh, and two makefiles counter.make and remail.make.
In compile.sh
make -f counter.make
make -f remail.make
In counter.make
SOURCE_APPLI=../SOURCES_COUNTERFLOW/
SOURCES_f77 = $(SOURCE_APPLI)table.f
TARGET = unst.e
OBJECTS = $(SOURCES_f77:.f=.o)
COMPILE = f77 -f
.f90.o :
$(COMPILE1) -o $*.o -c $*.f90
.f.o :
$(COMPILE) -o $*.o -c $*.f
$(TARGET) : $(OBJECTS)
$(COMPILE) $(OBJECTS) -o $#
del :
$(DELETE) $(OBJECTS)
In remail.make
SOURCE_APPLI= ../SOURCES_COUNTERFLOW/
$(SOURCE_APPLI)grcom.f
TARGET = remail.e
OBJECTS = $(SOURCES_f77:.f=.o)
COMPILE = f90
.f90.o :
$(COMPILE) -o $*.o -c $*.f90
.f.o :
$(COMPILE) -o $*.o -c $*.f
$(TARGET) : $(OBJECTS)
$(COMPILE) $(OBJECTS) -o $#
del :
$(DELETE) $(OBJECTS)
When I run compile.sh, I got an error as shown below
f77: error: unrecognized command line option â-fâ
counter.make:29: recipe for target 'unst.e' failed
make: *** [unst.e] Error 1
make: 'remail.e' is up to date.
So my question is what is the difference with and without using -f option in the f77 command line?
The f77 manual page at https://www.unix.com/man-page/v7/1/f77/ says
-f Use a floating point interpreter
(for PDP11's that lack 11/70-style floating point).
If you are not on a PDP-11, it appears that this option would perhaps not be useful at all in the first place.
Probably still review the local documentation, ideally for the system where this set of Makefiles was once created.
GNU Fortran 77 appears to use this option to specify various language options, but then it would not be useful on its own (it takes arguments like -fdollar-ok to enable something called "dollar ok", for example. See the linked manual for an extensive list of these options and their meaning).
I was given a makefile that looks like this, and told not to change it.
all: clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp clean: rm -f lex.yy.c rm -f parser.tab.*pp rm -f hw2
I am trying to run this makefile in a folder with files named: scanner.lex, parser.ypp, output.hpp and output.cpp
I copied it to a file like this:
all:
clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp
clean:
rm -f lex.yy.c rm -f parser.tab.*pp rm -f hw2
When I run the make command in my terminal I get an error:
clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp
/bin/sh: clean: command not found
make: *** [all] Error 127
Am I doing something wrong? Again, I was given this line and told not to change it.
Thanks a lot.
Line breaks are essential in most computer environments. If you were given a Makefile without the line breaks and you try to cut it randomly you will have difficulties before if finally works. Try this, maybe:
all: clean
flex scanner.lex
bison -d parser.ypp
g++ -std=c++11 -o hw2 *.c *.cpp
clean:
rm -f lex.yy.c
rm -f parser.tab.*pp
rm -f hw2
And use tabs to indent the indented lines, not spaces.
Explanations: all and clean are what is called a target in make parlance. They are the names of the things you want make to do. clean to delete some files, all to do everything else. The
target: prerequisite1 prerequisite2...
recipe1
recipe2
...
template is the basic make template. It means that target depends on prerequisite1, prerequisite2 and that in order to build it make shall pass recipe1 to the shell for execution, then recipe2...
Note that this Makefile is poorly written. As all and clean are not real file names they should be declared as phony, such that, if a file with that name exists make does the job anyway. As is, it wouldn't. Give it a try:
$ make all
$ touch clean
$ make clean
make: 'clean' is up to date.
See? Because a file named clean exists you cannot make clean anymore, make considers that there is nothing to do for clean. Add this at the beginning of your Makefile:
.PHONY: all clean
A second issue is that make works by comparing last modification times of targets and prerequisites to decide if targets must be rebuilt or not. With your Makefile make will always recompile everything, even if the inputs did not change and the outputs are up-to-date. This is a waste. A better (but untested) Makefile would be something like:
.PHONY: all clean
CFILES := $(filter-out lex.yy.c,$(wildcard *.c))
CPPFILES := $(filter-out parser.tab.cpp,$(wildcard *.cpp))
all: hw2
hw2: lex.yy.c parser.tab.cpp $(CFILES) $(CPPFILES)
g++ -std=c++11 -o $# $^
lex.yy.c: scanner.lex
flex $<
parser.tab.cpp: parser.ypp
bison -d $<
clean:
rm -f lex.yy.c
rm -f parser.tab.*pp
rm -f hw2
Understanding it and why it is better is left as an exercise.
Basically I am trying to make a simple make file that creates a lexer.o and then a driver.o file combining them into an executable.
Code below shows what has been tried. Running it in Windows powershell using GNU make.
.PRECIOUS = driver.cpp lexer.h lexer.cpp
lexer.o: lexer.cpp lexer.h
g++ -o $# -c lexer.cpp
driver.o: driver.cpp lexer.h
g++ -o $# -c driver.cpp
lex.exe: lexer.o driver.o
g++ -o $# $^
clean:
$(RM) *.o lex.exe
Here is what output is given. I was expecting it to create the lexer.o file, but instead it cannot "find" the file it was supposed to create.
g++ -o lexer.o -c lexer.cpp
process_begin: CreateProcess(NULL, g++ -o lexer.o -c lexer.cpp, ...)
failed.
make (e=2): The system cannot find the file specified.
make: *** [lexer.o] Error 2
It ended up just being a G++ installation problem. I swapped over to Ubuntu and reinstalled everything and it worked fine.
This question already has answers here:
Make error: missing separator
(14 answers)
Closed 3 years ago.
For the following make file copied below, I am getting the missing separator error. Nothing seems to be wrong with the tabspace.
OBJS = driver.o snapshot.o
SHOBJS = malloc.o mymemory.o
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
Snapshot: $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o Snapshot
driver.o: snapshot.h driver.cpp
$(CC) $(CFLAGS) driver.cpp
snapshot.o: mymemory.h snapshot.h snapshot.cpp
$(CC) $(CFLAGS) snapshot.cpp
libmymemory.so: $(SHOBJS)
gcc -shared -o libmymemory.so malloc.o mymemory.o
malloc.o: malloc.c
gcc -fPIC -g -c -Wall malloc.c
mymemory.o: mymemory.cpp
gcc -fPIC -g -c -Wall mymemory.cpp
clean:
\rm *.o *~ Snapshot
Line 18 is gcc -fPIC -g -c -Wall mymemory.cpp. Make is expecting a separator, typically :. It's not detecting this line as a command. You mistyped the intendation: you have spaces where you should have a tab.
Good editors highlight makefile lines that begin with spaces but look like they should begin with a tab instead.
I have seen this error message when a file used spaces instead of tab character(s) at the beginning of a line in the makefile.
This mostly happens if you copy paste the code from internet. Remove all the spaces from the indented lines by using the delete key. And then press the tab key, only once per line.
Save it and try running the file again. It should work now. This worked for me.
I don't know if it's accurate or an artifact of pasting the code online, but the indentation for the last two commands in the file looks like it's smaller than the commands above it. Double-check your spacing carefully.
While running my make file which is as follows,
../bin/output : ../lib/libfun.a ../obj/main.o
gcc ../main.o -L ../lib/ -lfun -o $#
../lib/libfun.a : ../obj/file_write.o ../obj/error.o
ar -rc $# $^
../obj/main.o : ../src/main.c
gcc -c $^ -o $# -I ../include
../obj/file_write.o : ../src/file_write.c
gcc -c $^ -o $# -I ../include
../obj/error.o : ../src/error.c
gcc -c $^ -o $# -I ../include
I am getting error like
make: Warning: File `makefile' has modification time 2.2e+03 s in the future
ar -rc ../lib/libfun.a ../obj/file_write.o ../obj/error.o
ar: ../lib/libfun.a: No such file or directory
make: *** [../lib/libfun.a] Error 1
and sometimes
"* missing separator (did you mean TAB instead of 8 spaces?). Stop"
Why is this happening? I gave correct Target,Pre-Requests and Command values whichever needed. Whats wrong in this?
For the first error, make sure the ../lib directory exists before trying to create a library in it. ar will return that error if the path doesn't exist.
For the second make syntax is strict: the commands after a target must be indented with a tab, not spaces.
target: deps
command
# ^ this here needs to be a tab character, not spaces