我有一个 makefile,在过去的几周里一直运行良好。然而,现在我已经用“main”向我的项目添加了另一个目标,它开始有点出格了。
CC=g++
CCOPTS=-g -w
OBJS = $(BINDIR)/manager.o $(BINDIR)/rtngnode.o
TARGETS = $(BINDIR)/manager $(BINDIR)/rtngnode
BINDIR = build
all: $(TARGETS) $(OBJS)
clean:
rm -f $(TARGETS) $(OBJS)
.PHONY: all clean
$(TARGETS): $(OBJS)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
$(BINDIR)/%.o: %.cpp
$(CC) -c $(CCOPTS) -o $@ $<
我仍然不太了解 makefile...所以我不确定发生了什么。我收到这两个错误:
build/rtngnode.o: In function `__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, Node> > >::new_allocator()':
/home/caleb/Documents/dev/tote2/mp2/rtngnode.cpp:5: multiple definition of `main'
build/manager.o:/home/caleb/Documents/dev/tote2/mp2/manager.cpp:161: first defined here
build/manager.o: In function `main':
manager.cpp:(.text+0xefb): undefined reference to `NetworkConnection::NetworkConnection(char const*, char const*)'
在我的 rtngnode
目标中,我依赖于 tcpcon
类...并且我的 manager
目标也有一个 main ()
引用。我很困惑……所以我什至不确定我问的问题是否正确。
我想我的问题是:
- 对于 OBJS 和 TARGETS,那里有什么?我所有的 .cpp 文件?我所有的可执行文件?
- 我喜欢这两者吗?
最佳答案
其他答案都是准确的,但我认为要理解的关键是这条规则:
$(TARGETS): $(OBJS)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
并不像您认为的那样。这扩展为:
$(BINDIR)/manager $(BINDIR)/rtngnode : $(BINDIR)/manager.o $(BINDIR)/rtngnode.o
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
在这里,Make 不会尝试将目标与先决条件进行某种神奇的匹配;相反,make 为每个目标再次重复整个规则,但具有所有先决条件。上面的规则等同于这样写:
$(BINDIR)/manager : $(OBJS)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
$(BINDIR)/rtngnode : $(OBJS)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
鉴于此,您可以看出问题所在:您正在尝试将所有对象链接到每个可执行文件中。
由于您的程序是从一个具有与程序名称相同前缀的单个目标文件构建的,因此您实际上根本不需要为它们编写规则;您可以依靠 make 的内置规则来构建程序。只需完全排除上述规则,它就会起作用。
关于c++ - 如何使用 main() 构建支持多个目标的 makefile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22190879/