I have the following Makefile in a directory full of .cpp
and .h
files:
CFLAGS=-g -std=c++0x -Wall -pedantic -Wextra -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -O0
CXX=g++
LDFLAGS=-lgmp -lmathsat -lz3
all: Foo.o Bar.o
$(CXX) $(CFLAGS) -o myexe Foo.o Bar.o $(LDFLAGS)
depend: .depend
.depend: $(wildcard *.cpp)
rm -f ./.depend
$(CXX) $(CFLAGS) -MM $^ > ./.depend
include .depend
%.o: %.cpp
$(CXX) $(CFLAGS) $(INCLUDE) $< -c
clean:
rm -f *.o myexe
When I hit make
, it invariably executes the last step (linking) even when none of the .o
files have changed. How can I prevent make
from doing that? I'd expect make
to output Everything up-to-date
or something similar.
I'm on a i686 GNU/Linux machine with GNU Make 3.82 and g++ version 4.8.2.
In makefiles for substantial projects, the rules and lists of files are often more complicated, using multiple symbols to convey commands, options, and lists of files. In this context, “relink” merely means that make will execute the command to link objects into an executable again.
GNU Make is a tool which controls the generation of executables and other non-source files of a program from the program's source files. Make gets its knowledge of how to build your program from a file called the makefile, which lists each of the non-source files and how to compute it from other files.
By default, the goal is the first target in the makefile (not counting targets that start with a period). Therefore, makefiles are usually written so that the first target is for compiling the entire program or programs they describe.
You create a special file called a makefile (the default name is GNUmakefile ) which contains instructions on how to create all object, library and executable files and then pass this file to gmake along with a request to build the program.
Make relinks your project because it tries to build all
. The rule for all
does not create any file named all
. Instead it produces myexe
. Next time you run make, it will see that there's no all
, but there's a rule to build one, so it dutifully executes that rule which happens to link myexe
every time you run make.
In order to fix your problem you need to change your makefile to look roughly like this:
all: myexe
echo Build done
myexe: <myexe dependencies go here>
$(CXX) $(CFLAGS) -o myexe $(wildcard *.o) $(LDFLAGS)
Make always tries to build the top rule. For you, this is all
. Since your all
rule doesn't actually make an all
file it will always be run.
Your probably want your all
rule to be a myexe
rule and, if you want an explicit all
rule, have a dependency only rule: all: myexe
.
(With GNU Make, you might want to explicitly declare those targets which aren't supposed to generate a real file with a .PHONY
rule. e.g. .PHONY: all depend clean
.)
make
is a rule-based expert system.
You give it a heap of rules and a target (default target is the first one listed), and then it builds a complete dependency tree.
All parts are rebuilt iff they are non-existent resp. older than their dependencies, recursively.
The rule you are stumbling over is this: Because the target all
does not create an output file all
, make invokes the non-existent-or-outdated rule.
You can correct this by making the target all
not do any work but instead just depend on the output file. Marking it .PHONY
is also a good idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With