C ++链接错误:编译器找不到函数的定义

时间:2011-12-05 07:20:14

标签: c++ linker makefile

我有一个文件Cache.cpp,它有一个相应的头文件Cache.h和另一个NetFunctions.cpp,它有一个相应的头文件NetFunction.h。

我有一个看起来像这样的makefile

all: net cache
    g++ main.cpp ../obj/NetFunctions.o ../obj/Cache.o -o ../bin/main
net: NetFunctions.cpp
    g++ -c NetFunctions.cpp -o ../obj/NetFunctions.o
cache: Cache.cpp net
    g++ -c Cache.cpp ../obj/NetFunctions.o -o ../obj/Cache.o

现在NetFunctions.cpp在那里定义了一个函数getNFHTML(string),它在Cache.cpp中使用。我已经检查了头文件,它们看起来很好,所有的功能,在那里声明和正确包含的头文件。

但是,当我制作时,我收到以下链接器错误

../obj/Cache.o: In function `Cache::getHTML(std::basic_string<char,  std::char_traits<char>, std::allocator<char> >)':
Cache.cpp:(.text+0x19ee): undefined reference to `getNFHTML(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: ld returned 1 exit status
make: *** [test] Error 1***

有人可以帮我吗?有什么问题?

我也提到了这篇文章C++ Linking error,但它对我毫无帮助。

修改

这是代码: NetFunctions.h

#ifndef NET
#define NET 1

#include "commons.h"

bool serv_bind(struct addrinfo **servinfo, struct addrinfo **p, int *sockfd, int *yes);
void* get_in_addr(struct sockaddr *sa);
string getNFHTML(string website);  
string saveHeaders(string);
//bool getNFHTML(string request, string last_modified, string *response);
extern bool useCache;

#endif

NetFunctions.cpp

    #include "NetFunctions.h"
    string getNFHTML(string request)
    {
    // a lot of code
    }

Cache.cpp

#include "NetFunctions.h"
#include "Cache.h"
string Cache::getHTML(string request)
{
//some code
    string response = getNFHTML(request);
//some code
}

我删除了文件,因为它们包含数百行

3 个答案:

答案 0 :(得分:1)

这与问题无关,但我把它放在一个答案中,以便更好地编写。

您的makefile不能很好地处理依赖项。试试这个:

.PHONY: all
all: ../bin/main

../bin/main: main.cpp ../obj/NetFunctions.o ../obj/Cache.o
    g++ $^ -o $@

../obj/NetFunctions.o: NetFunctions.cpp
    g++ -c $< -o $@

../obj/Cache.o: Cache.cpp 
    g++ -c $< -o $@

对于../bin/main目标,变量$^表示采用所有先决条件,$@是规则的目标。这意味着您可以根据需要添加任意数量的对象文件,并且所有对象文件都将被链接。

为了编译源到目标文件,$<变量是第一个先决条件。如果添加更多文件,这也可以更轻松地复制/粘贴目标。

规则还确保在构建../bin/main时,它所依赖的所有文件都将正确构建。

如果您在未指定目标的情况下运行all,则第一个目标make将成为默认目标。它已被标记为 phony 目标,因为它不会生成名为all的文件。

请注意,我的基础是GNU make,这几乎是所有Linux发行版中的标准,以及Cygwin / MingW。如果使用BSD,则变量可能会发生变化。

答案 1 :(得分:0)

变化:

cache: Cache.cpp net
    g++ -c Cache.cpp ../obj/NetFunctions.o -o ../obj/Cache.o

为:

cache: Cache.cpp net
    g++ -c Cache.cpp -o ../obj/Cache.o

更好的是,摆脱虚拟目标并打开编译器警告:

../bin/main: ../obj/NetFunctions.o ../obj/Cache.o
    g++ -Wall main.cpp ../obj/NetFunctions.o ../obj/Cache.o -o $@
../obj/NetFunctions.o: NetFunctions.cpp
    g++ -Wall -c NetFunctions.cpp -o $@
../obj/Cache.o: Cache.cpp
    g++ -Wall -c Cache.cpp -o $@

答案 2 :(得分:0)

虽然您的Makefile非常糟糕,但很明显如果您所说的话:

  

NetFunctions.cpp在那里定义了函数getNFHTML(string)

是真的,那就行了。因此,一定是你骗我们。在getNFHTML中显示NetFunctions.cpp的代码,或至少显示以下内容的输出:

nm ../obj/NetFunctions.o | grep getNFHTML

更新

好的,你告诉我们的 是真的。但是,似乎未能链接的目标称为test,并且您的makefile中没有此类目标。

我猜测 目标是在链接线上没有所需NetFunctions.o的情况下进行链接的。

在任何情况下,请使用失败的实际链接更新您的问题。