如何从makefile规则中导出变量?

9

我在我的Makefile规则中设置了环境:

.ONESHELL:
set_db_env:
    export DB_USER=XXX
    export DB_PASS=YYY   

我可以重复使用 set_db_env 目标吗?

another_rule: set_db_env
    echo ${DB_USER}

我也找到了.EXPORT_ALL_VARIABLES,但不知道如何使用。 更新
我已发现这个方法可行:
$(shell ${APP} db_env > ${CONF_DIR}/db_env.conf)
include ${CONF_DIR}/db_env.conf

但我认为这不是一个好的方法


你的 set_db_env 规则/配方实际上有效吗?这应该在每个 export 语句中运行一个单独的 shell,否则我会期望关于 := 无效语法的错误。 - G.M.
@G.M.: 我已经更新了问题。但无论如何它都导出到一个父shell中,对吗? - Eugen Konkov
1
看一下这个解决方案,它应该会给你带来一些启示。 - perror
@perror:是的,我之前也看到过。在每个规则之前写 N 个"export VAR"行太啰嗦了。我想只用一个命令“set_db_env”就可以重复使用它们。 - Eugen Konkov
@EugenKonkov:我之前不知道.EXPORT_ALL_VARIABLES,但这似乎是你要找的!这里有一个使用它的例子。基本上,你只需要在Makefile中将其声明为空目标即可。 - perror
@perror:.EXPORT_ALL_VARIABLES 导出变量给子进程,而不是依赖规则。但我认为还有一种方法... - Beta
2个回答

8

一般情况下,变量不会从一个规则传递到另一个规则。但是可以使用目标特定变量来实现:

another_rule: DB_USER=XXX
another_rule: DB_PASS=YYY                              

another_rule:
    @echo user is ${DB_USER}
    @echo pass is $(DB_PASS)

如果为每个规则编写许多额外的行太过繁琐,您可以将它们包装在函数中:
define db_env
$(1): DB_USER=XXX
$(1): DB_PASS=YYY
endef

$(eval $(call db_env,another_rule))
another_rule:
    @echo user is ${DB_USER}
    @echo pass is $(DB_PASS)

请问您能否提供更多关于这里正在发生的事情的描述?我已经阅读了调用,但仍然不明白db_env在哪里起作用。为什么您要将目标名称指定为调用的参数? - Eugen Konkov
@EugenKonkov:“another_rule”是第一个参数,因此call将该值分配给临时变量1,因此当call扩展变量db_env时,每个“$(1)”的实例都变成了“another_rule”。 - Beta

2

另一种解决方案可能是使用特定于模式的变量

我的用例:

staging%: export DB_HOST="127.0.0.1"
staging%: export DB_NAME="yolo"

staging-shell:
    @echo "My host is ${DB_HOST}"

staging-server:
    @echo "My host is ${DB_HOST}"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接