Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does GNU make always re-link my project?

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.

like image 683
Hinton Avatar asked Apr 29 '14 17:04

Hinton


People also ask

Why does makefile keep relinking?

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.

What does GNU make do?

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.

What is default in makefile?

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.

What is a GNUmakefile?

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.


3 Answers

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)
like image 179
ArtemB Avatar answered Oct 06 '22 01:10

ArtemB


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.)

like image 21
CB Bailey Avatar answered Oct 05 '22 23:10

CB Bailey


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.

like image 45
Deduplicator Avatar answered Oct 06 '22 01:10

Deduplicator