GNU Linux Makefile PHONY目标依赖项无法正常工作

时间:2017-10-09 11:30:55

标签: linux makefile

我正在尝试让一些依赖的安装目标在我的Makefile中工作,如下所示:

set.seed(123)

df2 <- data.frame(X1 = rnorm(20),
                  X2 = rnorm(20),
                  Group = rep(letters[1:4], each = 5))
df2[c(6, 11, 16), 1:2] <- NA

df2_complete <- lapply(split(df2, df2$Group), function(x){
        k <- which(names(x) == "Group")
        x[-k] <- sapply(x[-k], na.locf, na.rm = FALSE)
        x[-k] <- sapply(x[-k], na.locf, fromLast = TRUE)
        x
})
df2_complete <- do.call(rbind, df2_complete)
row.names(df2_complete) <- NULL
df2_complete

这与GNU Make手册中描述的非常相似:https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html

我做了

.PHONY: install-everything install-part1 install-part2

install-everything: install-part1 install-part2

install-part1:
    $(call part1-function)

install-part2:
    $(call part2-function)

首先,然后手动(即rm -rf)删除已创建的$(DESTDIR)目录。

现在,每当我尝试运行上面列出的任何目标时,我都会得到例如:

make install-part1

如果我尝试使用'-B'标志强制make,我会得到相同的答案。如果我添加调试信息(make --debug),我得到

make: nothing to be done for 'install-everything'.

我认为使用.PHONY指令可以解决这个问题 - 任何人都可以帮忙吗?

1 个答案:

答案 0 :(得分:3)

您的partX-function宏,正如您在评论中解释的那样,展开为空字符串。他们做什么,他们扩展的方式是两回事。因此,您的食谱都是空的,并通过其nothing to be done消息告诉您。分析你的宏并发现它们做了某些事情是不够聪明的。您对GNU make及其call函数的使用是非常规的。对于您展示的示例,使用plain make会更好(除非您要安装大量文件并且性能很重要):

.PHONY: install-everything install-part1 install-part2

install-everything: install-part1 install-part2

install-part1: $(addprefix $(DIR1)/,$(FILES1))

$(DIR1):
    mkdir -p $@

$(addprefix $(DIR1)/,$(FILES1)): $(DIR1)/%: $(SRCDIR)/% | $(DIR1)
    cp -f $< $@

install-part2:...

(假设make变量SRCDIRDIR1FILES1定义源目录,install-part1的目标目录以及要为{{1}复制的文件列表分别)。

为了完全理解这个示例makefile,您需要了解static pattern rulesorder-only prerequisites

如果要安装大量文件并且性能很重要,最好将副本(install-part1)分组,从而减少shell调用次数:

cp

甚至:

install-part1: $(addprefix $(SRCDIR)/,$(FILES1)) | $(DIR1)
    for f in $(FILES1); do \
         cp -f $(SRCDIR)/$$f $(DIR1);\
    done

它不太优雅,因为没有正确声明所有依赖项。每次调用install-part1: $(addprefix $(SRCDIR)/,$(FILES1)) | $(DIR1) cp -f $^ $(DIR1) 时都会复制所有文件,即使它们已经安装并且是最新的,但它应该比使用其他解决方案快得多。

最后但并非最不重要:在GNU / Linux安装下经常使用make install-part1实用程序而不是install ...