James
James

Reputation: 9278

Different 'make' behaviour

I'm trying to write a makefile for a kernel module and cannot get it to work. Running the following has this output

$ make
make: Nothing to be done for 'all'.

but running the make command directly on the terminal results in

$ make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make: Entering directory '/usr/src/linux-headers-3.5.0-17-generic'
   CC [M] <blah>
   Building modules, stage 2
   <blah>
make: Leaving directory...

The contents of my Makefile are (source file is main.c)

obj-m += main.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

I do delete *.o and *.ko before trying to use the makefile. Changing all to default does nothing either.

Upvotes: 0

Views: 65

Answers (2)

I knew this like the back of my hand several years ago; I’ll do the best I can from memory.  The procedure is that make looks at all the subordinate targets (dependencies) listed after a target it has been asked to make and checks whether they are up to date.  If they are all up to date, and the primary target is not older than any of them, we’re done.  Otherwise, execute the following commands. Thus, for

prog: main.o subr.o
    $(CC) main.o subr.o –o $@

If subr.c has been edited, we need to recompile it to bring subr.o up to date.  Then, since subr.o is newer than prog, we run the commands to relink prog.

The devil lives in the boundary conditions.  Your all pseudo-target has no dependencies.  Therefore, none of the dependencies is newer than the all target.  Therefore, we don’t do the commnd(s) below the all.

ISTR that I “fixed” this by saying

all: always
       command(s)…

where always is not a keyword, but is just a user-chosen pseudo-filename (like all, clean, new, etc.), chosen to remind you that it is there to force the command(s) under the all to be run always. Then put

always:
                               <– blank line (no commands)

somewhere else in the Makefile.


That’s peculiar: I thought I just saw an answer from Philipp Claßen here, but then it disappeared.  Anyway, he said

Your target has no dependents, so make assumes that nothing needs to be done.  You have to declare your target as .PHONY.

Here is a link to the documentation.

So now you know the “right” (non-kludge) way to handle the problem.

Upvotes: 0

Jonathan Callen
Jonathan Callen

Reputation: 11591

The most likely issue is that you didn't use a real tab character to begin the line reading make -C ..., but instead used multiple spaces. make requires that commands all begin with a tab character.

Upvotes: 3

Related Questions