我想创建一个Makefile,用于识别系统中是否存在给定程序,如果不存在则运行另一个目标(或命令)。请在问题结尾处阅读我的 post scriptum (P.S。),然后将其标记为重复。
总之,我想做类似以下伪代码的事情:
if (myProgram.exists()):
myProgram arg0 arg1 arg2
else:
otherProgram arg0 arg1 arg2 #suppose that otherProgram will always exists
我按照this SO question的最佳答案尝试了一些解决方案,告诉我这样做:
check: ; @which myProgram > /dev/null
mytarget: check
myProgram arg0 arg1 arg2
解决方案实际上有效,但会中止程序而不是执行另一个makefile目标/命令。我尝试了很多不同的实现,但没有解决我的问题。
P.S:这个问题不是来自" Check if a program exists from a Makefile"的重复问题。因为后者的目的是在程序不存在的情况下停止执行,而前者的目的是在程序不存在的情况下运行另一个目标。
答案 0 :(得分:3)
在Makefile中做这样的事情很容易(对于简单的问题;复杂的问题需要更多的关注,也许是另一种解决方案)。
对于您的示例,以下代码将起到作用:
run: check
myProgram arg0 arg1 arg2
check:
@type myProgram >/dev/null 2>&1 || otherProgram arg0 arg1 arg2
当然,您应该针对您的问题进行修改。为了帮助您,您可以从我的项目中读取一个真实的用例。
现在让我们看一下this small graph implementation in Python的真实用例。我用unittest
编写了一些测试,其中:(a)我可以直接从Python执行它,或者(b)可以从nose执行它。后者具有更多冗长,因此对于测试目的而言更好。
要运行(a)我需要像python mytest.py
这样的东西。对于(b)我需要像nosetests -v mytest.py
这样的东西。看看我的makefile
:
all: run_tests
run_tests: check
nosetests -v test_digraph.py
nosetests -v test_not_digraph.py
check:
@type nosetests >/dev/null 2>&1 || /usr/bin/env python test_digraph.py
@type nosetests >/dev/null 2>&1 || /usr/bin/env python test_not_digraph.py
此makefile将检查nosetests
是否存在,如果不存在,它将直接从Python执行测试(使用/usr/bin/env python test_digraph.py
)。如果nosetests
存在,那么它将执行来自run_tests
目标的说明(换句话说,nosetests -v test_digraph.py
和nosetests -v test_not_digraph.py
)。
希望它有所帮助!
答案 1 :(得分:1)
您可以在代码中添加任意shell脚本。但是,仅将命令定义一次是有意义的。
COMMAND:=$(shell type -p foo || echo bar)
会将COMMAND
设置为foo
(如果存在),否则设置为bar
。
如果您愿意,可以在目标中嵌入类似的代码段,但您可能希望避免代码重复。
target: prerequisites
{ type -p foo && foo $^ || bar $^; } >$@
您可能已经知道,ack && ick || poo
是if ack; then ick; else poo; fi