#!/bin/bash
NEEDED_COMMANDS="jlex byaccj ant javac"
for cmd in ${NEEDED_COMMANDS} ; do
if ! command -v ${cmd} &> /dev/null ; then
echo Please install ${cmd}!
exit 1
fi
done
touch .cmd_ok
我对后一种解决方案的改进是使用 which可执行文件(Windows 中的 where) ,而不是依赖于在每个可执行文件中都有一个 --version选项,直接在 GNU Make ifeq指令中,而不是定义一个新的变量,如果所需的可执行文件不在 ${PATH}中,则使用 GNU Make error函数停止构建。例如,要测试 lzop可执行文件:
ifeq (, $(shell which lzop))
$(error "No lzop in $(PATH), consider doing apt-get install lzop")
endif
如果有几个可执行文件需要检查,那么可能需要对 which可执行文件使用 foreach函数:
EXECUTABLES = ls dd dudu lxop
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH")))
对我来说,以上所有的答案都是基于 linux 的,而不是使用 Windows。我是新来的,所以我的方法可能不太理想。但是在 linux 和 windows 上对我都适用的完整例子是:
# detect what shell is used
ifeq ($(findstring cmd.exe,$(SHELL)),cmd.exe)
$(info "shell Windows cmd.exe")
DEVNUL := NUL
WHICH := where
else
$(info "shell Bash")
DEVNUL := /dev/null
WHICH := which
endif
# detect platform independently if gcc is installed
ifeq ($(shell ${WHICH} gcc 2>${DEVNUL}),)
$(error "gcc is not in your system PATH")
else
$(info "gcc found")
endif
当我需要检测更多我可以使用的工具时,可以选择:
EXECUTABLES = ls dd
K := $(foreach myTestCommand,$(EXECUTABLES),\
$(if $(shell ${WHICH} $(myTestCommand) 2>${DEVNUL} ),\
$(myTestCommand) found,\
$(error "No $(myTestCommand) in PATH)))
$(info ${K})
all: require validate test etc
require:
@echo "Checking the programs required for the build are installed..."
@shellcheck --version >/dev/null 2>&1 || (echo "ERROR: shellcheck is required."; exit 1)
@derplerp --version >/dev/null 2>&1 || (echo "ERROR: derplerp is required."; exit 1)
# And the rest of your makefile below.
下面脚本的输出是
Checking the programs required for the build are installed...
ERROR: derplerp is required.
makefile:X: recipe for target 'require' failed
make: *** [require] Error 1