2014-04-25 60 views
0

我正在与makefiles争斗......我需要一些帮助。GNU make:ifneq总是评估为真

check-fleet: 
    LOCAL_VERSION = $(shell fleetctl -version) 
    REMOTE_VERSION = $(shell ssh [email protected]$(FLEETCTL_TUNNEL) fleetctl -version) 
    ifneq $(strip $(LOCAL_VERSION)) $(strip $(REMOTE_VERSION)) 
     $(error Your fleetctl client version should match the server. Local version: $(LOCAL_VERSION), server version: $(REMOTE_VERSION). Uninstall your local version and install the latest build from https://github.com/coreos/fleet/releases) 
    endif 

当此执行,我看到它确实脱壳而出,并连接到服务器,但错误总是发生,甚至当我手动设置这些变量的值!此外,它们在错误声明中始终为空。

即使他们正在设置的问题(即他们是空白的),那么至少他们会是平等的,并且ifneq永远不会开火。

我想知道这是否是一个与Makefiles的两遍处理有关的问题,但我尝试将自己手动设置为已知字符串,并且错误仍然会激发。我没有想法...

回答

2

理解make不是配方的一部分(通常,而不是用TAB缩进)的行是由make解析的,而且行的makefile是配方的一部分(通常用TAB缩进)是而不是由make解析;它们被传递给shell并且shell运行它们。

因此,将变量赋值或在等命令中配制(使用TAB缩进)是不合法或无效的。

如果要命令作为check-fleet目标的一部分运行,则必须在配方中编写shell脚本,而不是使用make构造。

check-fleet: 
     LOCAL_VERSION=`fleetctl -version`; \ 
     REMOTE_VERSION=`ssh [email protected]$(FLEETCTL_TUNNEL) fleetctl -version`; \ 
     if [ $$LOCAL_VERSION != $$REMOTE_VERSION ]; then \ 
      echo "Your fleetctl client version should match the server. Local version: $$LOCAL_VERSION, server version: $$REMOTE_VERSION. Uninstall your local version and install the latest build from https://github.com/coreos/fleet/releases"; exit 1; \ 
     fi 
+0

这非常有帮助,而且很有意义 - 谢谢!但我注意到,我可以在配方中使用Make函数 - 我经常使用'$(call ...)'函数来调用用黄色回声输出的用户定义函数。这是我不应该做的事吗? –

+1

当然,您可以在食谱中使用它们:实际上这通常非常有用。所有的变量和函数在调用配方之前由make评估,然后将结果发送到shell。所以,只要你需要做的事情都可以在配方开始之前发生,而不依赖配方运行的命令的任何结果(因为它将不会运行,直到以后),那么你可以使用make函数。我的经验法则是,你不应该在配方中使用'$(shell ...)'(因为配方本身是一个shell脚本)。当然你不能使用ifeq或其他预处理器命令。 – MadScientist

+0

有帮助。谢谢! –