45

我在 Makefile 中有以下内容,用于重新创建我的数据库,包括在必要时销毁它。这没用。

.PHONY: rebuilddb
    exists=$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'")
    if [ $(exists) -eq 1 ]; then
        dropdb the_db
    fi
    createdb -E UTF8 the_db

运行它会导致错误:

$ make rebuilddb
exists=
if [  -eq 1 ]; then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [rebuilddb_postgres] Error 2

为什么这是错误的?据我所知,它看起来像是有效的 Bash?在 Makefile 中执行此操作时是否需要特别考虑?

更新:

使用答案,我得到了一个工作版本:

.PHONY: rebuilddb
    exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'"); \
    if [ "$$exists" == "1" ]; then \
        dropdb the_db; \
    fi;
    createdb -E UTF8 the_db
4

2 回答 2

57

至少有两个考虑。 $()引用 Make 变量。您必须转义$to do 命令替换。此外,shell 命令必须全部在一行上。尝试:

exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM \
    pg_database WHERE datname='the_db'"); \
    if [ "$$exists" -eq 1 ]; then \
        dropdb the_db; \
    fi; \
    createdb -E UTF8 the_db

另一方面,似乎总是尝试删除数据库并允许失败会更简单:

rebuilddb:
    -dropdb the_db  # Leading - instructs make to not abort on error
    createdb -E UTF8 the_db
于 2012-12-08T05:40:21.727 回答
0

为了完整起见 $(eval $(call ...)

在动态生成规则中,您必须使用 $$$$ 转义 shell 变量。

这是一个用“GNU Make 4.2.1”测试过的例子:

MY_LIBS=abc

a_objs=a1.o a2.o
b_objs=b1.o b2.o b3.o
c_objs=c1.o c2.o c3.o c4.o

默认值:库

# function lib_rule(name, objs)

定义 lib_rule
lib$(1).a: $(2)
退出 1 | 三通 make.log ; 测试$$$$ {PIPESTATUS[0]} -eq 0
endef

# 生成规则
$(foreach L,$(MY_LIBS),$(eval $(call lib_rule,$(L),$($(L)_objs))))

# 调用生成的规则
库:$(patsubst %,lib%.a,$(MY_LIBS))

# 虚拟对象生成
%.o:%.c
touch $@

# 虚拟源生成
%.c:
touch $@

clean::
rm -f *.c *.o lib*.a make.log

输出:'make -Rr'

1号出口 | 三通 make.log ; 测试$ {PIPESTATUS[0]} -eq 0
make: *** [Makefile:18: liba.a] 错误 1

管道中最后一个命令的结果从tee为。您可以从出口 1看到 bash 变量PIPESTATUS[0]的值为false

观察数据库:'make -Rrp'

定义 lib_rule
lib$(1).a: $(2)
退出 1 | 三通 make.log ; 测试$$$$ {PIPESTATUS[0]} -eq 0
endef

...

libc.a: c1.o c2.o c3.o c4.o
退出 1 | 三通 make.log ; 测试$$ {PIPESTATUS[0]} -eq 0

于 2018-09-13T08:50:07.827 回答