"Optional"生成文件中的目标文件目标?

"Optional" object file target in Makefile?

本文关键字:目标 文件 Optional      更新时间:2023-10-16

我有一些"可选"的代码:程序的其余部分可以在没有它的情况下链接。
如果在创建目标文件时出现错误,如何正确创建将其排除为依赖项的生成文件?

到目前为止,我有这样的东西:

OUT=my_program
OBJS=$(subst .cc,.o,$(wildcard *.cc))
all: $(OUT)
$(OUT): $(OBJS)
my_optional_file.o: other_target
.IGNORE: my_optional_file.o

好处:在处理规则my_optional_file.o时,这将正确忽略所有错误。

坏处:链接输出时,my_optional_file.o被指定为链接器的参数,尽管它没有构建,使链接器失败,因为它被赋予了一个不存在的文件作为输入!

当构建错误时如何排除my_optional_file.o

$(shell find . -maxdepth 1 -iname "*.o")与对链接器的显式调用一起使用。

喜欢:

$(OUT): $(OBJS)
    $(CXX) $(LDFLAGS) $(shell find . -maxdepth 1 -iname "*.o") $(LDLIBS) -o $@

原因是隐式调用时,链接器命令的调用方式如下:

$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@

随着$^扩展到$(OBJS)的内容。您需要显式调用才能改用特定文件。


无法使用 $(wildcard *.o) 函数,因为它是在创建文件之前执行的,因此它始终为空。

假设你的make是GNU make,这里有一种方法可以做到这一点。

假设我的程序prog有三个源文件main.cnecessary.coptional.c这样我想从所有三个.o文件中链接prog,如果他们得到构建( = 最大构建(,但我会满足于main.onecessary.o( = 最小构建(。(我放弃这样做的理由(。

目的是生成文件是:

.phony: all clean make_prog
max_objs=$(subst .c,.o,$(wildcard *.c))
all: make_prog
make_prog: $(max_objs)
    $(MAKE) prog
prog: $(wildcard *.o)
    gcc -o $@ $^
clean:
    rm -f prog *.o
.IGNORE: optional.o 

为了prog我首先制作虚假目标,make_prog,其先决条件是所有三个.o文件,但我忽略了失败 optional.o .然后我把prog变成真的,为了做到这一点,我只是链接我目前拥有的任何.o文件。如果optional.o不存在,没关系。

要明确这一点的行为:-

  • 如果最初我有一个 prog 的最大构建,那么进行破坏的更改 optional.c和重制,没有.o是重制的,所以prog不会重制。它保持最大。

  • 如果最初我有一个最小的prog版本,那么进行修复更改 optional.c和重拍,optional.o被重新制作,所以prog被重新制作。它变得最大。

未能做出optional.o排除了prog对它的依赖,并引入了没有新的。因此,如果满足所有其他依赖项,则无需翻拍prog .

现在可能是您实际上希望失败optional.o引入对失败的依赖 optional.o ,在感觉它会迫使prog重建得最小

实现此目的的一种简单方法是添加以下行:

.INTERMEDIATE: optional.o

到生成文件,这将强制optional.o始终在生成结束时删除。这会产生optional.c始终编译的成本,因此将始终重新链接最大构建。

最后,有人可能想知道为什么 makefile 不能更简单

.phony: all clean
objs=$(subst .c,.o,$(wildcard *.c))
all: prog
prog: $(objs)
    gcc -o $@ $(wildcard *.o)
clean:
    rm -f prog *.o
.IGNORE: optional.o

好吧,如果我们用它做一个干净的制作,输出是:

cc    -c -o main.o main.c
cc    -c -o necessary.o necessary.c
cc    -c -o optional.o optional.c
gcc -o prog 
gcc: fatal error: no input files
compilation terminated.
make: *** [prog] Error 4

这是因为当生成文件$(wildcard *.o)已解析,此时不存在.o文件。我们需要解析当我们扩展它时,再次制作文件,已经完成了所有我们可以.o文件。

GNU make 没有可选的依赖关系。您可以通过在构建失败时不返回 failure 并在链接时过滤掉不存在的对象来模拟这种情况。