在gnu make中,静态模式规则中的先决条件可以具有不同的后缀

时间:2009-10-21 21:04:59

标签: makefile gnu-make

我们的make文件使用静态模式规则编译.c源文件,如下所示:

OBJECTS = foo.o bar.o baz.o

$(OBJECTS): %.o: %.c
    $(CC) $< $(C_OPTIONS) -c -o $@

我需要将其中一个.c文件更改为Objective-C .m文件。对两种源类型调用编译器是相同的,所以我想使用相同的规则,只是调整它以使其更灵活。我宁愿不更改OPTIONS变量,因为它也用于链接步骤等。

有没有办法让上面的规则更灵活,以容纳.c和.m文件?

由于

3 个答案:

答案 0 :(得分:7)

我们可以将这个或者行为添加到事物列表中,Make应该能够轻松完成,但事实并非如此。这是一种方法,使用“eval”为每个对象创建一个单独的规则。

define RULE_template
$(1): $(wildcard $(basename $(1)).[cm])
endef

OBJECTS = foo.o bar.o baz.o

$(foreach obj,$(OBJECTS),$(eval $(call RULE_template,$(obj))))

$(OBJECTS):
    $(CC) $< $(C_OPTIONS) -c -o $@ 

请注意,这取决于运行Make之前已存在的源文件(foo.c或foo.m,但不是两者)。如果您在同一步骤中生成这些源,则无效。

这是不那么聪明,更健壮的方法

CPP_OBJECTS = foo.o bar.o
OBJECTIVE_OBJECTS = baz.o
OBJECTS = $(CPP_OBJECTS) $(OBJECTIVE_OBJECTS)

$(CPP_OBJECTS): %.o: %.c 

$(OBJECTIVE_OBJECTS): %.o: %.m 

$(OBJECTS):
    $(CC) $< $(C_OPTIONS) -c -o $@ 

编辑:更正了OBJECTS分配,感谢Jonathan Leffler。

答案 1 :(得分:1)

不仅仅是复制到

$(OBJECTS): %.o: %.m
  $(CC) $< $(C_OPTIONS) -c -o $@

答案 2 :(得分:-1)

对同一编译器的调用只是一个快乐的时刻。通常,您不会使用$(CC)编译objective-c代码。这感觉很奇怪。

但是,由于你采取严厉的方式,我不会发布正确的解决方案,你将目标C目标与C目标分成两个不同的$(OBJECTS)类变量并制定两个规则< strong>(你应该这样做)。太无聊。相反,采取黑客行动!

OBJC_FILES:=$(subst $(wildcard *.m))

real_name = `(test -h $(1) && readlink $(1) ) || echo $(1)`

$(OBJECTS): %.o: %.c
  $(GCC) $< $(C_OPTIONS) -c -o $(call real_name,$@)

$(OBJC_FILES): %.c: %.m
  ln -s $< $@

上帝帮助那些维护它的人!

顺便说一句,如果生成了m文件,这显然不起作用。