在模式规则中定义先决条件的选择

时间:2016-06-14 10:42:31

标签: makefile gnu-make

例如,假设我有一个可以从foobar来源构建baz个文件的编译器。

这个规则可能如下:

%.foo: %.bar
    # commands to
    # invoke compiler

%.foo: %.baz
    # commands to
    # invoke compiler

但是,随着输入类型和配方命令数量的增加,这可能会开始变得有点冗长。是否有任何语法可以将其压缩为单个规则?

%.foo: $(oneof %.bar %.baz)
    # commands to
    # invoke compiler

2 个答案:

答案 0 :(得分:2)

您在开始时提出的建议是正确的:Makefile应该清晰简洁地构建规则。

另一方面,您可以查看Canned Recipes以避免一次又一次地重复相同的食谱:

define MAKE_FOO =
#You may use automatic variables such as $^ or $@.
mv $< $@    #In this example just a file renaming.
endef

%.foo: %.bar
    $(MAKE_FOO)

%.foo: %.baz
    $(MAKE_FOO)

罐装食谱 MAKE_FOO将扩展为您在define语句中编写的任何食谱,就好像它们是手动复制一样。

答案 1 :(得分:1)

以下是制作.o文件的具体问题的说明 来自具有组合模式规则的.c文件或.cpp文件。 还构建了可执行文件以帮助说明。

<强>生成文件

.PHONY: all clean

all: test

%.o: %.c %.cpp
    gcc -c $?

test: main.o hw.o
    g++ -o $@ $^

clean:
    rm -f test *.o  

我们有:

<强> hw.c

#include <stdio.h>

void hw(void)
{
    puts("Hello from C");
}

<强> hw.cpp

#include <iostream>

extern "C" void hw()
{
    std::cout << "Hello from C++" << std::endl;
}

<强>的main.cpp

extern "C" void hw(void);

int main(void)
{
    hw();
    return 0;
}

从干净运行并运行:

$ make clean && make && ./test
rm -f test *.o
g++    -c -o main.o main.cpp
gcc -c hw.c hw.cpp
g++ -o test main.o hw.o
Hello from C++

根据模式规则编译hw.chw.cpp

其中每一个都被编译为相同的目标文件hw.o与第二个,C ++ 编译覆盖C编译。所以C ++对象文件被链接了, 仅仅因为它是最后建造的。明确你的期望 当组合规则由多个先决条件触发时发生。

现在让我们更新hw.c并重复:

$ touch hw.c
$ make && ./test
gcc -c hw.c
g++ -o test main.o hw.o
Hello from C

这一次,hw.o仅从hw.c编译并链接。

更新hw.cpp并重复:

$ touch hw.cpp
make && ./test
gcc -c hw.cpp
g++ -o test main.o hw.o
Hello from C++

再一次,来自C ++的hw.o被链接了。

组合模式规则的关键元素是$?,其中 表示比目标

更新的所有先决条件