Makefile 语法:静态库 lib$(library).a($objects)
我正在更新一些 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...
但是,这个新的 make 版本令人窒息:
*** 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 依赖项,然后 make 开始 g++ing obj 文件。在 3.82 下,我得到 .d 文件,但没有 .o 并且 make 失败,并显示“***没有规则可制定...”
I'm updating some Makefiles to move from Make 3.81 to 3.82. In multiple places, the original author used something like this to build static libs:
all: lib$(library).a($objects)
This seems to build each .o file in turn and insert it into the .a using ar:
g++ -O2 <snip> -o some_obj.o some_cpp.cpp
ar rv libsome_lib.a some_obj.o
etc...
This new make version, though, chokes with:
*** No rule to make target 'libsome_lib.a()', needed by 'all'
Am I safe to replace this shortcut with the way I'm used to doing this:
lib$(library).a: $(objects)
ar -rs lib$(library).a $objects
Thanks.
EDIT
Looks like I need a better Makefile education. Here's a larger excerpt from the original 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) lt; \
| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
[ -s $@ ] || rm -f $@'
%.d: %.c
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) lt; \
| 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
When this runs under 3.81, I get all the .d dependences created, then make starts g++ing the obj files. Under 3.82, I get the .d files but no .o and make fails with "***No rule to make..."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是 gnu make 支持的“归档成员”语法。对于我的口味来说,它与工具有点过于亲密,但就是这样。最初的错误可能是由于 $(object) 为空引起的。但我真的不确定。这里有一些文档:
http://www.gnu.org/software /make/manual/make.html#Archive-Members
This is the "archive member" syntax supported in gnu make. It's a bit too intimate with the tools for my tastes, but there it is. The original error may be caused by $(objects) being empty. But I'm really not sure. Here's some documentation:
http://www.gnu.org/software/make/manual/make.html#Archive-Members
你的方法看起来不错,但是如果旧方法真的有效的话,旧的 makefile 必须有更多内容。
哦,为了保持良好的形式,我建议这样做:
编辑
不要因为不理解 Make 而感到难过;它有相当长的学习曲线。
这里还不够,但是如果
sources.inc
不是太大,您可以在 3.81 和 3.82 中尝试以下操作并寻找差异:到目前为止的证据是 < code>objects 在 3.82 下为空,但如果在 3.82 下重建
.d
文件,则表明depends
不是空荡荡的,这很奇怪。Your way looks good, but there must be more to the old makefile if the old way worked at all.
Oh, and just for good form I'd suggest this:
EDIT
Don't feel bad about not understanding Make very well; it has quite a learning curve.
There is still not quite enough to go on here, but if
sources.inc
isn't too huge, you could try the following in 3.81 and 3.82 and look for differences:The evidence so far is that
objects
is empty under 3.82, but if the.d
files are being rebuilt under 3.82 that suggests thatdepends
is not empty, which is very strange.有可能,但是您没有明确的规则将
xyz.cpp
之类的内容转换为xyz.o
,在尝试将其对象注入库之前,您的源可能需要这些规则。 可能对此有合适的隐式规则,因此请先检查。我要问的第一个问题是:
$objects
发生了什么导致您尝试定位libsome_lib.a()
(即,括号之间没有任何内容)首先?老实说,我倾向于尽可能避免这些包含规则,而更喜欢明确的依赖关系声明(当然,除非有很多依赖关系)。是的,我知道它使 makefile 变得更大,并让我至少成为一个部分的勒德分子,但我更喜欢那些能够正常工作的东西,而不是那些巧妙地工作的东西。
剪切和粘贴是我的工具箱中最强大的工具之一:-)
Possibly, but you have no explicit rule for converting something like
xyz.cpp
toxyz.o
, which you may need for your sources before trying to inject their objects into the library. There may be a suitable implicit rule for this so check first.The first question I'd be asking is: what happened to
$objects
that caused you to try and targetlibsome_lib.a()
(i.e., with nothing between the parentheses) in the first place?To be honest, I tend to avoid these encompassing rules as much as possible, preferring explicit statements of dependencies (unless there are a lot of dependencies, of course). Yes, I know it makes the makefiles larger and marks me as at least a partial luddite, but I prefer to have things that just work over things that work cleverly.
Cut'n'paste is one of the strongest tools in my toolbox :-)