使用Makefile编辑文件而不是创建文件

时间:2015-08-04 19:12:41

标签: makefile

我正在考虑使用Make进行我的开发设置的小检查。我想要的一件事是在执行某些操作之前检查文件中是否存在特定字符串。如果我想创建整个文件,那将是微不足道的

action: filename
    ...

filename:
    echo 'blah' >> filename

但是如何将这种逻辑应用于grep等行为呢?我的依赖关系不是文件存在,而是文件的内容正确。

我具体询问Make而不是其他解决方案,如chef / puppet

3 个答案:

答案 0 :(得分:0)

您可以在make配方中运行所需的任何shell命令。正如你想要的那样,它们也很多。

因此,如果您需要在执行其他操作之前运行grep,请执行此操作。

请记住,配方中的每一行都在自己的shell会话中运行,因此它们不共享状态。

所以这个:

action: filename
    ...

filename:
    grep -qw blah $@ || echo 'blah' > $@

grep上运行filename(通过当前目标$@的{​​{3}})查找整个单词并在第一场比赛中退出(-q

如果grep找到blah,那么它将返回成功,||将短路并且配方已完成。如果grep失败,则||会触发,echo将会启动。

如果Y为真,你可能很想做一些需要逆逻辑做X的事情:

filename:
    grep -qw blah $@ && echo blah2 > $@

但这不能正常工作。当grep失败时,&&短路,make看到配方失败,并将make进程解除错误。

你需要这个。

filename:
    ! grep -qw blah $@ || echo blah2 > $@

反转逻辑并确保grep的“失败”在make方面被视为成功。

如果filename完全存在,那么在这个具体示例中所说的都是因为它没有先决条件,因此make 总是认为它不会运行最新。要解决此问题,您需要为文件提供一个先决条件,以强制它被视为过时。具体来说是automatic variable

尽管如此,请不要遵循有关.PHONY的建议。 .PHONY目标永远不应成为非.PHONY目标的先决条件。

答案 1 :(得分:0)

你可以在目标的配方中添加一个测试(在我完成这个答案之前,As Etan已经发布了......)。如果你想使用make逻辑来做这件事,你可以做一些事情:

actions: $(if $(shell grep -q $$string filename && echo y),filename,)

filename:
    echo blah >> $@

如果filename包含字符串,那么将存在actions: filename依赖项,并且在构建操作时将构建文件名。请注意,虽然这将检查在解析makefile时字符串是否存在于文件名中 - 如果生成文件名或在此makefile中修改了文件名,那么它将不会影响操作是否运行。如果要在覆盖文件之前进行测试,那么您将在配方本身中使用bash if语句。

答案 2 :(得分:0)

扩展@john写的内容我得到以下工作:

TEST_FILE=filename
.PHONY: ${TEST_FILE}
string=testing

filecheck=$(shell grep -qw ${string} ${TEST_FILE} || echo ${TEST_FILE})

all: ${filecheck}

${TEST_FILE}:
    echo 'changing the file'
    echo ${string} >> ${TEST_FILE}

此处我操作的文件是.PHONY目标。我认为没问题,因为我实际上并没有创建文件,只是修改它。如果文件不存在,或者没有所需的字符串,则工作。