GNU make confused by code generator
I have a code generator (Python script generating C++) that takes a text file containing the glyphs of a simple bitmap font and generates .h and .cc files with the font's parameters and data. The actuals of the generator are working fine; it's explaining this arrangement to GNU make
that's giving me trouble.
The directory structure looks like:
project_dir/
app/
Foo/
Makefile
... application source files ...
gcc/
... all object files ...
lib/
LCD/
Font_ProFont_10.txt
... library source files ...
My make rule looks like:
Font_%.cc Font_%.h: Font_%.txt $(GENFONT)
@if [ 'x${VERBOSE}' = x ]; then echo "FONT(F) $<"; else \
echo $(GENFONT) $<; fi
@$(GENFONT) $<
Starting from a clean build (this is important), make
will chug along fine on the sources until it hits a font, which dies with:
FONT(F) ../../lib/LCD/Font_ProFont_10.txt
CXX Font_ProFont_10.cc
arm-eabi-g++: Font_ProFont_10.cc: No such file or directory
arm-eabi-g++: no input files
make: *** [gcc/Font_ProFont_10.o] Error 1
Rerunning make
will whitewash over this problem, since make
will find the source file where it really is:
CXX ../../lib/LCD/Font_ProFont_10.cc
Since Font_ProFont_10.cc
didn't exist when the build started, make
gets the idea it would be generated into the current directory (project_dir/app/Foo/) instead of the library directory (which is where the rules says it will be, unless I'm missing something).
My key question is: How do I change the make rule so make doesn't get confused?
I don't want to put the generated files in with the distributed files, on principle, but I also would like make
to complete successfully on a clean set of files.
I don't开发者_运维问答 want to do this with recursion, because there are application-level configurations that need to be passed down to the libraries. So I'm generating all the objects into a directory in the application's directory.
EDIT: Changing to the following:
VPATH += ../../lib/LCD
LCD = ../../lib/LCD
# ...
$(LCD)/Font_%.cc $(LCD)/Font_%.h: Font_%.txt $(GENFONT)
# ...
does not solve the problem:
make: *** No rule to make target `gcc/Font_Atmel_16.o',
needed by `gcc/RTOSDemo.axf'. Stop.
Here, make
somehow doesn't know that you can make gcc/Font_Atmel_16.o
from ../../lib/LCD/Font_Atmel_16.cc
using the $(OBJDIR)/%.o: %.c
rule, since ../../lib/LCD
is in $(VPATH)
. It doesn't even run the $(LCD)/Font_%.cc
rule.
The trouble is that your Font_%.cc
rule doesn't really build what it claims to build. If Make tries to use it to build Font_ProFont_10.cc
, it expects to get Font_ProFont_10.cc
(and plans accordingly), but what it actually gets is ../../lib/LCD/Font_ProFont_10.cc
. If lib/LCD/
is where you want the generated files to go, then this
../../lib/LCD/Font_%.cc ../../lib/LCD/Font_%.h: Font_%.txt $(GENFONT)
...
will do exactly the same thing as your old rule, but Make will know what to expect. Just be sure your %.o
rule looks for them there (so that it will know to invoke the rule above).
EDIT:
The above solution does work, but you must make sure that the %.o
rules looks for the generated files in the right place. VPATH will not suffice in this case. If you want each generated file to go into the same directory as its source, and Make to know where they are for use as prerequisites -- and you really don't want to use recursion -- I can suggest two alternatives, both workable, neither perfect:
- When you create Font_foo.cc somewhere, create a symbolic link to it in app/Foo/, and delete the link when Make is finished. (There's no need to retain the links for a future invocation of Make, since VPATH will find the files then.)
- Create tailored rules like the one above, one for each directory containing a %.txt file. This can be done automatically, by Make, with some careful use of "eval" and "call".
If one of these approaches sounds reasonable, I can lay it out in more detail.
精彩评论