How do I write a clean Makefile?
The Makefiles that I have dealt with, for the most 开发者_运维技巧part, are complex and hide a lot of relationships. I have never written one myself, and was wondering if anybody had some tips on writing a Makefile that is easy to read and reusable?
I usually use something like this, in this example the source files are main.c file2.c file3.c file4.c
, to add more you simply add to the OBJECTS
var.
They all depend on Makefile
, so for a full recompile a simple touch Makefile
would suffice.
PROGNAME = hi2u
LIBS = -ljpeg -ldirectfb -pthread
INCLUDES = -I/usr/local/include/directfb
LDFLAGS = -Llibs/
OBJECTS = main.o file2.o \
file3.o file4.o
CFLAGS = -W -Wall -O2 -ggdb
all: $(PROGNAME)
$(PROGNAME): $(OBJECTS)
gcc -o $(PROGNAME) $(OBJECTS) $(LIBS) $(INCLUDES) $(LDFLAGS)
$(OBJECTS): Makefile
.c.o:
gcc -c $(CFLAGS) $(INCLUDES) -o $@ $<
clean:
rm *.o $(PROGNAME)
In all honesty, the complexity of a makefile relies on the complexity of the program. If you have a lot of folders and files and different compiling processes, you're makefile is probably going to be a little long and complicated. If you have a helloworld
program, there's no reason for it to be longer than a few lines.
Here's some tips on makefiles : http://mrbook.org/tutorials/make/
Here's a very reusable makefile that's not too complicated:
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
A tutorial that I've found helpful for understanding Makefiles is http://www.jfranken.de/homepages/johannes/vortraege/make_inhalt.en.html
Another tip is to make generous use of regular expressions for source files and dependencies
For me, the read that got me thinking about these issues, is the classic "Recursive Make Considered Harmful".
When I get the chance to create makefiles from scratch, I try to use implicit rules as much as possible, and also define rules in a separate file, which I can include from the "real" makefile.
The challenges with using make can be divided in two major groups:
issues inherent with make itself, its rich semantics and syntax and somewhat archaic appearance
issues which are not makes "fault", but come from when make is used to call another make process. Suddenly we have another task at hand - communicating between two or more make processes. It is very easy to get lost with environment variables or other ways to pass information. Platform differences which make itself is designed to hide, may become visible.
精彩评论