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

Pal*_*ini 2 makefile

我想创建一个 Makefile 来识别系统中是否存在给定的程序,如果不存在则运行另一个目标(或命令)。请阅读我在问题末尾的脚本(PS),然后将其标记为重复。

总之,我想做如下伪代码:

if (myProgram.exists()):
    myProgram arg0 arg1 arg2
else:
    otherProgram arg0 arg1 arg2 #suppose that otherProgram will always exists
Run Code Online (Sandbox Code Playgroud)

我已经按照this SO question的最佳答案尝试了一些解决方案,这告诉我做这样的事情:

check: ; @which myProgram > /dev/null
mytarget: check
    myProgram arg0 arg1 arg2
Run Code Online (Sandbox Code Playgroud)

该解决方案实际上有效,但这会中止程序而不是执行另一个 makefile target / command。我尝试了很多不同的实现,但没有一个解决了我的问题。

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

PS:这个问题不是“检查Makefile中的程序是否存在”的重复问题,因为后者旨在如果程序不存在则停止执行,而前者旨在如果程序不存在则运行另一个目标存在。

tri*_*eee 6

您可以在代码中放置任意的 shell 脚本片段。不过,仅定义该命令一次是有意义的。

COMMAND:=$(shell type -p foo || echo bar)
Run Code Online (Sandbox Code Playgroud)

如果存在则设置COMMAND为,否则设置为。foobar

如果您愿意,可以将类似的代码片段嵌入到目标中,但您可能希望避免代码重复。

target: prerequisites
    { type -p foo && foo $^ || bar $^; } >$@
Run Code Online (Sandbox Code Playgroud)

您可能已经知道,ack && ick || poo是简写if ack; then ick; else poo; fi


Pal*_*ini 5

一般用例:

在 Makefile 中做类似的事情很容易(对于简单的问题;复杂的问题需要更多的关注,也许还有其他解决方案)。

对于您的示例,以下代码将起作用:

run: check
    myProgram arg0 arg1 arg2

check: 
    @type myProgram >/dev/null 2>&1 || otherProgram arg0 arg1 arg2
Run Code Online (Sandbox Code Playgroud)

当然,您应该针对您的问题修改它。为了帮助你,下面你可以从我的一个项目中阅读一个真实的用例。


一个真实的用例:

现在让我们看一个从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
Run Code Online (Sandbox Code Playgroud)

这个 makefile 将检查是否nosetests存在,如果不存在,它将直接从 Python 执行测试(使用/usr/bin/env python test_digraph.py)。如果nosetests存在,那么它将执行来自run_tests目标的指令(换句话说,nosetests -v test_digraph.pynosetests -v test_not_digraph.py)。

希望能帮助到你!