functionmakefileprerequisites

How to use make file functions with $@ to generate prerequisites?


I want to extract the name of a prerequisite from the target.

TARS= zabc zbcd zcde zdef
# and I want abc.o to be a prerequisite for zabc
$(TARS): $(patsubst z%,%.o,$@) z.c
    gcc -c -o $@ $^ 

However, this is not working. Consider the following:

TARS= zabc zbcd zcde zdef
# and I want abc.o to be a prerequisite for zabc
$(TARS): $(patsubst z%,%.o,zabc) z.c
    gcc -c -o $@ $^ 

Ignore the TARS in above code but this works for make zabc. So I want to know how to use $@ as an argument in the function for getting the prerequisite name.


Solution

  • The short answer is, you can't. Automatic variables, as made clear in the documentation, are only set inside the recipe of a rule, not when expanding the prerequisites. There are advanced features you can take advantage of to work around this, but they are intended only to be used in very complicated situations which this isn't, really.

    What you want to do is exactly what pattern rules were created to support:

    all: $(TARS)
    
    z%: z%.o z.c
            gcc -c -o $@ $^
    

    That's all you need.

    ETA

    GNU make doesn't provide any completion capabilities, so you'll need to figure out where that completion is done and how it works, to know what you need to have in your makefile to have it work. If it only completes on explicit targets, you can either just make them like this:

    all: $(TARS)
    
    $(TARS):
    
    z%: z%.o z.c
            gcc -c -o $@ $^
    

    Or you can use static pattern rules instead:

    all: $(TARS)
    
    $(TARS): z%: z%.o z.c
            gcc -c -o $@ $^
    

    I didn't understand the last sentence in your comment below.