“未定义的参考"当链接到静态库时 [英] "undefined reference" when linking against a static library

查看:47
本文介绍了“未定义的参考"当链接到静态库时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

g ++(Ubuntu/Linaro 4.4.4-14ubuntu5)4.4.5

我有以下名为sdpAPI.a的静态库.我在尝试将其与我的测试应用程序链接时遇到问题.只是想知道我是否做错了什么.静态库已使用g ++构建;

我的目录如下:

 /projects/unit_test/main.c/projects/unit_test/sdp/inc/sdpAPH.h/projects/unit_test/sdp/lib/sdpAPI.a 

我的源代码是这样的:

  #include< stdio.h>#include"sdpAPI.h"int main(无效){printf("----- TEST SDP ------ \ n");尝试 {sdpSessionDescription sdp;sdp.clear();}抓住(...) {printf("-----测试失败-------- \ n");返回0;}printf("------测试成功------ \ n");返回0;} 

我的Makefile是这样的:

  OBJECT_FILES = main.oCC = g ++CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0目标= sdp_demoINC_PATH = -I sdp/incLIB_PATH = -L sdp/lib/sdpAPI.a$(TARGET):$(OBJECT_FILES)$(CC)$(CFLAGS)$(INC_PATH)$(LIB_PATH)$(OBJECT_FILES)-o $(TARGET)main.o:main.c$(CC)$(CFLAGS)$(INC_PATH)$(LIB_PATH)-c main.c干净的:rm -f $ {目标)$ {OBJECT_FILES)*〜 

这些是我得到的链接器错误:

 对`sdpSessionDescription :: sdpSessionDescription()'的未定义引用未定义对sdpSessionDescription :: clear()的引用未定义对`sdpSessionDescription ::〜sdpSessionDescription()的引用未定义对`sdpSessionDescription ::〜sdpSessionDescription()的引用 

非常感谢您的任何建议,

解决方案

-L 指定库 path ,而不是特定的库.您可能希望 -L sdp/lib -l sdpAPI 同时指定路径库名.

尽管它将尝试使用 lib .a .sl (或类似名称)为库名称添加前缀和后缀./p>

因此,您可能还需要按照gcc联机帮助页将库重命名为 libsdpAPI.a :

-l xyz
链接器在标准目录列表中搜索该库,该库实际上是一个名为 libxyz.a 的文件.


还请记住,命令行中事物的顺序很重要.通过执行 $(CC)$ {CFLAGS)$ {INC_PATH)$ {LIB_PATH)$ {OBJECT_FILES)-o $ {TARGET} (对象之前的库),在以下位置没有未解析的符号您列出了该库,因此该库不会带来任何影响.

然后,当您最终引入对象(带有其未解析的符号)时,它们将 stay 未解析,因为此后未列出任何库.

通常应该在对象之后创建库:

 <代码> $(CC)$ {CFLAGS)$ {INC_PATH)$ {OBJECT_FILES)$ {LIB_PATH)-o $ {TARGET) 

确保在检查库之前知道所有未解析的符号.

这不会解决所有问题(例如可以使用其他方法修复的依赖库),但可以确保在查看对象之前了解所有 object 文件中未解析的符号.库.

在上面引用的手册页的同一部分中:

在命令中写入此选项的位置有所不同;链接器按照指定的顺序搜索和处理库和目标文件.因此, foo.o -lz bar.o 在文件 foo.o 之后但在 bar.o z .>.如果 bar.o 引用了 z 中的函数,则可能不会加载这些函数.

g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5

I have the following static library called sdpAPI.a. I am having problems trying to link it with my test application. Just wondering if I am doing something wrong. The static library has been built with g++;

My directory is as follows:

/projects/unit_test/main.c
/projects/unit_test/sdp/inc/sdpAPH.h
/projects/unit_test/sdp/lib/sdpAPI.a

My source code is this:

#include <stdio.h>

#include "sdpAPI.h"

int main(void)
{
    printf("----- TEST SDP ------\n");

    try {
        sdpSessionDescription sdp;
        sdp.clear();
    }
    catch(...) {
        printf("----- TEST FAILED --------\n");
        return 0;
    }

    printf("------ TEST SUCCESSFULL ------\n");

    return 0;
}

And my Makefile is this:

OBJECT_FILES = main.o
CC = g++
CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0
TARGET = sdp_demo

INC_PATH = -I sdp/inc
LIB_PATH = -L sdp/lib/sdpAPI.a

$(TARGET): $(OBJECT_FILES)
 $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)

main.o: main.c
 $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) -c main.c

clean:
 rm -f $(TARGET) $(OBJECT_FILES) *~

These are the linker errors I am getting:

undefined reference to `sdpSessionDescription::sdpSessionDescription()'
undefined reference to `sdpSessionDescription::clear()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'

Many thanks for any suggestions,

解决方案

-L specifies the library path, not a specific library. You probably want -L sdp/lib -l sdpAPI to specify both the path and the library name.

Although it will try to prefix and postfix your library name with lib and either .a or .sl (or similar).

So you may also need to rename your library to libsdpAPI.a as per the gcc manpage:

-l xyz
     The linker searches a standard list of directories for the library, which is actually a file named libxyz.a.


Also keep in mind that the order of things in the command line matters. By doing $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) (libraries before objects), there are no unresolved symbols at the point where you list the library, so nothing will be brought in from that library.

Then, when you finally bring in the objects (with their unresolved symbols), they stay unresolved because there are no libraries listed after that.

You should usually do libraries after objects:

$(CC) $(CFLAGS) $(INC_PATH) $(OBJECT_FILES) $(LIB_PATH) -o $(TARGET)

to ensure all unresolved symbols are known before checking the libraries.

This won't catch all problems (such as co-dependent libraries which can be fixed using other means) but it will ensure all unresolved symbols in the object files are known about before looking at the libraries.

From the same section of the man page quoted above:

It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

这篇关于“未定义的参考"当链接到静态库时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆