Reputation: 5281
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
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