定义外壳:为什么有些目标因错误“无效语法”而失败,而另一些目标却没有失败?

时间:2018-10-26 13:52:32

标签: makefile gnu-make

我的Makefile如下(摘录):

# be a POSIX guy!
SHELL = /bin/dash

# avoid accursed tabs
.RECIPEPREFIX +=

PROJECT = my_project

# before-commit stuff
CHANGED_FILES = $(shell git ls-files --modified)

files ?= $(CHANGED_FILES)

lint:
    pyflakes $(files)

lint-all:
    pyflakes $(PROJECT)

STAGING_DB_PORT = 5437

staging-db-start:
    ssh -fNL 0.0.0.0:$(STAGING_DB_PORT):localhost:$(STAGING_DB_PORT) staging-db
    ss -tlpn sport eq :$(STAGING_DB_PORT)

staging-db-stop:
    ssh -O check staging-db
    ssh -O stop staging-db
    ss -tlpn sport eq :$(STAGING_DB_PORT)

staging-db-check:
    ss -tlpn sport eq :$(STAGING_DB_PORT)
    ssh -O check staging-db

.PHONY: lint, lint-all, staging-db-start, staging-db-stop, staging-db-check

当我运行目标时,说staging-db-check很好。虽然,当我运行目标lint时,它失败并显示错误:

Makefile:2:9: invalid syntax
SHELL = /bin/dash
        ^

对我来说,这很奇怪。我阅读了文档,他们说您总是必须设置SHELL变量,所以我决定这样做。但是我不知道哪里有错误?

我有GNU make,版本4.2.1。

1 个答案:

答案 0 :(得分:1)

GNU Make永远不会生成以下形式的诊断:

Makefile:2:9: invalid syntax
SHELL = /bin/dash
    ^

但是pyflakes会这样做,这是由您的lint目标的配方运行的程序:

lint:
    pyflakes $(files)

如您所知,pyflakes减少了Python源文件。您的$(files),已分配 通过:

# before-commit stuff
CHANGED_FILES = $(shell git ls-files --modified)

files ?= $(CHANGED_FILES)

扩展到包含Makefile的文件列表。您的Makefile不是 Python源文件和Makefile中第一行的语法 有效的Python是:

SHELL = /bin/dash

这是一个较短的makefile:

制作文件

# be a POSIX guy!
SHELL = /bin/dash

.PHONY: all

all:
    echo "Hello World"

用来重现您的错误的

$ pyflakes Makefile
Makefile:2:9: invalid syntax
SHELL = /bin/dash
        ^

稍后

  

是否可以从$ files变量中排除非python文件?

是的。假设Python文件是扩展名为.py的文件,请更改:

CHANGED_FILES = $(shell git ls-files --modified)

收件人:

CHANGED_FILES = $(filter %.py,$(shell git ls-files --modified))

查看功能:

$(filter pattern...,text)
$(filter-out pattern...,text)

8.2 Functions for String Substitution and Analysis中 在the GNU Make manual

如果这样做,最好将CHANGED_FILES更改为CHANGED_PYTHON_FILES