我有一个代码生成器(生成C ++的Python脚本),它接受一个包含简单位图字体字形的文本文件,并使用字体的参数和数据生成.h和.cc文件。发电机的实际工作正常;它正在向GNU make
解释这种安排给我带来麻烦。
目录结构如下:
project_dir/
app/
Foo/
Makefile
... application source files ...
gcc/
... all object files ...
lib/
LCD/
Font_ProFont_10.txt
... library source files ...
我的制作规则如下:
Font_%.cc Font_%.h: Font_%.txt $(GENFONT)
@if [ 'x${VERBOSE}' = x ]; then echo "FONT(F) $<"; else \
echo $(GENFONT) $<; fi
@$(GENFONT) $<
从一个干净的构建开始(这很重要),make
将会对源进行处理,直到它遇到一个字体,该字体会死掉:
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
重新运行make
会对此问题进行粉饰,因为make
会找到原始文件的源文件:
CXX ../../lib/LCD/Font_ProFont_10.cc
由于构建开始时Font_ProFont_10.cc
不存在,make
会认为它将生成到当前目录(project_dir / app / Foo /)而不是库目录(这是除非我遗漏了什么,否则规则会说明了。
我的关键问题是:如何更改制作规则,以免制作混淆?
我原则上不希望将生成的文件放在分布式文件中,但我也希望make
能够在一组干净的文件上成功完成。
我不希望通过递归来执行此操作,因为需要将应用程序级别的配置传递给库。所以我将所有对象生成到应用程序目录中的目录中。
编辑:更改为以下内容:
VPATH += ../../lib/LCD
LCD = ../../lib/LCD
# ...
$(LCD)/Font_%.cc $(LCD)/Font_%.h: Font_%.txt $(GENFONT)
# ...
无法解决问题:
make: *** No rule to make target `gcc/Font_Atmel_16.o',
needed by `gcc/RTOSDemo.axf'. Stop.
此处make
以某种方式不知道您可以使用gcc/Font_Atmel_16.o
规则从../../lib/LCD/Font_Atmel_16.cc
$(OBJDIR)/%.o: %.c
生成../../lib/LCD
,因为$(VPATH)
位于{{1} }}。它甚至没有运行$(LCD)/Font_%.cc
规则。
答案 0 :(得分:3)
麻烦的是,您的Font_%.cc
规则并没有真正构建它声称构建的内容。如果Make尝试使用它来构建Font_ProFont_10.cc
,它希望获得Font_ProFont_10.cc
(并相应地计划),但实际得到的是../../lib/LCD/Font_ProFont_10.cc
。如果您希望生成的文件位于lib/LCD/
,那么
../../lib/LCD/Font_%.cc ../../lib/LCD/Font_%.h: Font_%.txt $(GENFONT)
...
将与旧规则完全相同,但Make会知道会发生什么。请确保您的%.o
规则在那里查找它们(以便它知道调用上面的规则)。
修改:
上述解决方案确实有效,但您必须确保%.o
规则在正确的位置查找生成的文件。在这种情况下,VPATH是不够的。如果你想让每个生成的文件进入与其源相同的目录,并且要知道它们在哪里用作先决条件 - 你真的不想使用递归 - 我可以建议两种方法,既可行,又不完美:
如果其中一种方法听起来合理,我可以更详细地说明。