C++ &引用;“可选”;Makefile中的对象文件目标?
我有一些代码是“可选的”:程序的其余部分可以在没有它的情况下链接。C++ &引用;“可选”;Makefile中的对象文件目标?,c++,makefile,C++,Makefile,我有一些代码是“可选的”:程序的其余部分可以在没有它的情况下链接。 如果在创建对象文件时出现错误,如何正确地创建将其作为依赖项排除的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_opt
如果在创建对象文件时出现错误,如何正确地创建将其作为依赖项排除的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
?GNU make没有可选的依赖项。您可以通过在构建失败时不返回failure并在链接时过滤掉不存在的对象来模拟这种情况。使用$(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)
的内容。您需要显式调用来使用特定文件
无法使用
$(通配符*.o)
函数,因为它是在创建文件之前执行的,所以它总是空的。假设您的make
是GNUmake
,下面是一种方法
假设我的程序prog
有三个源文件main.c
,required.c
,optional.c
这样,我想从所有三个.o
文件链接prog
,如果它们
构建(=最大构建),但我会满足于main.o
和required.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
文件,但我忽略了生成的失败
可选.o
。然后我真的做了prog
,为了做到这一点,我只需要
链接我现在得到的.o
文件。如果可选。o
没有,没关系
要了解这种情况,请执行以下操作:-
- 如果一开始,我有一个
的最大构建,那么进行一个中断的更改prog
和re-make,不重新生成optional.c
,因此不重新生成.o
。信息技术 保持最大值prog
- 如果一开始我有一个最小的
,那么做一个修改来修复这个问题prog
并重新生成,optional.c
被重新生成,因此optional.o
被重新生成。信息技术 变得最大prog
设置为可选。o
排除prog
对它的依赖,并引入
没有新的。因此,如果满足了所有其他依赖项,就没有必要这样做
重新制作prog
现在,您可能真的希望将设置为可选.o
失败
在中引入对未能使可选.o
的依赖项
感觉到它将迫使prog
以最小的速度重建
实现这一目标的简单方法是添加以下行:
.INTERMEDIATE: optional.o
到makefile,这将强制在make结束时始终删除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
如果我们用它来做一个make from clean,输出是:
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
这是因为在生成文件时,$(通配符*.o)
是展开的
已解析,此时不存在.o
文件。我们需要进行语法分析
当我们展开此文件时,会再次调用makefile,因为已经完成了所有
我们可以使用
.o
文件。+1,但“这需要花费optional.c
始终被编译”。。。没有办法避免这种情况吗?实际上,我在尝试此路由时遇到了这个问题,但不确定如何修复它…我根本没有手动调用链接器,我认为它是隐式调用的。应该吗?这里没有隐式调用。我知道你没有隐式调用它,我想说的是,我的Makefile中肯定没有显式调用,但它仍然在被调用。你是说这不应该发生吗?因为你发布的Makefile不是你使用的完整的Makefile,我想,我只能说你提供了什么。在这个特定的设置中,使用make
时不会隐式调用它。看我的编辑。+1你让我找到了正确的答案。我没有意识到显式调用链接器工作得这么好。现在很好用了,谢谢。