在可选的中间配方

时间:2018-03-04 17:33:58

标签: makefile

一个给定的工具编译文件夹中的所有源文件,我正在尝试使用Makefile来构建过时的对象。

我的第一个结果是:

objects := a.bin b.bin c.bin

all: $(objects) compile

%.bin: %.src
    @echo copy $< to build/ folder

compile:
    @echo run compiler against the build/ folder

有以下缺点:

  • compile配方总是用make all执行,即使没有什么可构建的,我可以通过有条件地运行编译器来解决,具体取决于构建目录是否为空;
  • 指定目标make a.bin不会执行compile食谱。

上面让我进行了第二次尝试:

objects := a.bin b.bin c.bin

all: $(objects)

build/%.src: %.src
    @echo copy $< to build/ folder

compile: build/a.src build/b.src build/c.src
    @echo run compiler against the build/ folder

%.bin: %.src build/%.src compile
    @echo $@ is outdated

.INTERMEDIATE: compile build/a.src build/b.src build/c.src

指定build/*.src目标的所有compile先决条件是我设法确保在编译之前进行复制的唯一方法。 不幸的是,这也意味着所有源都会被复制到构建目录,即使不需要它,这会使编译器构建所有内容,从而使首先拥有Makefile的目的无效。 / p>

当所有compile个对象都是最新的时,将.bin标记为中间会产生想要的效果以跳过编译。 但是,其余的中间先决条件似乎没有产生任何影响。

我怀疑.SECONDEXPANSION或对$(MAKE)的递归调用可能是要走的路,有没有更优雅的解决方案?

我需要在Windows上运行它,因此首选兼容GNU Make 3.81的解决方案,但无论如何我都会对理解如何使用任何不那么古怪的新版本感到满意。

1 个答案:

答案 0 :(得分:0)

看我的评论:我会回答我认为你真正想要的。如果那不是你真正想要的,请纠正我。

我根本不明白为什么你需要/build目录 - 从你的问题来看,没有必要。还有其他需要吗?

无论如何,复制文件是一个非常糟糕的主意。如果必须,请使用符号链接。

最后评论,在“我的拙见”中,您正在尝试用越来越不必要的复杂解决方案来解决一个简单的问题。您应该尝试寻找简单的解决方案。

好的,这是一个&#34;规范&#34;解决这样的问题。它挑出一个目标文件并将其与其余文件分开。 (如果只有一个文件,它仍然可以工作,因为GNU Make手册中的&#34;多个&#34;目标规则的含义包括0 - 但这个文档很少记录)

SOURCES := \
    a.src \
    b.src \
    c.src

OBJECTS := $(SOURCES:src=bin)

OBJECT := $(firstword $(OBJECTS))

.PHONY: all clean

all: $(OBJECTS)

$(subst $(OBJECT),, $(OBJECTS)): $(OBJECT)

$(OBJECT): $(SOURCES) Makefile
    compiler .

clean:
    rm -f $(OBJECTS)