我正在编写一个可以在Windows和Linux上运行的makefile。所以尽可能避免使用特定于操作系统的shell命令。
这是我的makefile的片段,最后带有clean
函数:
# OS specific part
# -----------------
ifeq ($(OS),Windows_NT)
RM = del /F /Q
RMDIR = -RMDIR /S /Q
MKDIR = -mkdir
ERRIGNORE = 2>NUL || (exit 0)
SEP=\\
else
RM = rm -rf
RMDIR = rm -rf
MKDIR = mkdir -p
ERRIGNORE = 2>/dev/null
SEP=/
endif
PSEP = $(strip $(SEP))
# Definitions for nullstring and space
# -------------------------------------
nullstring :=
space := $(nullstring) #End
# Lists of all files and folders to keep or remove
# -------------------------------------------------
buildFiles_toKeep := ... # I wrote some scripts to
buildDirs_toKeep := ... # automatically generate
buildFiles_toRemove := ... # these lists. But that would lead
buildDirs_toRemove := ... # us too far here.
.PHONY: clean
clean:
@echo.
@echo ----------------------------------------------------------
@echo.$(space) __ ************** $(space)
@echo.$(space) __\ \___ * make clean * $(space)
@echo.$(space) \ _ _ _ \ ************** $(space)
@echo.$(space) \_`_`_`_\ $(space)
@echo.$(space) $(space)
@echo.$(space)Keep these files:
@echo.$(space) $(buildFiles_toKeep)
@echo.$(space)
@echo $(space)Keep these directories:
@echo.$(space) $(buildDirs_toKeep)
@echo.$(space)
@echo.$(space)Remove these files:
@echo.$(space) $(buildFiles_toRemove)
$(RM) $(buildFiles_toRemove)
@echo.
@echo.$(space)Remove these directories:
@echo.$(space) $(buildDirs_toRemove)
$(RMDIR) $(buildDirs_toRemove)
@echo.
@echo ----------------------------------------------------------
这个makefile效果很好。在Windows和Linux上,它都使用适当的shell命令替换$(RM)
和$(RMDIR)
以删除文件和文件夹。但我想提示用户他/她可以按Y或N.我不想删除他/她想要保留的文件。我试图在clean
目标的配方中插入一些批处理命令,提示用户输入。但是没有显示提示。也许是因为GNU make推迟了输入流。
我想知道是否可以使用'pure'make syntaxis生成[Y / N]提示符(没有特定于操作系统的shell命令)。我知道make语言有其局限性。也许一个聪明的解决方案可以在一个操作系统(例如Linux)上运行,并以最小的开销移植到另一个操作系统(例如Windows)。
有人有想法吗?
编辑:
我被引用了这个链接:How do I get `make` to prompt the user for a password and store it in a Makefile variable?
Gnu make会通过提示用户创建变量PASSWORD
:
$ cat Makefile
PASSWORD ?= $(shell bash -c 'read -s -p "Password: " pwd; echo $$pwd')
只要您希望在makefile 解析时出现提示,这种提示用户输入的方式就可以正常工作。但我的情况有所不同。我想在makefile 已经运行时提示用户,换句话说,当makefile中的配方正在执行时。
编辑:
运行make多线程时,无法提示用户。所以我完全可以调用clean
函数单线程:
>> make clean -j1
毕竟,clean
功能不需要很长时间才能完成。我不打算在build
函数中提示用户任何内容,因此可以执行多线程: - )
>> make all -j8 --output-sync=target
答案 0 :(得分:1)
概念上make是一个非常简单的应用程序,只有一个目的 - 构建一个依赖树,并重新制作具有较新祖先的东西。交互不应该是一个因素,所以make不能本地提供,理想情况下make应该已经拥有它需要的所有信息。如果您确实需要,可以使用shell
,!=
解决此问题,甚至可以使用guile或load
提供您自己的扩展程序。
这实际上并不适用于clean
规则,因为clean
首先不会重新制作任何内容,只是一个快速的黑客攻击,可以方便地表达非制作使用make语法进行操作。
就个人而言,我没有看到提示用户删除文件的价值,除非你要删除你不负责的东西,这本身就是反模式。
如果你绝对肯定你需要这个,那么将clean
食谱包装在一个脚本中,并为bash和windows提供两个版本。您也可以假设在Windows上运行GNU make的任何人已经在使用MSYS2,Cygwin或MS认可的bash for Windows 10版本,并且完全放弃了cmd / powershell脚本。
答案 1 :(得分:0)
如果您想在一行中使用 Yes/No 来执行某些操作(这里是另一个 makefile 目标):
request-test:
@echo -n "Are you sure? [y/N] " && read ans && if [ $${ans:-'N'} = 'y' ]; then make ENV=test spec-tests; fi
ans
的变量中;if
使用默认值读取 ans
变量的值以避免错误。