Petorix Petorix - 2 months ago 21
Linux Question

Using G++, Undefined Reference std:: Makefile

I've been working on getting a server/client running for a simple single-threaded messenger service. It's able to compile on Visual Studio but when I attempt to compile it on Linux via a makefile, using the command:

make client
, I get a very large list of errors. I will provide the beginning part and then a list of errors:

Here it says that it is at least trying to use g++:


g++ -g -c -o client.o client.cc cc client.o -o client client.o:
In function
main':
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:10:
undefined reference to
std::allocator::allocator()'

EDIT: I noticed something unusual here. When I call
make client
again without calling
make clean
I get the following:

peter@peter-VirtualBox:~/Desktop/CS360/Messaging_Service/messenger$ make client
cc client.o -o client
client.o: In function
main':
/home/peter/Desktop/CS360/Messaging_Service/messenger/client.cc:10: undefined reference to
std::allocator::allocator()'
Not sure if this is significant or not, but it doesn't mention g++ again.


Snippet of said errors:

/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)'


This leads me to believe that there is an error with my makefile. I use g++ and I believe it also is set to compile just fine as well, so I am not too sure where to go from here. My Makefile is:

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)


If needed I'll link my code as well: https://bitbucket.org/picklepetters/messenger/src/44e4fa12541948215f874b56e4ba0dedea1766f5/client.cc?at=master&fileviewer=file-view-default

When I trace make with
make -d
it gives me a HUGE amount of data. I'll post some snippets of what was given, because I honestly have no idea what I am looking at:

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'.


It's like that until maybe 150~ lines towards the end when it says that it has finished the prerequisites of target file:

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'.


for the last 100 lines it states:

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";

Answer

Those undefined reference to 'std::allocator<char>::allocator()' errors normally mean that libstdc++ is not linked in, most often because people link with gcc instead of g++.

The dependency generation rule uses $(CC) instead of $(CXX), this is what causes those compiler errors. In fact, this rule has been unnecessary for a decade now. What you should do is the following:

  1. Remove that %.d rule and its recipe entirely.
  2. Direct the compiler to produce the dependencies (-MD -MP) when compiling .cc to .o (your makefile uses the built-in rule %.o : %.cc):

    %.o : %.cc
        $(CXX) -c -o $@ -MD -MP ${CPPFLAGS} ${CXXFLAGS} $<
    
  3. Change include $(OBJS:.o=.d) to -include $(OBJS:.o=.d).

Nothing else is required to generate and use dependencies. See http://stackoverflow.com/a/32379965/412080 for more details.

Comments