1

here's my error

make
cc   msgd.o   -o msgd
msgd.o: In function `main':
/home/cam/Desktop/lab1/msgd.cc:37: undefined reference to `Server::Server(int, bool)'
/home/cam/Desktop/lab1/msgd.cc:39: undefined reference to `Server::~Server()'
msgd.o: In function `__static_initialization_and_destruction_0':
/usr/include/c++/4.7/iostream:75: undefined reference to `std::ios_base::Init::Init()'
/usr/include/c++/4.7/iostream:75: undefined reference to `std::ios_base::Init::~Init()'
msgd.o:(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status
make: *** [msgd] Error 1

The first two undefined references to Server:: are bogus, the code works and Server.h is included properly in msgd.cc.

However when I simply do "make server" it runs fine, and when I do "make client" it runs fine, but I want to be able to just do "make" and have it build both.

Here's my makefile. According to https://stackoverflow.com/a/10907227/2080104 I need to include -lstdcc++ but I can't seem to figure out how to do so in a makefile.

# Makefile for socket examples

CXX=            g++ $(CCFLAGS)
msgd=           msgd.o Server.o Data.o User.o Message.o Str.o
msg=            msg.o Client.o Str.o
OBJS =          $(msgd) $(msg)


CCFLAGS= -std=c++11 -g

all:    msgd Server Data User Message Str msg Client

server:$(msgd)
    $(CXX) -o msgd $(msgd) 

client:$(msg)
    $(CXX) -o msg $(msg)

clean:
    rm -f $(OBJS) $(OBJS:.o=.d)

realclean:
    rm -f $(OBJS) $(OBJS:.o=.d) msgd msg


# 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)
Community
  • 1
  • 1
CamHart
  • 3,825
  • 7
  • 33
  • 69
  • wat error you are getting? – shofee Sep 18 '13 at 05:32
  • Aside from the good advice below, you should _never_ add `-lstdc++` to your link line. The SO answer you reference recommends simply linking with C++ (`g++`) rather than C (`gcc`). If you link with `g++` it will understand you're trying to link C++ code, and automatically add in all the libraries you need, including `-lstdc++`, in the right order. It's very complicated to get that right yourself, so just don't do it unless you have extremely complicated linking requirements that mandate it. – MadScientist Sep 18 '13 at 11:50

2 Answers2

3

You named a variable msgd when you had an object file named msgd.o, and then you got them mixed up. Oh, and you have a target server which doesn't actually build server, it builds msgd.

You have a default target (all) which builds things other than what you want the default target to build.

You want to Make to do something (i.e. use -lstdcc++) when either you don't know how to do it on the command line, or you don't know which part of the makefile corresponds to what you do on the command line.

I'd suggest specific changes to the makefile, but your intent is so unclear I'm afraid I'd do more harm than good.

Beta
  • 96,650
  • 16
  • 149
  • 150
1

What happens is that target all requires msgd.

all:    msgd Server Data User Message Str msg Client

You don't have a rule for msgd, however, make figures it can build msgd from msgd.o from msgd.cc (or whatever extension your source has) using the built-in rule:

Linking a single object file

n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise recipe used is ‘$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)’.

Your makefile should look more like the following:

CXX := g++
CXXFLAGS := -std=c++11 -g
CPPFLGS :=
LDFLAGS :=
LDLIBS := -g

all : msgd msg

msgd_obj := msgd.o Server.o Data.o User.o Message.o Str.o
msg_obj := msg.o Client.o Str.o
OBJ := ${msgd_obj} ${msg_obj}

msgd : ${msgd_obj}
msg : ${msg_obj}

# The rule to link the executables.
msgd msg :
    ${CXX} -o $@ ${LDFLAGS} $^ ${LDLIBS}

# The rule to compile object files and produce dependencies.
%.o : %.cc
    ${CXX} -o $@ ${CPPFLAGS} ${CXXFLAGS} -MD -MP $<

clean:
    rm -f $(OBJS) $(OBJS:.o=.d)

realclean:
    rm -f $(OBJS) $(OBJS:.o=.d) msgd msg

-include $(OBJS:.o=.d)

.PHONY: all clean realclean

Note that there should not be a specific rule to produce dependencies. Dependencies are produced as a by-product of compilation. On the first run dependencies are unnecessary because everything must be built anyway, on subsequent runs it uses dependencies from the previous run to determine what have changed since.

Community
  • 1
  • 1
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271