如果你想这样做,你必须把它写成一个静态规则:
$(OBJDIR)/special_file.$(OE): special_file.c
$(ECHO) "Compiling file $< => $@"
$(CC) $(CFLAGS) $(CFLAGS_SPECIAL) $(DEFINES) $(INCLUDE) $< -o $@
然而,更简单、更灵活的是使用递归变量命名。做这样的事情:
special_file_FLAGS = $(CFLAGS_SPECIAL)
$(OBJDIR)/%.$(OE): %.c
$(ECHO) "Compiling file $< => $@"
$(CC) $(CFLAGS) $($*_FLAGS) $(DEFINES) $(INCLUDE) $< -o $@
自动变量$*
扩展到词干(匹配的部分%
)。现在,当您构建除 之外的任何内容时special_file.c
,例如other_file.c
, make 将扩展$(other_file_FLAGS)
为空。当您构建时special_file.c
,make 会扩展$(special_file_FLAGS)
。
顺便说一句,您应该(几乎)永远不要将目录列为目标的先决条件。搜索其他答案以找出原因以及确保创建目标目录的正确方法。
预计到达时间:
特定于目标的变量绝对是一个很酷的功能。不过,我倾向于不使用它们。为什么?因为我更喜欢将我的数据与我的规则分开。
如果您使用特定于目标的变量,则将规则语法(目标)与数据语法(变量分配)混合在一起。使用递归变量名方法,我将规则语法和数据分配分开。如果我决定需要更改模式规则以更改目标名称怎么办?使用特定于目标的变量,我必须浏览所有文件并更改目标名称。使用递归变量命名,我只需更改模式规则,它就可以工作。
在我的构建环境中,我通常有只包含数据(变量分配)的生成文件,以及一个include
声明所有规则的通用生成文件。避免在我的通用数据驱动的 makefile 中泄漏目标格式语法的需要,从我超级神奇的通用规则定义中转义,使我无法对特定于目标的变量做很多事情。