检查Makefile中是否存在程序,否则运行命令

时间:2015-10-20 03:35:47

标签: makefile

我想创建一个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目标/命令。我尝试了很多不同的实现,但没有解决我的问题。

如何在Makefile中实现类似的功能?

P.S:这个问题不是来自" Check if a program exists from a Makefile"的重复问题。因为后者的目的是在程序不存在的情况下停止执行,而前者的目的是在程序不存在的情况下运行另一个目标。

2 个答案:

答案 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.pynosetests -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 || pooif ack; then ick; else poo; fi

的简写