(Gnu) make:具有特殊编译器开关的多个目标

(Gnu) make: multiple targets with special compiler switches

我在使联编文件工作时遇到问题。我有几个编译 XML 模式的解析器如下:

$(srcdir)/schema_1_parser.cpp: \
                 $(srcdir)/schema_1_parser.l \
                 $(srcdir)/schema_1_parser.tab.cpp
    $(LEX) -Pschema_1 -o$(srcdir)/schema_1_parser.cpp \
                        $(srcdir)/schema_1_parser.l

$(srcdir)/schema_1_parser.tab.cpp $(srcdir)/schema_1_parser.tab.hpp: \
                $(srcdir)/schema_1_parser.y
    $(YACC) -ldv -p schema_1 -o $(srcdir)/schema_1_parser.tab.cpp \
                                $(srcdir)/schema_1_parser.y

有多个这样的规则对,使用 schema_2、schema_3 等。这些名称确实遵循我想尽可能利用的模式。 (目前我只有特殊规则。)

由于 makefile 错误 "Do not know how to make schema_1_parser.tab.hpp",我添加了第二个目标 $(srcdir)/schema_1_parser.tab.hpp,即使 header 与 .tab.cpp 文件一起自动生成。

现在 bison 解析器被调用了两次。我仔细阅读了这篇文章,并相信这是具有多个目标的特殊规则的预期行为,我应该改用模式规则。但是,我有点不确定 flex 的命令行选项 -Pschema_1 和 bison 的 -p schema_1 是什么。我也可以使用该模式来处理这些问题吗? (我的经历是负面的,但我可能还漏掉了其他东西。)

嗯,我们不能给你一个完整的答案,因为你没有给我们展示任何其他规则,所以我们不知道它们之间有哪些模式是共同的。但是,是的,当然有多种方法可以处理您描述的情况。如果你的解析器都匹配模式 %_parser.y%_parser.l,你可以这样写规则:

$(srcdir)/%_parser.cpp: \
             $(srcdir)/%_parser.l \
             $(srcdir)/%_parser.tab.cpp
        $(LEX) -P$* -o$@ $<

$(srcdir)/%_parser.tab.cpp $(srcdir)/%_parser.tab.hpp: \
            $(srcdir)/%_parser.y
        $(YACC) -ldv -p $* -o $(srcdir)/$*_parser.tab.cpp $<

因为 $* 扩展到模式的主干。

如果这不起作用,您可以使用递归变量:

NAME_schema_1_parser = schema_1

$(srcdir)/%.cpp: $(srcdir)/%.l $(srcdir)/%.tab.cpp
        $(LEX) -P$(NAME_$*) -o$@ $<

$(srcdir)/%.tab.cpp $(srcdir)/%.tab.hpp: $(srcdir)/%.y
        $(YACC) -ldv -p $(NAME_$*) -o $(srcdir)/$*_parser.tab.cpp $<

您还可以使用特定于目标或特定于模式的变量。