如果未设置,请从控制台读取Makefile变量

3
我将更新一个Makefile,该文件从外部源访问某些资源,即存在以下形式的规则:
$(External)/% : 
    cvs up $@

如果资源没有限制,它将按预期工作。现在,由于功能漂移,外部资源需要更复杂的登录,因此规则已更改为与此类似:

$(External)/% : 
    cvs -d :pserver:$(CVSUSER)@cvs-server up $@

...这使得规则依赖于变量CVSUSER。要强制执行这个规则的快速简单方法是,如果未定义,则用有用的错误消息中止。但这并不好玩,如果在需要时它未设置,我想从控制台读取变量CVSUSER。我天真地尝试了

CVSUSER ?= $(shell read -p "User name: ")

但这显然行不通 :) 你会如何解决这个问题?
3个回答

3

$(shell) 抓取来自 shell 命令的输出。但是 read 在变量中读取输入(默认为 REPLY)并不输出它。这里有一个快速修复方法:

CVSUSER ?= $(shell read -p "User name: ";echo $$REPLY)

然而,每次访问变量时都会调用shell命令。当你要进行几百个文件更新时,这并不好 :) - Christoffer

2
你已经自己找到了解决方案,但我建议不要创建一个在被调用后依赖用户交互的makefile。这样做会使构建难以集成到自动化构建系统(例如CruiseControl、AntHill等),也会使它难以集成到分布式构建系统(pvmgmake等)中。
更好的方法是在调用makefile之前放置对CVSUSER的检查的包装脚本,如果未设置CVSUSER,则使makefile立即退出并显示错误。
祝好,
Eric Melski

http://blog.electric-cloud.com


如果Makefile不用于软件构建,而是用于从模板简化各种配置文件的创建(“在此运行make,它将为您生成虚拟机”),那么读取用户输入可能是合理的。当然,这不是常见情况,但我以前见过这种用例。 - Florin Andrei

1
当然,我需要一个简单扩展的变量,而不是递归的。这样我就可以让变量依赖于自身,并使用普通的Make工具来有条件地设置它。条件赋值隐式地创建了一个正常的(递归的)变量,所以我需要执行以下操作:
CVSUSER := $(shell if [ -z $(CVSUSER) ] ; then read -p "User name: " REPLY ; echo $$REPLY ; fi )

或者

ifndef CVSUSER
    CVSUSER := $(shell then read -p "User name: " REPLY ; echo $$REPLY ; fi )
endif

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