Help understanding makefile: static pattern rules

Hi all,
I'm reading the GNU Make book I cannot understand the following syntax from the book.

objects = foo.o bar.o

all : $(objects)
$(objects) : %.o : %.c
	$(CC) -c $(CFLAGS) $< -o  $@

If I run:

make

, I get the output:

cc  -c foo.c
cc  -o foo   foo.o

I think I understand that line $(objects) : %.o : %.c produces line cc -c foo.c when the target is foo.o. This is because
$(objects) : %.o : %.c is converted into foo.o : foo.c right?

But I cannot see the process that produces the second line: cc -o foo foo.o.

any help would be much appreciated!

hello?

Hi.

I think you are reporting the use of a static rule, followed by an implicit rule. If you run make on the Makefile as described at Static Usage - GNU `make' , then I think you will generate the object files foo.o and bar.o. If you then run make foo the implicit rule will be invoked, and you will get the executable foo, as noted here:

#!/usr/bin/env bash

# @(#) s1	Demonstrate static GNU make rule.
# See:
# http://www.gnu.org/software/make/manual/html_node/Static-Usage.html#Static-Usage

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C make

FILE=${1-Makefile}

pl " Input data file $FILE:"
head $FILE

rm -f *.o foo bar
pl " Results for running command \"make\":"
make

pl " Results for running command \"make foo\":"
make foo

rm -f *.o foo bar
pl " Results for running command \"make foo\", no extant .o files:"
make foo

exit 0

producing:

$ ./s1 

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0.8 (lenny) 
bash GNU bash 3.2.39
make GNU Make 3.81

-----
 Input data file Makefile:
objects = foo.o bar.o

all: $(objects)

$(objects): %.o: %.c
	$(CC) -c $(CFLAGS) $< -o $@


-----
 Results for running command "make":
cc -c  foo.c -o foo.o
cc -c  bar.c -o bar.o

-----
 Results for running command "make foo":
cc   foo.o   -o foo

-----
 Results for running command "make foo", no extant .o files:
cc -c  foo.c -o foo.o
cc   foo.o   -o foo

Best wishes ... cheers, drl

1 Like

thanks for the reply.
I think what I was confused because I didn't know I was executing an implicit rule.