4

我正在 Linux 上的 C++ 中的 QT Creator 中开发一个应用程序

我创建了自己的库,以便可以在一组应用程序中使用一些通用类。

在我创建的库中,我使用了另一个外部静态库 (libSDL.a)。我已将我的库配置为静态库 (*.a),它可以毫无问题地编译。

然后我将我的库添加到另一个应用程序并使用了一些类。在尝试编译我的应用程序时,我从我的库中获取未定义的引用来调用另一个库的函数。

据我了解,静态库应该在编译期间被复制。为什么我会得到对应该复制到我的库中的库的未定义引用?

以下是在 *.pro 文件中配置库项目的方式:

QT -= gui
TARGET = FoobarTools
TEMPLATE = lib
CONFIG += staticlib
CONFIG -= shared
DEFINES += FOOBARTOOLS_LIBRARY
INCLUDEPATH += ./include/SDL_Headers/
LIBS += -L./bin/ -lSDL
SOURCES += ...
HEADERS += ...

以下是我的应用程序 *.pro 文件如何使用我的库:

QT -= gui
TARGET = FoobarApp
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
INCLUDEPATH += ./include/
LIBS += -L./bin/ -lFoobarTools
SOURCES += ...
HEADERS += ...
4

3 回答 3

1

在应用程序的 .pro 中,您需要:

INCLUDEPATH += LibraryPath(这指向头文件的目录。)

DEPENDPATH += LibraryPath(这也指向头文件的目录。)

LIBS += -LDebugOrReleasePath -lLibraryName(这是 lib 文件名减去开头的“lib”和结尾的“.a”。)

完成后,检查自定义库的#includes 是否仍在工作。

在静态库的 .pro 文件中,您不需要触摸任何内容,可以添加“CONFIG += release”。

于 2012-06-08T18:09:56.223 回答
1

您的库和它使用的库都应该在应用程序中链接。

INCLUDEPATH += ./include/SDL_Headers/
INCLUDEPATH += ./include/
LIBS += -L./bin/ -lFoobarTools
LIBS += -L./bin/ -lSDL
//And dont forget the Target dependencies.
PRE_TARGETDEPS += ./libFoobarTools.a
PRE_TARGETDEPS ./libSDL.a

如果您想了解有关库编译而不是应用程序编译原因的更多信息,请查看此问题

于 2017-04-06T17:31:02.403 回答
-1

我想你可以在这里找到答案:

http://gcc.gnu.org/ml/gcc-help/2004-04/msg00104.html

而且,更准确地说,在这个后续行动中:

http://gcc.gnu.org/ml/gcc-help/2004-04/msg00106.html

我现在无法对其进行测试,但我认为可能的原因可能会通过以下方式恢复:

“如果链接器遇到它,它将“丢弃”一个库,但不需要它定义的任何符号”

作为急救帮助,将 -lSDL 添加到您的第二个 .pro 文件中。

编辑:你确定你的静态库(第一个 .pro 文件)真的使用了 libSDL 中的一些符号吗?如果不是,那么编译器将简单地忽略 libSDL.a 文件,并且不会将其包含在您的静态库中。即使您使用 libSDL.a 中的某些符号,也只有那些函数会被复制到可执行文件中,而其他符号则不会(至少,我是这么认为的)。“静态库在链接方面有特殊的规则。静态库中的对象只有在对象提供未解析的符号时才会添加到二进制文件中。” (见:https ://stackoverflow.com/a/2649792/1284631)。然后,如果您的可执行文件(第二个 .pro 文件)使用了一些来自 libSDL 的未复制符号,则会出现错误。引用同一来源:“在 Linux 上,您可以使用 --whole-archive 链接器选项更改该行为:g++ -Wl,--whole-archive some_static_lib.a -Wl,--no-whole-archive”。这样,您可以确保在您的文件中携带整个静态 libSDL.a 存档。

于 2012-06-03T22:04:51.423 回答