Makefile 语法:静态库 lib$(library).a($objects)

发布于 2024-10-08 00:56:10 字数 1694 浏览 2 评论 0原文

我正在更新一些 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

世界等同你 2024-10-15 00:56:10

这是 gnu make 支持的“归档成员”语法。对于我的口味来说,它与工具有点过于亲密,但就是这样。最初的错误可能是由于 $(object) 为空引起的。但我真的不确定。这里有一些文档:

http://www.gnu.org/software /make/manual/make.html#Archive-Members

11.1 将存档成员作为目标

存档文件的单个成员可以用作目标或
make 的先决条件。您指定存档中名为member的成员
文件存档如下:

 档案(成员)

此构造仅在目标和先决条件中可用,而不在配方中可用!您可能使用的大多数程序
食谱不支持此语法,不能直接作用于存档
成员。只能运行ar等专门设计的程序
对档案馆可以这样做。因此,更新档案的有效方法
成员目标可能必须使用 ar。例如,这条规则规定
通过复制文件 hack.o 在 archivefoolib 中创建成员 hack.o:

foolib(hack.o) : hack.o
         ar cr 傻瓜 hack.o

事实上,几乎所有存档成员目标都以这种方式更新,并且有一个隐含的规则
为你做。请注意:如果
存档文件尚不存在。

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

11.1 Archive Members as Targets

An individual member of an archive file can be used as a target or
prerequisite in make. You specify the member named member in archive
file archive as follows:

 archive(member)

This construct is available only in targets and prerequisites, not in recipes! Most programs that you might use in
recipes do not support this syntax and cannot act directly on archive
members. Only ar and other programs specifically designed to operate
on archives can do so. Therefore, valid recipes to update an archive
member target probably must use ar. For example, this rule says to
create a member hack.o in archive foolib by copying the file hack.o:

 foolib(hack.o) : hack.o
         ar cr foolib hack.o

In fact, nearly all archive member targets are updated in just this way and there is an implicit rule to
do it for you. Please note: The ‘c’ flag to ar is required if the
archive file does not already exist.

秋日私语 2024-10-15 00:56:10

你的方法看起来不错,但是如果旧方法真的有效的话,旧的 makefile 必须有更多内容。

哦,为了保持良好的形式,我建议这样做:

lib$(library).a: $(objects)
     ar -rs $@ $^

编辑
不要因为不理解 Make 而感到难过;它有相当长的学习曲线。

这里还不够,但是如果 sources.inc 不是太大,您可以在 3.81 和 3.82 中尝试以下操作并寻找差异:

experiment:
    @echo sources: $(sources)
    @echo objects: $(objects)
    @echo depends: $(depends)

到目前为止的证据是 < 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:

lib$(library).a: $(objects)
     ar -rs $@ $^

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:

experiment:
    @echo sources: $(sources)
    @echo objects: $(objects)
    @echo depends: $(depends)

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 that depends is not empty, which is very strange.

桃气十足 2024-10-15 00:56:10

有可能,但是您没有明确的规则将 xyz.cpp 之类的内容转换为 xyz.o,在尝试将其对象注入库之前,您的源可能需要这些规则。 可能对此有合适的隐式规则,因此请先检查。

我要问的第一个问题是: $objects 发生了什么导致您尝试定位 libsome_lib.a() (即,括号之间没有任何内容)首先?

老实说,我倾向于尽可能避免这些包含规则,而更喜欢明确的依赖关系声明(当然,除非有很多依赖关系)。是的,我知道它使 makefile 变得更大,并让我至少成为一个部分的勒德分子,但我更喜欢那些能够正常工作的东西,而不是那些巧妙地工作的东西。

剪切和粘贴是我的工具箱中最强大的工具之一:-)

Possibly, but you have no explicit rule for converting something like xyz.cpp to xyz.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 target libsome_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 :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文