Makefile 一个目标的多个规则

Makefile 一个目标的多个规则,makefile,Makefile,我有一个很大的项目,它是在几个不同的机器上按需编译的,有不同的操作系统。 其中一个目标在其依赖项中具有foo.res。可以使用以下两种不同规则之一编译此资源文件: 第一条规则要求文本文件foo.txt存在。此规则还要求在系统中安装一些非跨平台软件。我们的工程师无法在现场使用此规则,因为它不会在旧MacOS下运行 第二条规则使用资源目录中预编译的资源文件foo.res,并将其复制到build/。显然,这是不必要的解决办法,但我别无选择 我试图在一个Makefile中描述两条规则,但我遇到了这样的错

我有一个很大的项目,它是在几个不同的机器上按需编译的,有不同的操作系统。 其中一个目标在其依赖项中具有
foo.res
。可以使用以下两种不同规则之一编译此资源文件:

第一条规则要求文本文件
foo.txt
存在。此规则还要求在系统中安装一些非跨平台软件。我们的工程师无法在现场使用此规则,因为它不会在旧MacOS下运行

第二条规则使用资源目录中预编译的资源文件
foo.res
,并将其复制到
build/
。显然,这是不必要的解决办法,但我别无选择

我试图在一个Makefile中描述两条规则,但我遇到了这样的错误:

Makefile:78: warning: overriding recipe for target 'build/foo.res'
Makefile:75: warning: ignoring old recipe for target 'build/foo.res'
目前我使用Makefile时,其中一条规则已被注释掉:

.PHONY: compile
build/app.bin: some_files... build/foo.res
    (Here is compiler call)

build/:
    -mkdir build/

.PHONY: clear
clear:
    -rm -rf ./build

... Lots of stuff here ...

# build/foo.res: res/foo.res | build/.
#     cp res/foo.res build/foo.res

build/foo.res: res/foo.txt | build/.
    some_app -o build/foo.res res/foo.txt
我将预编译的
res/foo.res
部署到一些机器上,然后交换注释规则,因此使用常规的
cp
。这很好,直到在某些提交中对Makefile引入了一些更改。然后它会阻止git中的快进更新


如何根据匹配的依赖项将make配置为仅触发其中一个规则?

使用显式规则无法做到这一点。一个明确的规则告诉我们,这是如何构建这个目标的。您可以创建两个不同的模式规则来构建相同的目标。模式规则说这是构建目标的一种方法

因此,将makefile更改为:

build/%.res: res/%.res | build/.
        cp $< $@

build/%.res: res/%.txt | build/.
        some_app -o $@ $<
build/%.res:res/%.res | build/。
cp$<$@
build/%.res:res/%.txt | build/。
一些应用程序-o$@$<

我应该指出,这是GNU制定的具体要求;您正在使用GNU make(正如您引用的错误所证明的那样),但是您没有标记它。因为它是
res/foo.txt
->
build/foo.res
->需要
foo.res
的一些东西,一个相对明显的解决方法是将预编译
foo.res
部署到
build/foo.res
。这应该会让
make
感到高兴,因为它使用了一条规则(在您的案例中是后者/没有注释的规则)来满足先决条件,而不需要尝试构建
build/foo.res
<代码>生成在确定有效的先决条件时并不特别聪明或挑剔。