GNU让代码生成器感到困惑

时间:2011-06-20 03:28:09

标签: code-generation makefile

我有一个代码生成器(生成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规则。

1 个答案:

答案 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是不够的。如果你想让每个生成的文件进入与其源相同的目录,并且要知道它们在哪里用作先决条件 - 你真的不想使用递归 - 我可以建议两种方法,既可行,又不完美:

  1. 在某处创建Font_foo.cc时,在app / Foo /中创建一个指向它的符号链接,并在Make完成时删除该链接。 (由于VPATH 找到文件,因此无需为将来调用Make保留链接。)
  2. 创建如上所示的定制规则,每个目录包含一个%.txt文件。 这可以通过Make,自动完成,并小心使用“eval”和“call”。

如果其中一种方法听起来合理,我可以更详细地说明。