Jet Blue
Jet Blue

Reputation: 5281

Make - Apply rule to a dynamically created file

I have the following rule:

%.o: $(SRCDIR)%.S
    $(CC) $(ASFLAGS) -c $< -o $(BINDIR)$@

It works great, except for the case where one of the source files vectors.S is created dynamically. The file does not come into existence until the following rule is ran:

vectors.S: $(SRCDIR)vectors.pl
    $(SRCDIR)vectors.pl > $(SRCDIR)vectors.S

The rule creates the file src/vectors.S. Why doesn't the previous rule get applied to this new file? (The default implicit rule is used instead). What can I do to make it apply?

For reference, here is a sample of the Makefile output:

gcc -m32 -gdwarf-2 -Wa,-divide -c src/swtch.S -o bin/swtch.o
gcc -m32 -gdwarf-2 -Wa,-divide -c src/trapasm.S -o bin/trapasm.o
src/vectors.pl > src/vectors.S
gcc -m32 -gdwarf-2 -Wa,-divide   -c -o vectors.o vectors.S
gcc: error: vectors.S: No such file or directory
gcc: fatal error: no input files
compilation terminated.
make: *** [vectors.o] Error 4


-- Update --

I managed to get it to work by specifying an explicit rule for vectors.o:

vectors.o: vectors.S
    $(CC) $(ASFLAGS) -c $(SRCDIR)$< -o $(BINDIR)$@

I am still curious why the custom %.o: $(SRCDIR)%.S rule is ignored and the implicit one chosen... And what (if any) is the standard way to resolve this.

Upvotes: 0

Views: 105

Answers (1)

MadScientist
MadScientist

Reputation: 100836

It's ignored because it's not building the right file.

The file vector.S is not the same file as src/vector.S. You have asked make to build src/vector.S by listing it as a prerequisite, and you've defined a rule that tells make how to build vector.S, but that rule is useless to make because that's not the file you want to build.

The Second Rule of Makefiles says, a recipe should always update the target you told make it would, which is $@. If your recipe updates something other than just exactly $@, then it's wrong.

So, you want your rules to be this:

$(BINDIR)%.o: $(SRCDIR)%.S
        $(CC) $(ASFLAGS) -c $< -o $@

$(SRCDIR)vectors.S: $(SRCDIR)vectors.pl
        $(SRCDIR)vectors.pl > $@

Upvotes: 2

Related Questions