linuxcompilationmakefilegnu

Why doesn't %.o wildcard work in the prerequisites section of a rule?


So I am having some issues understanding how exactly the % wildcard actually works using makefile. I have looked at static pattern rules in the GNU make man but i am still pretty confused and I feel like I have seen them do something similar to what I have below.

EXEC = a.out
CC = gcc
FLAGS = -Wall -c

$(EXEC): %.o
    $(CC) -o $(EXEC) $<
%.o: %.c
    $(CC) $(FLAGS) $<

clean:
    rm -rf *.o

I keep getting an error that says %.o rule not defined. If someone could explain why this is wrong (probably in many ways, guessing the automatic variable part is incorrect as well) that would be appreciated !


Solution

  • I'm not sure what you intend, but I'm pretty sure that this rule:

    $(EXEC): %.o
        $(CC) -o $(EXEC) $<
    

    doesn't do it. In this rule, '%' is not any kind of wildcard, it's just a character. So when Make tries build a.out, it goes looking for a file called %.o, can't find it, doesn't have a rule to build it (since there is no %.c and no way to build that), and gives up.

    Your intention is unclear. If you want the rule to be able to build a.out from a.o (and likewise foo.out from foo.o, and bar.out from bar.o, and so on), write a pattern rule:

    %.out: %.o
        $(CC) -o $@ $<
    
    $(EXEC): # Make will not use a pattern rule as the default, so we need this
    

    (Note the use of $@.) Or (to restrict it to executables in the EXEC list) a static pattern rule:

    $(EXEC): %.out : %.o
        $(CC) -o $@ $<
    

    If, on the other hand, you want Make to use all the source files it can find to build this executable, you must do something like this:

    SOURCES = $(wildcard *.c) # make a list a.c foo.c bar.c
    OBJECTS = $(patsubst %.c, %.o, $(SOURCES)) # translate it into a.o foo.o bar.o
    $(EXEC): $(OBJECTS)
        $(CC) -o $^ $<
    

    Note the use of the wildcard function, and $^ which expands to the list of prerequisites, and also note that "*.o" wouldn't do you much good.