使用 G++,未定义参考 std::Makefile
Posted
技术标签:
【中文标题】使用 G++,未定义参考 std::Makefile【英文标题】:Using G++, Undefined Reference std:: Makefile 【发布时间】:2016-09-16 20:38:21 【问题描述】:我一直致力于让服务器/客户端运行一个简单的单线程信使服务。它可以在 Visual Studio 上编译,但是当我尝试通过 makefile 在 Linux 上编译它时,使用命令:make client
,我得到一个非常大的错误列表。我将提供开始部分,然后提供错误列表:
这里说它至少在尝试使用 g++:
g++ -g -c -o client.o client.cc cc client.o -o client client.o: 在函数
main': /home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:10: undefined reference to
std::allocator::allocator()'编辑:我注意到这里有一些不寻常的地方。当我再次调用
make client
而不调用make clean
时,我得到以下信息:peter@peter-VirtualBox:~/Desktop/CS360/Messaging_Service/messenger$ 制作客户端 cc 客户端.o -o 客户端 client.o:在函数
main': /home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:10: undefined reference to
std::allocator::allocator()' 不确定这是否重要,但它没有再次提及 g++。
上述错误的片段:
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:7: undefined reference to `std::allocator<char>::allocator()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:7: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:7: undefined reference to `std::allocator<char>::~allocator()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:15: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(char const*)'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:18: undefined reference to `std::cout'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:18: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:18: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:18: undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:23: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:23: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:7: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:25: undefined reference to `std::allocator<char>::~allocator()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:25: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:7: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
client.o: In function `Client::Client(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)':
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:27: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:27: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:29: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:32: undefined reference to `operator new[](unsigned long)'
这让我相信我的 makefile 有错误。我使用 g++,我相信它也可以编译得很好,所以我不太确定从这里去哪里。我的 Makefile 是:
CXX= g++ $(CCFLAGS)
MSG-SERVER= server.o
MSG-CLIENT= client.o
OBJS = $(MSG-SERVER) $(MSG-CLIENT)
LIBS =
CCFLAGS = -g
all: msg-server msg-client
msg-server:$(MSG-SERVER)
$(CXX) -o server $(MSG-SERVER) $(LIBS)
msg-client:$(MSG-CLIENT)
$(CXX) -o client $(MSG-CLIENT) $(LIBS)
clean:
rm -f $(OBJS) $(OBJS:.o=.d)
realclean:
rm -f $(OBJS) $(OBJS:.o=.d) server client
# These lines ensure that dependencies are handled automatically.
%.d: %.cc
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
[ -s $@ ] || rm -f $@'
include $(OBJS:.o=.d)
如果需要,我也会链接我的代码:https://bitbucket.org/picklepetters/messenger/src/44e4fa12541948215f874b56e4ba0dedea1766f5/client.cc?at=master&fileviewer=file-view-default
当我使用 make -d
跟踪 make 时,它给了我大量的数据。我将发布一些给出的内容的 sn-ps,因为老实说,我不知道我在看什么:
Trying implicit prerequisite '/usr/include/c++/5/SCCS/s.stdexcept.F'.
Trying pattern rule with stem 'stdexcept'.
Trying implicit prerequisite '/usr/include/c++/5/stdexcept.r'.
Looking for a rule with intermediate file '/usr/include/c++/5/stdexcept.r'.
Avoiding implicit rule recursion.
Avoiding implicit rule recursion.
Avoiding implicit rule recursion.
Trying pattern rule with stem 'stdexcept'.
Rejecting impossible implicit prerequisite '/usr/include/c++/5/stdexcept.l'.
Trying pattern rule with stem 'stdexcept.r'.
Trying implicit prerequisite '/usr/include/c++/5/stdexcept.r,v'.
Trying pattern rule with stem 'stdexcept.r'.
Trying implicit prerequisite '/usr/include/c++/5/RCS/stdexcept.r,v'.
Trying pattern rule with stem 'stdexcept.r'.
Trying implicit prerequisite '/usr/include/c++/5/RCS/stdexcept.r'.
Trying pattern rule with stem 'stdexcept.r'.
Trying implicit prerequisite '/usr/include/c++/5/s.stdexcept.r'.
Trying pattern rule with stem 'stdexcept.r'.
Trying implicit prerequisite '/usr/include/c++/5/SCCS/s.stdexcept.r'.
Trying pattern rule with stem 'stdexcept'.
Rejecting impossible implicit prerequisite '/usr/include/c++/5/stdexcept.F'.
Trying pattern rule with stem 'stdexcept'.
Trying implicit prerequisite '/usr/include/c++/5/stdexcept.m'.
Looking for a rule with intermediate file '/usr/include/c++/5/stdexcept.m'.
Avoiding implicit rule recursion.
Avoiding implicit rule recursion.
Trying pattern rule with stem 'stdexcept'.
Trying implicit prerequisite '/usr/include/c++/5/stdexcept.ym'.
Trying pattern rule with stem 'stdexcept.m'.
Trying implicit prerequisite '/usr/include/c++/5/stdexcept.m,v'.
Trying pattern rule with stem 'stdexcept.m'.
Trying implicit prerequisite '/usr/include/c++/5/RCS/stdexcept.m,v'.
Trying pattern rule with stem 'stdexcept.m'.
Trying implicit prerequisite '/usr/include/c++/5/RCS/stdexcept.m'.
Trying pattern rule with stem 'stdexcept.m'.
一直到最后大概有 150~ 行,当它说它已经完成了目标文件的先决条件时:
Finished prerequisites of target file 'server.d'.
Prerequisite 'server.cc' is older than target 'server.d'.
Prerequisite 'server.cc' is older than target 'server.d'.
Prerequisite '/usr/include/stdc-predef.h' is older than target 'server.d'.
Prerequisite 'server.h' is older than target 'server.d'.
Prerequisite '/usr/include/errno.h' is older than target 'server.d'.
Prerequisite '/usr/include/features.h' is older than target 'server.d'.
Prerequisite '/usr/include/x86_64-linux-gnu/sys/cdefs.h' is older than target 'server.d'.
Prerequisite '/usr/include/x86_64-linux-gnu/bits/wordsize.h' is older than target 'server.d'.
Prerequisite '/usr/include/x86_64-linux-gnu/gnu/stubs.h' is older than target 'server.d'.
Prerequisite '/usr/include/x86_64-linux-gnu/gnu/stubs-64.h' is older than target 'server.d'.
Prerequisite '/usr/include/x86_64-linux-gnu/bits/errno.h' is older than target 'server.d'.
对于最后 100 行,它声明:
Must remake target 'server.o'.
g++ -g -c -o server.o server.cc
Putting child 0x13601a0 (server.o) PID 7768 on the chain.
Live child 0x13601a0 (server.o) PID 7768
server.cc: In function ‘int main(int, char**)’:
server.cc:19:17: error: ‘cout’ was not declared in this scope
cout << "server [-p port]" << endl;
^
server.cc:19:47: error: ‘endl’ was not declared in this scope
cout << "server [-p port]" << endl;
^
server.cc: In constructor ‘Server::Server(int)’:
server.cc:34:30: error: ‘>>’ should be ‘> >’ within a nested template argument list
map<string, vector<string>> mappedMessages;
^
server.cc: At global scope:
server.cc:121:36: error: ‘String’ has not been declared
Server::handle_message(int client, String message)
^
server.cc:121:1: error: prototype for ‘void Server::handle_message(int, int)’ does not match any in class ‘Server’
Server::handle_message(int client, String message)
^
In file included from server.cc:1:0:
server.h:33:12: error: candidate is: std::__cxx11::string Server::handle_message(int, std::__cxx11::string)
string handle_message(int, string);
^
server.cc:127:35: error: ‘String’ has not been declared
Server::parse_message(int client, String message)
^
server.cc:127:1: error: prototype for ‘std::__cxx11::string Server::parse_message(int, int)’ does not match any in class ‘Server’
Server::parse_message(int client, String message)
^
In file included from server.cc:1:0:
server.h:34:12: error: candidate is: std::__cxx11::string Server::parse_message(int, std::__cxx11::string)
string parse_message(int, string);
^
server.cc:190:63: error: ISO C++ forbids declaration of ‘store_message’ with no type [-fpermissive]
Server::store_message(string name, string subject, string data)
^
server.cc:190:1: error: prototype for ‘int Server::store_message(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)’ does not match any in class ‘Server’
Server::store_message(string name, string subject, string data)
^
In file included from server.cc:1:0:
server.h:36:10: error: candidate is: void Server::store_message(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)
void store_message(string, string, string);
^
server.cc: In member function ‘std::__cxx11::string Server::get_subjects(std::__cxx11::string)’:
server.cc:210:5: error: ‘mappedMessages’ was not declared in this scope
if(mappedMessages.find(name) != mappedMessages.empty())
^
server.cc:214:15: error: missing template arguments before ‘it’
for(iterator it = mappedMessages.at(name).begin(); it != mappedMessages.at(name).end(); ++it)
^
server.cc:214:53: error: ‘it’ was not declared in this scope
for(iterator it = mappedMessages.at(name).begin(); it != mappedMessages.at(name).end(); ++it)
^
server.cc:214:59: error: ‘mappedMessages’ was not declared in this scope
for(iterator it = mappedMessages.at(name).begin(); it != mappedMessages.at(name).end(); ++it)
^
server.cc:219:29: error: no match for ‘operator+’ (operand types are ‘std::__cxx11::basic_string<char>’ and ‘int’)
response = response + " " + counter + " " + mappedMessages.at(name).it.front() + "\n";
【问题讨论】:
你能告诉我们你的makefile执行的完整轨迹吗?我怀疑涉及到一些 C 编译... 好的,我只是把它放到原始帖子中,如果这就是你所说的完整跟踪的意思,我输入了 makefile 执行的文件路径 我的意思是:make
执行的痕迹,请在问题中。
好的,抱歉,我刚刚又更新了。
基于error: ‘cout’ was not declared in this scope
之类的错误消息,在我看来,您的源文件中没有#include <iostream>
(或等效标头),或者您没有设置std
命名空间.
【参考方案1】:
这里的问题是使用
make client
而不是
make msg-client
由于客户端没有目标,因此默认使用 cc。这显示在原始问题的第一个黄色框中。
【讨论】:
【参考方案2】:那些undefined reference to 'std::allocator<char>::allocator()'
错误通常意味着libstdc++
未链接,最常见的原因是人们使用gcc
而不是g++
链接。
依赖生成规则使用$(CC)
而不是$(CXX)
,这就是导致那些编译器错误的原因。事实上,这条规则十年来已经没有必要了。你应该做的是:
-
完全删除
%.d
规则及其配方。
在将.cc
编译为.o
(您的makefile 使用the built-in rule %.o
: %.cc
)时,指导编译器生成依赖项(-MD -MP
):
%.o : %.cc
$(CXX) -c -o $@ -MD -MP $CPPFLAGS $CXXFLAGS $<
将include $(OBJS:.o=.d)
更改为-include $(OBJS:.o=.d)
。
生成和使用依赖项不需要其他任何东西。详情请见https://***.com/a/32379965/412080。
【讨论】:
我理解,如果您查看 Makefile,它使用 g++ 而不是 gcc。是不是没有得到 g++ 部分而只是默认使用 gcc? @Petorix 更新了答案。 原来我犯了一个错误,将这个 makefile 与我正在编码的另一个文件混淆了。结果我输入了一个不同的 make 命令,所以它找到了最接近的选择并恢复到 gcc。令人惊讶的是另一双眼睛可以做什么。不过,我会赞成你的回答,很高兴知道我使用的是过时的方法。【参考方案3】:在您的命令行中为 g++ [-std=c++11] 添加选项
【讨论】:
以上是关于使用 G++,未定义参考 std::Makefile的主要内容,如果未能解决你的问题,请参考以下文章
来自 GCC 的未定义参考错误使用带有 std::vector 和特征矩阵的模板?