使用GNU make复制一堆文件

时间:2014-11-26 22:24:07

标签: makefile gnu-make

假设我有一个makefile,我想将一些文件从一个地方复制到另一个地方,例如:

  • include/mylib/mylib.hdist/include/mylib/mylib.h
  • include/mylib/platform/linux/platform.hdist/include/mylib/platform.h

这是"安装"的一部分。规则。我想到的是某种类似的东西:

EXTRA_INSTALL += include/mylib/mylib.h=dist/include/mylib/mylib.h
EXTRA_INSTALL += include/mylib/platform/linux/platform.h=dist/include/mylib/platform.h

# All other dependecies (objects, .so, etc.) go through `$(TARGET)`
install: $(TARGET) $(EXTRA_INSTALL)

$(EXTRA_INSTALL):
    @cp $(firstword $(subst =, ,$@)) $(lastword $(subst =, ,$@))

.PHONY: install $(EXTRA_INSTALL)

我认为这是一种黑客行为,但我无法想出一个合适的方法。那么有更好的方法来实现同样的目标吗?请注意,输入文件名和输出文件名之间没有明显的连接,因此排序dist/include/%.h:include/%.h的规则不合适。

2 个答案:

答案 0 :(得分:2)

以下内容可能更具可读性(虽然它增加了一些重复),如果文件碰巧发生了变化,它可以更新文件。

EXTRA_INSTALL := dist/include/mylib/mylib.h dist/include/mylib/platform.h

.PHONY: install
install: $(EXTRA_INSTALL)

dist/include/mylib/mylib.h: include/mylib/mylib.h
dist/include/mylib/platform.h: include/mylib/platform/linux/platform.h

.SECONDEXPANSION:
$(EXTRA_INSTALL): $$^
    cp $^ $@

您也可以完全放弃.SECONDEXPANSION,但每个文件额外一行

EXTRA_INSTALL := dist/include/mylib/mylib.h dist/include/mylib/platform.h

.PHONY: install
install: $(EXTRA_INSTALL)

dist/include/mylib/mylib.h: include/mylib/mylib.h
    cp $^ $@
dist/include/mylib/platform.h: include/mylib/platform/linux/platform.h
    cp $^ $@

答案 1 :(得分:2)

这是一个可怕的黑客攻击。做这种事情完全 make是什么,你不需要在make内发明你自己的迷你语言。

source=target映射定义为make先决条件,然后通过cp定义创建它的配方:

dist/include/mylib/mylib.h: include/mylib/mylib.h 
        cp $^ $@

这表示创建文件dist/include/mylib/mylib.h取决于另一个文件(因此如果另一个文件发生更改将重新创建),并且应该通过复制它来创建它。

@ user657267的答案显示了如何通过将依赖项的定义与用于执行实际复制的配方分开来减少重复,因此您不需要在每个文件上重复cp配方。然而,由于配方非常简单,我认为重复它没有任何害处。如果配方变得更复杂,你总是可以用函数调用替换配方:

CP := cp -f
copy_file := $(CP) $(1) $(2)

dist/include/mylib/mylib.h: include/mylib/mylib.h 
        $(call copy_file,$^,$@)

dist/include/mylib/platform.h: include/mylib/platform/linux/platform.h
        $(call copy_file,$^,$@)