如何在我的 makefile 中提示用户输入 [y/n](使用纯 make 语法)?
How to prompt user for [y/n] in my makefile (with pure make syntaxis)?
我正在编写一个应该在 Windows 和 Linux 上工作的 makefile。因此,只要有可能,我都会避免使用 OS-specific 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 ----------------------------------------------------------
这个生成文件效果很好。在 Windows 和 Linux 上,它用正确的 shell 命令替换 $(RM)
和 $(RMDIR)
来删除文件和文件夹。但我想提示用户 he/she 可以按 Y 或 N。我不想删除 he/she 想保留的文件。我试图将一些批处理命令插入到 clean
目标的 recipeee 中,以提示用户输入。但是没有显示提示。可能是因为 GNU make 延迟了输入流。
我想知道是否可以使用 'pure' make syntaxis 生成 [Y/N] 提示符(没有 OS-specific shell 命令)。我知道 make 语言有其局限性。也许一个聪明的解决方案可以在一个操作系统上运行(例如 Linux)并以最小的开销移植到另一个操作系统(例如 Windows)。
有人有想法吗?
编辑:
我提到了这个 link: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')
只要您希望在 parsed 时提示出现,这种提示用户输入的方法就可以正常工作。但我的情况不同。我想在 makefile already 运行ning 时提示用户,换句话说,当 makefile 中的 recipeee 正在执行时。
编辑:
当您运行设置为多线程时,将无法提示用户。所以我完全可以调用 clean
单线程函数:
>> make clean -j1
毕竟,clean
功能不需要很长时间就可以完成。我不打算在 build
函数中提示用户任何内容,以便可以多线程执行:-)
>> make all -j8 --output-sync=target
从概念上讲,make 是一个非常简单的应用程序,只有一个目的 - 构建依赖树,并重新制作具有较新祖先的东西。交互不应该是一个因素,所以 make 不会在本地提供它,理想情况下 make 应该已经拥有它需要的所有信息。如果您确实需要,可以使用 shell
、!=
解决此问题,甚至可以使用 guile 或 load
.
提供您自己的扩展
虽然这并不真正适用于 clean
规则,因为 clean
一开始并没有重新制作任何东西,它只是一个快速的 hack,让你方便地表达一个非-make 操作使用 make 语法。
就我个人而言,我看不到提示用户删除文件的价值,除非你要删除你不负责的东西,这本身就是一种反模式。
如果您绝对肯定需要这个,那么将 clean
配方包装在脚本中,并为 bash 和 windows 提供两个版本。您也可以假设 运行 GNU make on windows 已经在使用 MSYS2、Cygwin 或 MS 认可的 bash for Windows 10 版本,并完全放弃 cmd / powershell 脚本。
如果您想在一行中使用是/否来执行某些操作(这里是另一个 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
变量的值,避免出错。
我正在编写一个应该在 Windows 和 Linux 上工作的 makefile。因此,只要有可能,我都会避免使用 OS-specific 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 ----------------------------------------------------------
这个生成文件效果很好。在 Windows 和 Linux 上,它用正确的 shell 命令替换 $(RM)
和 $(RMDIR)
来删除文件和文件夹。但我想提示用户 he/she 可以按 Y 或 N。我不想删除 he/she 想保留的文件。我试图将一些批处理命令插入到 clean
目标的 recipeee 中,以提示用户输入。但是没有显示提示。可能是因为 GNU make 延迟了输入流。
我想知道是否可以使用 'pure' make syntaxis 生成 [Y/N] 提示符(没有 OS-specific shell 命令)。我知道 make 语言有其局限性。也许一个聪明的解决方案可以在一个操作系统上运行(例如 Linux)并以最小的开销移植到另一个操作系统(例如 Windows)。
有人有想法吗?
编辑:
我提到了这个 link: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')
只要您希望在 parsed 时提示出现,这种提示用户输入的方法就可以正常工作。但我的情况不同。我想在 makefile already 运行ning 时提示用户,换句话说,当 makefile 中的 recipeee 正在执行时。
编辑:
当您运行设置为多线程时,将无法提示用户。所以我完全可以调用 clean
单线程函数:
>> make clean -j1
毕竟,clean
功能不需要很长时间就可以完成。我不打算在 build
函数中提示用户任何内容,以便可以多线程执行:-)
>> make all -j8 --output-sync=target
从概念上讲,make 是一个非常简单的应用程序,只有一个目的 - 构建依赖树,并重新制作具有较新祖先的东西。交互不应该是一个因素,所以 make 不会在本地提供它,理想情况下 make 应该已经拥有它需要的所有信息。如果您确实需要,可以使用 shell
、!=
解决此问题,甚至可以使用 guile 或 load
.
虽然这并不真正适用于 clean
规则,因为 clean
一开始并没有重新制作任何东西,它只是一个快速的 hack,让你方便地表达一个非-make 操作使用 make 语法。
就我个人而言,我看不到提示用户删除文件的价值,除非你要删除你不负责的东西,这本身就是一种反模式。
如果您绝对肯定需要这个,那么将 clean
配方包装在脚本中,并为 bash 和 windows 提供两个版本。您也可以假设 运行 GNU make on windows 已经在使用 MSYS2、Cygwin 或 MS 认可的 bash for Windows 10 版本,并完全放弃 cmd / powershell 脚本。
如果您想在一行中使用是/否来执行某些操作(这里是另一个 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
变量的值,避免出错。