How to add an all rule to this Makefile? - makefile

I want to just type 'make all' and have the following Makefile do everything it's supposed to do:
LEX = lex
YACC = yacc
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu

What all is it supposed to do? If you just want it to build calcu, all you have to do is type make and it will make it along with everything it depends on, because it is the first rule in the file.
If you still want to make an all rule, it can be done like this. I recommend putting this above all other rules, so that you can just type make instead of make all.
all: calcu

Related

Make did not work after I changed my file

These are my files:
add.c add.h main.c makefile
This is makefile:
main:main.o add.o
gcc -o main main.o add.o
main.o:$(#:%.o=%.c)
gcc -o main.o -c main.c
add.o:$(#:%.o=%.c) $(#:%.o=%.h)
gcc -o add.o -c add.c
.PHONY:clean
clean:
rm *.o -rf
rm main -rf
Then after I change the main.c and make.
But make told me this:
make: `main' is up to date.
If I change my makefile:
main:main.o add.o
gcc -o main main.o add.o
main.o:main.c
gcc -o main.o -c main.c
add.o:$(#:%.o=%.c) $(#:%.o=%.h)
gcc -o add.o -c add.c
.PHONY:clean
clean:
rm *.o -rf
rm main -rf
Then after I change the main.c and make.
It can work.
I donot know the reason.
The dependencies in
main.o:$(#:%.o=%.c)
add.o:$(#:%.o=%.c) $(#:%.o=%.h)
are not valid make syntax.
Replace these two rules with one pattern (generic) rule:
%.o : %.c
gcc -c -o $# ${CPPFLAGS} ${CFLAGS} $<
The above rule is actually very similar to the built-in rule for compiling .o files from .c:
Compiling C programs
n.o is made automatically from n.c with a recipe of the form $(CC) $(CPPFLAGS) $(CFLAGS) -c.
In other words, you can remove your original rules for main.o and add.o and it should build correctly.

Make file not working?

Solution found. See below:
I'm trying to get my makefile to compile three c programs into one executable, but I get the following error:
cachesim.o: could not read symbols: File in wrong format
Yes, I'm using make clean every time I use it. The make file is as follow
CC = gcc
CFLAGS = -Wall -m32 -O -g
all: cachesim cache trace_file_parser
gcc -o cachesim cachesim.o cache.o trace_file_parser.o
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
cache: cache.c
$(CC) -c -o cache.o cache.c $(CFLAGS)
trace_file_parser: trace_file_parser.c
$(CC) -c -o trace_file_parser.o trace_file_parser.c $(CFLAGS)
clean:
rm -f *.o
I cannot figure out why this is....
I'm using make clean every time.
Attempting to compile:
[katiea#mumble-15] (34)$ make clean
rm -f *.o
[katiea#mumble-15] (35)$ ls
cache.c cache.h cachesim.c~ gcc_trace Makefile~ trace_file_parser.c
cache.c~ cachesim.c cache_structs.h Makefile strgen_trace trace_file_parser.h
[katiea#mumble-15] (36)$ make
gcc -c -o cachesim.o cachesim.c -Wall -m32 -O -g
gcc -c -o cache.o cache.c -Wall -m32 -O -g
gcc -c -o trace_file_parser.o trace_file_parser.c -Wall -m32 -O -g
gcc -o cachesim cachesim.o cache.o trace_file_parser.o
cachesim.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
make: *** [all] Error 1
SOLUTION
CC = gcc
CFLAGS = -Wall -m32 -O -g
all: cachesim.c cache.c trace_file_parser.c
$(CC) -o cachesim cachesim.c cache.c trace_file_parser.c $(CFLAGS)
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
cache: cache.c
$(CC) -c -o cache.o cache.c $(CFLAGS)
trace_file_parser: trace_file_parser.c
$(CC) -c -o trace_file_parser.o trace_file_parser.c $(CFLAGS)
clean:
rm -f *.o
Please read an intro to makefiles. This looks like homework to me.
One of the most basic tenets of makefiles is that the target should be the actual file you're building. These rules are all bogus:
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
(etc.) because the target is cachesim but the recipe (command line) builds the file cachesim.o.
Your makefile can be written as easily as this (taking advantage of make's built-in rules):
CC = gcc
CFLAGS = -Wall -m32 -O -g
LDFLAGS = -m32 -O -g
cachesim: cachesim.o cache.o trace_file_parser.o
clean:
rm -f *.o
That's all you need.
As for your error, it seems to me that the file cachesim.o must be in some bizarre format, maybe from back before you had the makefile set up properly.
If you run make clean then make again, do you get the same error? If so please show the compile and link lines.
ETA: use the -m32 flag on the link line as well as the compile line, if you want to create a 32bit program.

make recompiles everything every time, why?

Here's my makefile:
all: lex yacc compile
lex: sql.l
lex -i sql.l
yacc: sql.y
yacc -d -v sql.y
compile: y.tab.c lex.yy.c
$(CC) -o sql_parser y.tab.c lex.yy.c -ly -ll
test: all
#./parsesql.sh selecttest.sql
#./parsesql.sh insertintotest.sql
#./parsesql.sh deletefromtest.sql
#./parsesql.sh createtest.sql
cleanup:
rm test.tab.cacc
rm y.output
Running make will always trigger a full recompile, even if nothing has changed:
parsesql> make
lex -i sql.l
yacc -d -v sql.y
cc -o sql_parser y.tab.c lex.yy.c -ly -ll
parsesql> make
lex -i sql.l
yacc -d -v sql.y
cc -o sql_parser y.tab.c lex.yy.c -ly -ll
parsesql> make
lex -i sql.l
yacc -d -v sql.y
cc -o sql_parser y.tab.c lex.yy.c -ly -ll
None of the files have changed, so why is it doing this? The lex and yacc commands should only trigger if sql.l or sql.y respectively have changed, no?
Your targets are all not real files. Make them the names of the actual files you're generating so that make can find them and check timestamps.
Example:
all: sql_parser
lex.yy.c: sql.l
lex -i sql.l
y.tab.c: sql.y
yacc -d -v sql.y
sql_parser: y.tab.c lex.yy.c
$(CC) -o sql_parser y.tab.c lex.yy.c -ly -ll
test: all
#./parsesql.sh selecttest.sql
#./parsesql.sh insertintotest.sql
#./parsesql.sh deletefromtest.sql
#./parsesql.sh createtest.sql
cleanup:
rm test.tab.cacc
rm y.output
You can add .PHONY: all test cleanup to indicate to make that those targets are not intended to be real files.

Configuring my makefile for gdb

I've used gdb before, but never with a makefile and only configuring in very simple ways. g++ -g -o file.cpp, etc. I've tried everything, and I cannot get it to recognize debugging objects. I want to debug all of my executable compile.
I'm running g++ and Ubuntu.
compile: scanner.o parser.o listing.o locals.o globals.o
g++ -o compile scanner.o parser.o listing.o locals.o globals.o
scanner.o: scanner.c locals.h globals.h listing.h tokens.h
g++ -c scanner.c
scanner.c: scanner.l
flex scanner.l
mv lex.yy.c scanner.c
parser.o: parser.c listing.h locals.h globals.h
g++ -c parser.c
parser.c tokens.h: parser.y
bison -d -v parser.y
mv parser.tab.c parser.c
mv parser.tab.h tokens.h
listing.o: listing.cc
g++ -c listing.cc
locals.o: locals.cc
g++ -c locals.cc
globals.o: globals.cc
g++ -c globals.cc
Do not override the default rules. Just assign CC and CFLAGS as necessary. In other words, your Makefile should be (in its entirety):
CC=g++ # Not best practice. See comments below
CFLAGS=-g
compile: scanner.o parser.o listing.o locals.o globals.o
$(CC) $(CFLAGS) -o $# $^
scanner.o: scanner.c locals.h globals.h listing.h tokens.h
parser.o: parser.c listing.h locals.h globals.h
scanner.c: scanner.l
flex scanner.l
mv lex.yy.c scanner.c
parser.c tokens.h: parser.y
bison -d -v parser.y
mv parser.tab.c parser.c
mv parser.tab.h tokens.h
As an aside, you really should use CXX to specify a C++ compiler and name your source code files appropriately. (Use *.c for C, *.cxx for C++) Since you are using non standard names, you need to fool make by using a C++ compiler for CC, which is not really the best practice.

What's wrong with this Makefile?

When I run make all on the following Makefile I get this error:
Makefile:5: *** missing separator. Stop.
What's wrong with it and how do I fix it?
LEX = lex
YACC = yacc
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu
G'day,
You need tabs to indent the lines underneath each target.
LEX = lex
YACC = yacc
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu
BTW General convention is that you should use braces rather than brackets for your macros. Using brackets are a legacy thing left over from substituting an object back in to an archive. So the above is better expressed as:
LEX = lex
YACC = yacc
CC = gcc
calcu: y.tab.o lex.yy.o
${CC} -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
${YACC} -d parser.y
y.tab.o: y.tab.c parser.h
${CC} -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c
${CC} -c lex.yy.c
lex.yy.c: calclexer.l parser.h
${LEX} calclexer.l
clean:
rm *.o
rm *.c
rm calcu
HTH
You need to indent like so. (Note: they changed my tabs into a 4space. Make sure to indent with the tab character.)
LEX = lex
YACC = yacc
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu
The extra blank lines aren't required but the indenting is. You'll also need to make an all rule if you want to make all.
Generally, this sort of error means that you have erroneously used spaces instead of a tab when indenting lines in your Makefile.
Your example appears to have been pasted without indenting, but I can't tell whether your file really looks like that or whether there was a paste error. In the following:
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
the whitespace before $(CC) must be a tab, not spaces:
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
|tab-->|
Whitespace formatting can make answering this difficult. In Make whitespace is critical. Actions must have a tab character in front to be recognised as such by Make. e.g.
calcu: y.tab.o lex.yy.o
\t$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl y.tab.c y.tab.h: parser.y
Note that \t means <tab>. Not 4 spaces, not any spaces, but tab!
Also ensure there is a blank line between dependencies, i.e. if you're going to say file: dependencies then ensure there is a blank line immediately above.

Resources