我有一些“可选”的代码:程序的其余部分可以在没有它的情况下链接 如果在创建目标文件时出错,如何正确创建将其排除为依赖关系的Makefile?
到目前为止,我有这样的事情:
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
?
答案 0 :(得分:2)
使用$(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)
函数,因为它是在创建文件之前执行的,因此它始终为空。
答案 1 :(得分:1)
假设您的make
是GNU make
,这是执行此操作的一种方法。
假设我的计划prog
有三个源文件main.c
,necessary.c
,optional.c
这样我想从所有三个prog
文件链接.o
,如果他们得到的话
已构建(= 最大版本),但我会选择main.o
和necessary.o
(= 最小版本)。 (我放弃了这个理由)。
用于此目的的makefile是:
.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
到makefile,它将强制optional.o
始终在make的末尾被删除。
这具有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
好吧,如果我们用干净的做一个make,输出是:
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
那是因为当makefile是$(wildcard *.o)
时会扩展
已解析,此时不存在.o
个文件。我们需要解析
当我们扩展它时,makefile 再次,已经完成了所有
我们可以使用.o
个文件。
答案 2 :(得分:0)
GNU make没有可选的依赖项。您可以通过在链接时无法构建和过滤掉不存在的对象时不返回失败来模拟它。