【问题标题】:Rule not recognized in makefile?makefile 中无法识别规则?
【发布时间】:2017-02-27 14:42:18
【问题描述】:

我有一个基本的 makefile 来编译编译共享库所需的 C 文件,我有一个错误,因为 makefile 无法识别:

 SOURCES=/home/test/project/sources
 OBJECTS=/home/test/project/objects

 $(OBJECTS)/%.o:$(SOURCES)/%.c
 $(CC) -fPIC -c $^ -o $@

 sharedlib: $(OBJECTS)/%.o
 $(CC) -shared -o libsharedlib.so $<

当我运行 make 时,我发现目标没有规则:sharedlib 需要 $(OBJECTS)/%.o。虽然规则是在 sharedlib 之前编写的。

【问题讨论】:

  • 但是通配符意味着我一次编译所有文件?
  • 我已经改了,但还是一样的问题。
  • 您是否要同时编译所有对象的 libsharedlib.so?
  • 是的。第二条规则是获取所有目标文件

标签: c makefile shared-libraries


【解决方案1】:

主要的问题是你没有在任何地方明确告诉 make 你的源文件是什么。从这样做开始:

SOURCEDIR=/home/test/project/sources
SOURCES=$(wildcard $(SOURCEDIR)/*.c)

然后,通过将.c 替换为.o,从源文件名派生目标文件名:

OBJECTDIR=/home/test/project/objects
OBJECTS=$(patsubst $(SOURCEDIR)/%.c,$(OBJECTDIR)/%.o,$(SOURCES))

您仍然可以保留通用规则来构建目标文件:

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.c
        $(CC) -fPIC -c $^ -o $@

但是您将明确的目标文件列表提供给规则以生成sharedlib:

libsharedlib.so: $(OBJECTS)
        $(CC) -shared -o $@ $<

请注意,我使规则的名称与正在生成的文件相同。这很重要,因为连续两次调用 make 将跳过第二次构建库。如果需要,您可以随时添加别名:

sharedlib: libsharedlib.so

在这种情况下,告诉 make sharedlib 不是真正的文件也很好:

.PHONY sharedlib

如果您在目录中确实有一个名为 sharedlib 的文件,这可以防止发生奇怪的事情。

【讨论】:

  • 还有一个问题,那就是当我在目标 ´$(OBJECTDIR)/%.o´ 上调用 make 时:我没有规则可以使目标成为 ´$(OBJECTDIR)/%.o´ ?你能告诉我为什么吗?基本上,当在目标 sharedlib 上调用 make 时,makefile 不会执行规则 '$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.c'。
  • @Bionix1441:因为没有真正意义上的$(OBJECTDIR)/%.o 规则。这只是一个模式,在使用该规则之前,您必须为 make 提供一个与模式匹配的真实文件名。
  • 你是对的。终于可以顺利编译了
【解决方案2】:

图书馆规则

sharedlib: $(OBJECTS)/%.o

不足以告诉 Make 库需要哪些 obj。

这应该可以工作,并且可以明确控制您想要在库中使用哪些源/objs 对:

SOURCESDIR=/home/test/project/sources
OBJECTDIR=/home/test/project/objects

OBJLIST = \
    $(OBJECTS)/file1.o \
    $(OBJECTS)/file2.o

$(OBJECTDIR)/%.o: $(SOURCESDIR)/%.c
    $(CC) -fPIC -c $^ -o $@

sharedlib: $(OBJLIST)
    $(CC) -shared -o libsharedlib.so $<

【讨论】:

  • 我刚刚注意到G Sliepen在上面的答案中关于图书馆规则的建议非常合适
  • 感谢您的澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多