【问题标题】:"undefined reference to function" error on a function in the library库中函数的“未定义的函数引用”错误
【发布时间】:2015-11-21 23:33:03
【问题描述】:

我正在尝试用 C 处理 id3 标签,所以我下载了 mplib 并安装了它。

我试图在 mplib.h 中调用这个函数,其中 __P 是一个宏

extern id3_tag_list* mp_get_tag_list_from_file __P((const char* path));

通过写入 example.c:

int main() {
    char* pa = "R U MINE";
    id3_tag_list* list = mp_get_tag_list_from_file(pa);
    id3_tag *newTag = list->tag;
    printf("tag %d\n", newTag->version);
    return 0;
}

但是当我链接时,我得到一个错误:

example.o: In function `main':
example.c:(.text+0x27): undefined reference to `mp_get_tag_list_from_file'
collect2: error: ld returned 1 exit status
make: *** [example] Error 1

我的 makefile 看起来像这样

OBJECTS = example.o
target=example
misc=Makefile
cflags=-Wall -g -O0 -Werror -pedantic -std=c99

all: $(target)

$(target) : $(OBJECTS) $(misc)
    gcc $(cflags) -o $(target) $(OBJECTS)

clean:
    rm -f $(OBJECTS) $(target)

我在编译这个时遇到了麻烦。我认为问题在于我在将其链接到实际定义该函数的实际 mplib.c 文件时遇到问题,但我不确定如何准确执行此操作。我从http://mplib.sourceforge.net/ 获得了库,并使用“make”和“make install”安装了它。我应该手动将mplib.c 文件移动到某处吗?

【问题讨论】:

  • 尝试将用于链接的库添加到cflags-l mplib
  • 似乎无法解决问题
  • 我认为 nnn 是正确的,你没有链接库。在您的主要内容中,您也没有显示包含的标头,但是从您得到的错误中我猜想 mpilib.h 已包含在内。

标签: c linux gcc compiler-errors


【解决方案1】:

如果您构建mplib 1.0.3,它会创建一个库libmp.a。因此,您需要在链接器命令行上指定-lmp,或许还需要指定-L /where/you/installed/it/lib 来指定库的安装目录。


链接器命令行应该如下所示:

LDFLAGS = -L/usr/local/lib
LDLIBS  = -lmp

gcc $(cflags) -o $(target) $(OBJECTS) $(LDFLAGS) $(LDLIBS)

其实最好是这样的:

$(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LDFLAGS) $(LDLIBS)

大写宏CFLAGS 用于C 编译器的标志。 $@ 表示“当前目标的名称”。 LDFLAGS 是链接器的标志,例如在哪里可以找到库,LDLIBS 包含库的规范。诸如-lmp 之类的选项表示“在搜索图书馆的地点列表中的每个目录中查找libmp.solibmp.a”(非常接近)。 -L 选项将以下目录作为前缀添加到搜索库的位置列表中。

【讨论】:

  • #Thomas Lee #CS 3210 OBJECTS = example.o target=example misc=Makefile cflags=-Wall -g -O0 -Werror -pedantic -std=c99 all: $(target) $(target ) : $(OBJECTS) $(misc) gcc $(cflags) -o $(target) $(OBJECTS) -l usr/local/lib clean: rm -f $(OBJECTS) $(target) 这样好吗?这不起作用:(
  • 否;它不好,部分是因为它不工作,部分是因为难以阅读 cmets 中的代码,即使它包含在反引号中。我从您的评论中复制了一条命令:gcc $(cflags) -o $(target) $(OBJECTS) -l usr/local/lib;当我查看它时,我发现它是小写的 l。 -l 选项用于指定库的名称; -L 选项用于指定找到库的目录。 -I 选项指定标头的位置;使用-I /usr/local/include(也请注意前导斜杠;这很关键)。您需要添加-L /usr/local/lib -lmp
  • 为什么是-lmp? .a 文件在 libmp.a 中,但 -lmp 以某种方式工作?
  • 因为链接器将参数 -lmp-l mp 视为查找包含单词 mp 并带有前缀 lib 和后缀 .a 的库名称的指令(对于静态存档库)或.so(在许多平台上;在其他平台上有多种替代后缀,例如.sl.dylib)。这只是链接器的工作方式。这意味着当您创建库时,您可以使用名称模式libxyz.a 并使用-lxyz 与其链接。这也意味着如果不使用名称模式,则必须准确指定库的路径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2017-02-27
  • 1970-01-01
  • 2022-05-03
  • 1970-01-01
相关资源
最近更新 更多