在GNU make模式中可以使用目录名称吗?

时间:2018-10-15 06:01:39

标签: gnu-make

我有许多设备驱动程序:每个设备的源代码都在与该设备同名的子目录中:

let items = document.querySelectorAll('.item'),
  removeClassFromItems = function (className) {
    // Iterate all 'items', and remove the `className` from its class.
    for (let i = 0; i < items.length; i++) {
      items[i].classList.remove(className);
    }
  };

// Iterate all items and attach an event handler for click event.
for (let i = 0; i < items.length; i++) {
  items[i].addEventListener('click', function() {
    removeClassFromItems('active');
    this.classList.add('active');
  });
}

如果我为每个这样的设备设置一个单独的GNU make规则,它将起作用:

devices/foo/foo.c
devices/bar/bar.c

如果我设置这样的制作模式,则无法确定如何制作文件。我想问题出在用%作为子目录的名称。

obj/foo.o: devices/foo/foo.c
    $(CC) $(CFLAGS) devices/foo/foo.c -o obj/foo.o

是否可以通过某种方式设置模式来做到这一点?

2 个答案:

答案 0 :(得分:2)

一个模式中只能有一个myfolder/filesystemmatching rules有点涉及。但是,匹配仅发生在目标(左侧),这就是为什么不能使用单个模式在多个目录中搜索正确的先决条件的原因。

作为一种解决方法,您可以为每个目录生成一个模式规则。 GNU make将使用先决条件实际存在的第一个模式规则。您也可以使用VPATH variablevpath directive搜索多个目录。

请注意,所有这些构造都会大大降低GNU make的速度,并使makefile难以编写和调试。最后,最好是在性能和​​维护开销方面进行权衡,以生成仅包含非模式规则的简单makefile。

答案 1 :(得分:1)

另一种方法是在您的makefile中定义以下函数expand

expand = devices/$1/$1.c

然后,启用secondary expansion后,您可以根据$*中的词干调用该函数来确定目标的先决条件:

.SECONDEXPANSION:
obj/%.o: $$(call expand,$$*)
    $(CC) $(CFLAGS) $< -o $@