我正在更新一些Makefile,从Make 3.81升级到3.82。在多个地方,原作者使用这样的东西来构建静态库:
all: lib$(library).a($objects)
这似乎依次构建每个.o文件并使用ar:
将其插入.a文件中g++ -O2 <snip> -o some_obj.o some_cpp.cpp
ar rv libsome_lib.a some_obj.o
etc...
然而,这个新的制作版本窒息:
*** No rule to make target 'libsome_lib.a()', needed by 'all'
我可以安全地用我习惯的方式替换这个快捷方式:
lib$(library).a: $(objects)
ar -rs lib$(library).a $objects
感谢。
修改
看起来我需要更好的Makefile教育。这是原始Makefile的更大摘录:
CXXFLAGS += -O2 -g -Wall -Wunused-parameter \
`pkg-config --cflags gthread-2.0 glibmm-2.4 gtkmm-2.4`
libs += `pkg-config --libs gthread-2.0 glibmm-2.4` -lc
%.d: %.cpp
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
[ -s $@ ] || rm -f $@'
%.d: %.c
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
[ -s $@ ] || rm -f $@'
from_sources = $(patsubst %.c,$(2),$(filter %.c, $(1))) $(patsubst %.cpp,$(2),$(filter %.cpp, $(1)))
sources = $(shell cat sources.inc)
objects = $(call from_sources,$(sources),%.o)
depends = $(call from_sources,$(sources),%.d)
library = some_lib
.PHONY: all clean fresh
all: lib$(library).a($(objects))
clean:
<SNIP>
if neq($(MAKECMDGOALS),clean)
include $(depends)
endif
当它在3.81下运行时,我会创建所有.d依赖项,然后启动g ++ ing obj文件。在3.82之下,我得到了.d文件,但是没有.o并且因为“***没有规则制作......”而失败了。
答案 0 :(得分:4)
这是&#34;档案会员&#34; gnu make支持的语法。对于我的口味来说,这个工具有点过于贴心,但事实确实如此。原始错误可能是由$(对象)为空引起的。但我真的不确定。这是一些文档:
http://www.gnu.org/software/make/manual/make.html#Archive-Members
11.1将成员存档为目标
存档文件的单个成员可用作目标或 制作的先决条件。您在归档中指定名为member的成员 文件存档如下:
archive(member)
此构造仅在目标和先决条件中可用,而不在食谱中可用!您可能使用的大多数程序 食谱不支持此语法,不能直接对存档执行操作 成员。只有ar和其他专门设计用于运营的程序 档案馆可以这样做。因此,更新存档的有效配方 成员目标可能必须使用ar。例如,这条规则说 通过复制文件hack.o:
在archive foolib中创建一个成员hack.ofoolib(hack.o) : hack.o ar cr foolib hack.o
事实上,几乎所有的归档成员目标都是以这种方式更新的,并且有一个隐含的规则 为你而做。请注意:如果是,则需要ar的'c'标志 存档文件尚不存在。
答案 1 :(得分:3)
你的方式看起来不错,但如果旧的方式有效,那么旧的makefile必须有更多。
哦,只是表现良好,我建议:
lib$(library).a: $(objects)
ar -rs $@ $^
修改的
不理解不理解做得很好;它有相当的学习曲线。
此处仍然不够,但如果sources.inc
不是太大,您可以在3.81和3.82中尝试以下内容并寻找差异:
experiment:
@echo sources: $(sources)
@echo objects: $(objects)
@echo depends: $(depends)
到目前为止的证据是objects
在3.82下是空的,但是如果.d
文件在3.82下重建,则表明depends
不是空的,这很奇怪。
答案 2 :(得分:1)
可能,但您没有明确的规则可以将xyz.cpp
转换为xyz.o
之类的内容,在尝试将对象注入库之前,您可能需要这些内容。 可能是适合的隐含规则,因此请先检查。
我要问的第一个问题是:$objects
发生了什么导致你首先尝试定位libsome_lib.a()
(即括号之间没有任何内容)?
说实话,我倾向于尽可能地避免这些包含规则,更喜欢显式依赖关系语句(当然,除非存在 lot 依赖关系)。是的,我知道它会使makefile更大并且标记我至少是一个部分luddite,但我更喜欢让事情适用于巧妙运作的东西。
Cut'n'paste是我工具箱中最强大的工具之一: - )