A good makefile example

closed account (oG8U7k9E)
I have been teaching myself using what I believe is a pretty good text book. I use the gcc compiler and makefiles. I program this way because I could not find an IDE that I like, but I have this fear that the makefile I use is written poorly. Could some give me a good example of a makefile that they are using, or at least tell me if I am doing something the hard way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#------------------------------------------------------------------------------

SOURCE=octhecdec.cpp octhecdec.h
MYPROGRAM=octhecdec
MYINCLUDES=/home/scale/g++Projects/gLib/

MYLIBRARIES=fltk
CC=g++

#------------------------------------------------------------------------------



all: $(MYPROGRAM)



$(MYPROGRAM): $(SOURCE)

	$(CC) -I$(MYINCLUDES) $(SOURCE) -o$(MYPROGRAM) -l$(MYLIBRARIES)

clean:

	rm -f $(MYPROGRAM)







Your example seems ok.

I dunno if this link helps.
http://www.cplusplus.com/forum/unices/6710/
I'm not a makefile expert, however there are a couple of issues with your makefile.

1) You pass a .h file to the compiler;
2) If any source file changes, you have to rebuild all of them, all the time.
The best place to start is actually with the documentation. Since you are using GNU tools, you might as well stick with GNU Make -- which is superior to other Make tools in many ways.
http://www.gnu.org/software/make/manual/

Your choice of variable names could be improved.
See http://www.gnu.org/software/make/manual/make.html#Implicit-Variables
In particular, your MYLIBRARIES variable is dangerous -- because at some point you'll want to do something like

7 MYLIBRARIES=fltk m

(That is, you'll list more than one library, like FLTK and the C math library.) This will produce a command line terminating in:

-lfltk m

which is erroneous (obviously). Instead, list the libs directly:

7 LDFLAGS = -lfltk -lm

The same thing can be said of MYINCLUDES. When you are done, you should see something like:
20 $(CC) $(CFLAGS) $(SOURCE) -o octhecdec $(LDFLAGS)

You should avoid trying to use a variable in the name of a pattern target -- like $(MYPROGRAM). Since the purpose of the makefile is to compile a specific program, there is no need to put the program's name in a variable.


The typical form for a make file is something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CC      = g++
CFLAGS  = -I/home/scale/g++Projects/gLib/
LDFLAGS = -lfltk

all: octhecdec clean

octhecdec: octhecdec.o
	$(CC) -o $@ $^ $(LDFLAGS)

octhecdec.o: octhecdec.cpp octhecdec.h
	$(CC) -c $(CFLAGS) $<

.PHONY: clean cleanest

clean:
	rm *.o

cleanest: clean
	rm octhecdec

Certain things have special meaning:

$@
name of the target
$^
name of all prerequisites with duplicates removed
$<
name of the first prerequisite
Notice that the first rule after 'all' was to link the program from the compiled object files. The other rule (or rules if more than one object file is involved) simply compile individual object files. And the phony targets 'clean' and 'cleanest' get rid of leftover stuff. Notice how the 'all' target builds the program then gets rid of everything except the final executable? Whether or not this is done is up to you... some hate it, others prefer it. (In general, the point of a makefile is not to do that... so that only the object files that actually need recompiling are recompiled.)


If you all want to see it, I wrote a simple "Make Anything Makefile" for use at Rutgers (using GNU Make and Grep) a while back... It is pretty interesting in how it works. Let me know if you want to see it.

Hope this helps.
closed account (oG8U7k9E)
Duoas,

Thank you for your example and the document reference--it explained everything I wanted to know. It also helped me understand what others are doing when I look at their makefiles.

It really was a great answer thank you, I am always amazed by how well individuals answer questions at this forum.

Topic archived. No new replies allowed.