1

这是我的错误

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

对 Server:: 的前两个未定义引用是伪造的,代码有效,并且 Server.h 正确包含在 msgd.cc 中。

然而,当我只是做“制作服务器”时它运行良好,当我做“制作客户端”时它运行良好,但我希望能够只做“制作”并让它同时构建。

这是我的生成文件。根据https://stackoverflow.com/a/10907227/2080104我需要包括 -lstdcc++ 但我似乎无法弄清楚如何在生成文件中这样做。

# 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)
4

2 回答 2

3

msgd当你有一个名为 的目标文件时,你命名了一个变量msgd.o,然后你把它们弄混了。哦,你有一个server实际上没有构建的目标server,它构建了msgd

您有一个默认目标 ( all),它构建的内容与您希望默认目标构建的内容不同。

-lstdcc++当您不知道如何在命令行上执行某项操作,或者您不知道 makefile 的哪个部分对应于您在命令行上执行的操作时,您想要 Make 执行某项操作(即使用)。

我建议对 makefile 进行特定更改,但是您的意图如此不清楚,恐怕我弊大于利。

于 2013-09-18T05:34:47.363 回答
1

发生的事情是目标都需要msgd

all:    msgd Server Data User Message Str msg Client

但是,您没有规则msgd,可以使用内置规则msgd从(或您的源具有msgd.omsgd.cc任何扩展名)构建数字:

链接单个目标文件

n 是通过 C 编译器运行链接器(通常称为 ld)从 no 自动生成的。使用的精确配方是'$(CC) $(LDFLAGS) no $(LOADLIBES) $(LDLIBS)'。

您的 makefile 应该看起来更像以下内容:

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

请注意,不应该有特定的规则来产生依赖关系。依赖项是编译的副产品。在第一次运行时依赖项是不必要的,因为无论如何都必须构建所有内容,在随后的运行中,它使用上一次运行的依赖项来确定此后发生了什么变化。

于 2013-09-18T09:33:12.320 回答