Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefiles and wildcards

Alright so this is my current setup for a makefile. There are files which are named public01.c, public02.c, etc. I'm trying to make object files for each of them using the public*.o label with a wildcard.

public*.o: public*.c hashtable.h
    $(CC) $(CFLAGS) -c public*.c

public*: public*.o
    $(CC) -o public* public*.o

However, when I try and run the makefile, I get this:

make: *** No rule to make target `public*.c', needed by `public*.o'.  Stop.

I guess it's treating public*.c as a label and not a wildcard as I'd like. I read about $(wildcard pattern...) function and played around with it, but I didn't really understand it or got it to work...

like image 416
id2341677 Avatar asked Jul 05 '11 00:07

id2341677


1 Answers

Short answer: that syntax does not work the way you want it to. The correct way to do what you want in GNU make syntax is to use pattern rules:

public%.o: public%.c hashtable.h
        $(CC) $(CFLAGS) -c $<

public%: public%.o
        $(CC) -o $@ $<

Long answer: This:

public*.o: public*.c hashtable.h

does not mean what you want it to mean. Assuming you have several file public01.c, etc., and no files public01.o, etc., at the start of your build, that syntax is equivalent to this:

public*.o: public01.c public02.c public03.c ... hashtable.h

That is, if public01.o, etc., do not exist, then make will use the literal string public*.o as the filename. If some of the .o files do exist, then that syntax is equivalent to this:

public01.o public02.o ...: public01.c public02.c ... hashtable.h

Seems like what you want right? But that's a common misunderstanding with make, because in fact that line is exactly the same as this:

public01.o: public01.c public02.c ... hashtable.h
public02.o: public01.c public02.c ... hashtable.h

That is -- every .o file has a dependency on every .c file! The correct way to do what you want is to use a pattern rule, as shown above.

like image 112
Eric Melski Avatar answered Sep 24 '22 22:09

Eric Melski