GNU 被代码生成器搞糊涂了

发布于 2024-11-16 08:10:13 字数 1993 浏览 2 评论 0原文

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

我的 make 规则如下所示:

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

重新运行 < code>make 将粉饰这个问题,因为 make 会找到源文件真正所在的位置:

  CXX   ../../lib/LCD/Font_ProFont_10.cc

因为 Font_ProFont_10.cc 在构建时不存在开始, make 认为它将生成到当前目录(project_dir/app/Foo/)而不是库目录(这是规则所说的位置,除非我遗漏了一些东西) 。

我的关键问题是:如何更改 make 规则,以便 make 不会混淆?

原则上,我不想将生成的文件与分布式文件放在一起,但我也希望就像 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) 中。它甚至不运行 $(LCD)/Font_%.cc 规则。

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) 
lt;"; else \
        echo $(GENFONT) 
lt;; fi
    @$(GENFONT) 
lt;

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嗼ふ静 2024-11-23 08:10:13

问题在于您的 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 是不够的。 如果您希望每个生成的文件都进入与其源相同的目录,并且 Make 知道它们作为先决条件使用的位置 - 而您确实不想使用递归——我可以建议两种替代方案,两者都可行,但都不完美:

  1. 当您在某处创建 Font_foo.cc 时,在 app/Foo/ 中创建指向它的符号链接,并在 Make 完成时删除该链接。 (没有必要为将来调用 Make 保留链接,因为 VPATH 将找到这些文件。)
  2. 创建与上面类似的定制规则,每个包含 %.txt 文件的目录都有一个规则。 这可以通过 Make 自动完成,并仔细使用“eval”和“call”。

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

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:

  1. 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.)
  2. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文