【问题标题】:Make tries to compile target as fileMake尝试将目标编译为文件
【发布时间】:2021-01-25 10:50:00
【问题描述】:

这是我的 Makefile:

FREETYPE=/usr/include/freetype2

CC = c++
CXXFLAGS = -Wall -Wextra -Ofast -std=gnu++20 -Iinclude -I${FREETYPE}
LDLIBS = -lfreetype -lGLEW -lglfw -lGL

rundemo: demo
        ./demo

demo: LDFLAGS += -L.
demo: LDLIBS += -lx
demo: demo.o shared

objects = x.o

shared: CXXFLAGS += -shared -fPIC
shared: $(objects)

x.o : include/x/x.h

输出:

c++ -L.  demo.o shared  -lfreetype -lGLEW -lglfw -lGL -lgllabel -o demo
c++: error: shared: No such file or directory

似乎 make 认为 shared 是隐式规则的文件,而不是目标。我该如何解决这个问题?

【问题讨论】:

  • 提问时,除了错误消息外,请显示您运行的命令和调用的编译器命令。我真的不明白您的makefile 打算做什么,但我无法将您遇到的错误映射到您提供的makefile,即兴发挥。那是你的makefile的全部吗?还是只是其中的一部分?

标签: c++ c makefile


【解决方案1】:

因为shared 没有显示如何创建它的操作规则(只是一个依赖规则),它会根据第一个依赖关系查找模式规则以查看如何构建它。但是第一个依赖是x.o,没有模式规则与shared匹配,所以它只是做了一个noop操作。

然后当它去构建目标demo时,它同样没有动作规则,但在这种情况下,第一个依赖是demo.o,它与内置模式规则匹配1

%: %.o
        $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

这就是它运行的操作。

如果您想要创建shared 的操作,您应该添加它。例如,您可以向共享规则添加一个操作:2

shared: $(objects)
        $(CC) $(CXXFLAGS) $^ -o $@

如果您想要一个不同的操作来创建demo,您应该添加它。


1在 GNU 中,这个默认规则也有 $(TARGET_ARCH)$(LOADLIBES),但是这些变量在你的 makefile 中是空的

2shared 是共享库的一个不同寻常的名称——通常您使用.so 文件扩展名。

【讨论】:

  • 我添加了一些应该有效的自定义隐式规则,但它显示“无事可做”。介意再看一下吗?
  • @Discape 隐式规则不适用于这种情况,因为它无法匹配这些名称。正如我上面建议的那样,你需要一个真正的规则。
  • 那么先决条件与隐含规则无关?
  • 它们是完全独立的——如果显式依赖关系中的依赖关系中存在名称匹配的文件,则使用隐式规则构建目标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 2012-10-21
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多