【问题标题】:QT shared library undefined reference toQT 共享库未定义引用
【发布时间】:2013-04-15 09:02:41
【问题描述】:

我正在研究在 QT 中链接共享库,尝试了教程但没有任何效果。 有人可以帮我找出错误吗?

我在编译测试项目时遇到错误“未定义的测试引用”。

我试图链接我的库的项目: loadTestLib.pro:

#-------------------------------------------------
#
# Project created by QtCreator 2013-04-22T15:32:30
#
#-------------------------------------------------

QT       += core

QT       -= gui

TARGET = loadTestLib
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app


SOURCES += main.cpp
LIBS+=-L../libtest.so.1.0.0

HEADERS += \
    test_global.h \
    test.h

main.cpp:

#include <QCoreApplication>
#include "test.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Test test;
    return a.exec();
}

test_global.h:

#ifndef TEST_GLOBAL_H
#define TEST_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(TEST_LIBRARY)
#  define TESTSHARED_EXPORT Q_DECL_EXPORT
#else
#  define TESTSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // TEST_GLOBAL_H

test.h:

#ifndef TEST_H
#define TEST_H

#include "test_global.h"

class TESTSHARED_EXPORT Test
{
public:
    Test();
};

#endif // TEST_H

图书馆:

test_global.h:

#ifndef TEST_GLOBAL_H
#define TEST_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(TEST_LIBRARY)
#  define TESTSHARED_EXPORT Q_DECL_EXPORT
#else
#  define TESTSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // TEST_GLOBAL_H

test.cpp:

#include "test.h"


Test::Test()
{
}

test.h:

#ifndef TEST_H
#define TEST_H

#include "test_global.h"

class TESTSHARED_EXPORT Test
{
public:
    Test();
};

#endif // TEST_H

test.pro:

#-------------------------------------------------
#
# Project created by QtCreator 2013-04-22T15:31:04
#
#-------------------------------------------------

QT       -= gui

TARGET = test
TEMPLATE = lib

DEFINES += TEST_LIBRARY

SOURCES += test.cpp

HEADERS += test.h\
        test_global.h

unix:!symbian {
    maemo5 {
        target.path = /opt/usr/lib
    } else {
        target.path = /usr/lib
    }
    INSTALLS += target
}

编译输出:

13:49:12: Running steps for project loadTestLib...
13:49:12: Configuration unchanged, skipping qmake step.
13:49:12: Starting: "/usr/bin/make" -w
make: Entering directory `/home/bonart/Workspace/test/loadTestLib-build-Desktop_Qt_5_0_1_GCC_64bit-_______'
/home/bonart/Qt5.0.1/5.0.1/gcc_64/bin/qmake -spec linux-g++-64 CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug -o Makefile ../loadTestLib/loadTestLib.pro
make: Leaving directory `/home/bonart/Workspace/test/loadTestLib-build-Desktop_Qt_5_0_1_GCC_64bit-_______'
make: Entering directory `/home/bonart/Workspace/test/loadTestLib-build-Desktop_Qt_5_0_1_GCC_64bit-_______'
g++ -m64 -Wl,-rpath,/home/bonart/Qt5.0.1/5.0.1/gcc_64 -Wl,-rpath,/home/bonart/Qt5.0.1/5.0.1/gcc_64/lib -o loadTestLib main.o   -L./libs -L../libs/-ltest -L/home/bonart/Qt5.0.1/5.0.1/gcc_64/lib -lQt5Core -lpthread 
main.o: In function `main':
/home/bonart/Workspace/test/loadTestLib-build-Desktop_Qt_5_0_1_GCC_64bit-_______/../loadTestLib/main.cpp:7: undefined reference to `Test::Test()'
make: Leaving directory `/home/bonart/Workspace/test/loadTestLib-build-Desktop_Qt_5_0_1_GCC_64bit-_______'
collect2: ld returned 1 exit status
make: *** [loadTestLib] Error 1
13:49:12: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project loadTestLib (kit: Desktop Qt 5.0.1 GCC 64bit)
When executing step 'Сборка'

$ nm -D for my library 给了我:

w _Jv_RegisterClasses
                 U _Unwind_Resume
                 U _Z17qt_message_output9QtMsgTypeRK18QMessageLogContextRK7QString
                 U _ZN10QArrayData10deallocateEPS_mm
                 U _ZN11QTextStreamD1Ev
                 U _ZN11QTextStreamlsERK7QString
                 U _ZN11QTextStreamlsEc
0000000000000bb0 T _ZN4TestC1Ev
0000000000000bb0 T _ZN4TestC2Ev
0000000000000d90 W _ZN6QDebugD1Ev
0000000000000d90 W _ZN6QDebugD2Ev
                 U _ZN7QString15fromUtf8_helperEPKci
                 U _ZNK14QMessageLogger5debugEv
                 U _ZTISt9bad_alloc
                 U _ZdlPv
0000000000202080 A __bss_start
                 U __cxa_begin_catch
                 U __cxa_end_catch
                 w __cxa_finalize
                 w __gmon_start__
                 U __gxx_personality_v0
0000000000202080 A _edata
0000000000202090 A _end
0000000000000ec8 T _fini
00000000000009e8 T _init

【问题讨论】:

  • 不应该将其标记为 QMake 而不是 CMake?
  • 你的库建成功了吗?如果是,那么输出位置是否正确(相对于主应用程序)?
  • 是的,已经构建成功了
  • 对于未来的访问者:LIBS+=-L../libtest.so.1.0.0 是一个简单的错误,导致 libtest.so.1.0.0 不能输入到链接中。根据@Troubadour 的回答对其进行了更正后,OP 发现该应用程序无法在运行时加载libtest.so.1,除非将其复制到加载程序的受信任目录之一/usr/lib。当然不能,不使用LD_LIBRARY_PATHldconfig。这里没什么可看的。

标签: qt shared-libraries qt-creator qmake qt5


【解决方案1】:

您在 In loadTestLib.pro 中的 LIBS 行是错误的。应该是

LIBS+=-L.. -ltest

为了清楚起见,您也可以将其放在两行(也可以使用空格)

LIBS += -L..
LIBS += -ltest

请注意,这将链接到 ../libtest.so。通常,您在构建时链接不带版本后缀的文件,而在运行时链接带有版本号的文件。

【讨论】:

  • 现在我得到这个错误:/usr/bin/ld: 找不到 -ltest make: Leaving directory `/home/bonart/Workspace/test/loadTestLib-build-Desktop_Qt_5_0_1_GCC_64bit-_______' collect2: ld返回 1 个退出状态 make: *** [loadTestLib] 错误 1
  • 好的,我已经写了 LIBS+= "absolute path to lib/libtest.so.1.0.0" 现在它编译成功了。但是当我运行应用程序时,控制台说它找不到“libtest.so.1”。当我将 libtest.so、libtest.so.1、libtest.so.1.0、libtest.so.1.0.0 放入 /usr/lib 时,一切正常。你知道为什么 app 在它的文件夹中看不到 lib 吗?我使用 Ubuntu。
  • @madmaker:先说几点。 1. 查看您添加到问题中的构建输出,您似乎缺少-ltest 之前的空格。 2. 如果您将相对路径传递给-L,请确保它相对于调用g++ 的位置是正确的。现在关于运行应用程序的问题。运行时链接不同于构建时链接。前者在 Linux 上由 ld.so 完成,您需要在您的系统上查阅 man 页面。通常最简单的方法是将正确的路径添加到您的 LD_LIBRARY_PATH 环境变量中。
【解决方案2】:

除了 Troubadour 所说的之外,您还应该告诉链接器在哪里可以找到该库。您可以在 .pro 文件中设置 QMAKE_LIBDIR,或者将包含您的库的目录添加到 /etc/ld.so.conf 并使用 ldconfig 命令。

【讨论】:

  • 现在我再次收到错误“未定义对 Test::test() 的引用”。没有改变。我注意到如果我写“LIBS+=-L../-ltest”——没有空格——它是“未定义的引用”。如果我写“LIBS+=-L../ -ltest” - 带有空格,我会收到错误“找不到 -ltest”。怎么了?
  • 我已将编译输出添加到我的问题中
  • 一切正常,尝试使用nm util 来查看您的库导出功能是否正常。 Here is the link about using nm. 您也可以尝试使用qmake &amp;&amp; make clean &amp;&amp; make 重建您的项目。
  • 好的,我已经写了 LIBS+= "absolute path to lib/libtest.so.1.0.0" 现在它编译成功了。但是当我运行应用程序时,控制台说它找不到“libtest.so.1”。当我将 libtest.so、libtest.so.1、libtest.so.1.0、libtest.so.1.0.0 放入 /usr/lib 时,一切正常。你知道为什么 app 在它的文件夹中看不到 lib 吗?我使用 Ubuntu。
  • 你可以将lib文件夹添加到/etc/ld.so.conf(或者ld.so.conf放在哪里,我记不太清楚了)。然后你应该运行ldconfig。但是对于谷歌更好的关于应用程序的 lib 文件夹的明确答案或询问比我更熟悉 linux 编程的人,我不确定其他人会在这里看到你的评论。并尽量避免.pro文件中的绝对路径,你试过QMAKE_LIBDIR = your_relative_path_to_lib吗?
【解决方案3】:

在 Windows 中,库的绝对路径和带有 .dll 的名称对我有用。 在 Ubuntu 中,它也以相同的方式成功编译,但应用程序只有在将其放入 /usr/lib 时才能找到库

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2019-02-12
    • 2015-11-15
    • 1970-01-01
    • 2011-02-28
    • 2013-06-21
    相关资源
    最近更新 更多