在现有Qt项目中从源构建第三方库

时间:2013-09-05 22:11:41

标签: c++ qt qt-creator zlib qmake

我的项目需要所有目标计算机上都没有的zlib版本,所以我想在项目中从源代码构建zlib。然后,当我make我的项目时,它应首先构建zlib,以便在编译项目时链接到它。

一个复杂因素是zlib需要在configure运行之前运行make

我甚至不确定从哪里开始。是否有Qt Creator内置的功能用于导入第三方库源代码,或者我是否需要编写自定义.pro文件?

我尝试右键单击项目时出现的“添加库...”菜单,但它无法识别库 - 可能是因为没有.pro文件。我还尝试按文件创建.pro文件 - >新项目 - >导入现有项目,并且一旦zlib运行就可以编译configure,但它仍然不会生成.pro文件。

我认为也许subdirs可能有用,但我不确定在这种情况下这是否是正确的路线,即使它是我不确定我是否可以自动创建必要的.pro文件,或者我必须自己创建。

鉴于像zlib这样的第三方库的源代码,如何将其集成到现有的Qt项目中,以便我可以从源代码编译库,并在我的项目中使用它?

3 个答案:

答案 0 :(得分:7)

是的,您需要为它创建一个项目文件。您可以在我用于多个项目的版本之下找到我的版本。

zlib.pro

QT       -= core gui

TARGET = zlib
TEMPLATE = lib
# Use this for static zlib rather than the default dynamic
# CONFIG += staticlib
include(zlib.pri)

zlib.pri

HEADERS += \
    $$PWD/crc32.h \
    $$PWD/deflate.h \
    $$PWD/gzguts.h \
    $$PWD/inffast.h \
    $$PWD/inffixed.h \
    $$PWD/inflate.h \
    $$PWD/inftrees.h \
    $$PWD/trees.h \
    $$PWD/zconf.h \
    $$PWD/zlib.h \
    $$PWD/zutil.h

SOURCES += \
    $$PWD/adler32.c \
    $$PWD/compress.c \
    $$PWD/crc32.c \
    $$PWD/deflate.c \
    $$PWD/gzclose.c \
    $$PWD/gzlib.c \
    $$PWD/gzread.c \
    $$PWD/gzwrite.c \
    $$PWD/infback.c \
    $$PWD/inffast.c \
    $$PWD/inflate.c \
    $$PWD/inftrees.c \
    $$PWD/trees.c \
    $$PWD/uncompr.c \
    $$PWD/zutil.c

    INCLUDEPATH += $$PWD

然后在包含这个的项目文件中,您可以执行以下操作:

main.pro

# CONFIG += order # If you wanna make sure about order. This is optional.

SUBDIRS += \
    zlib \
    ...

如果你想在qmake上更进一步,你可以这样做:

SUBDIRS += \
    src_zlib \
    src_mylib \
    ...

src_zlib.subdir = $$PWD/zlib
src_zlib.target = sub-zlib
src_zlib.depends =

src_mylib.subdir = $$PWD/mylib
src_mylib.target = sub-mylib
src_mylib.depends = src_zlib

正如您可以看到的那样,无论顺序设置如何,您都可以在依赖关系中进行更合理的控制。例如,您仍然可以按字母顺序保留条目,这有助于长期进行适当的维护。

然后,您需要在子项目的项目文件(.pro)中使用这样的行,让我们说“foo”,这取决于zlib。

foo.pro

LIBS += -L$${PROJECTROOT}/$${SUBDIR_TO_ZLIB} -lz

# These lines are only option, and you do not necessarily need them.
# win32:LIBNAME = zlib.dll
# unix:LIBNAME = libzlib.so
# PRE_TARGETDEPS += $${PROJECTROOT}/$${BUILD_SUBDIR_LIBS}/$${LIBNAME}

答案 1 :(得分:4)

以下是向Qt项目添加第三方存储库并从源代码构建它的说明。

有些人可以通过Qt Creator添加这样的库,但我永远无法让它工作。因此,这些是有关如何创建必要的.pro.pri文件的说明。在这篇文章中,我将使用zlib作为示例,尽管其他库应该类似。

设置构建顺序

由于您的应用程序依赖于此库,因此我们需要确保首先构建库。为此,第三方库和您的应用程序的源代码应位于 sibling 目录中。

~/myApp $ ls myApp
src zlib

您可能已经有一个myApp.pro文件可以正确构建您的应用程序。我建议将其重命名为src.pro,您将在下一步中看到原因。

mv src/myApp.pro src/src.pro

现在,您可以在根目录中创建新的myApp.pro

~/myApp $ touch myApp.pro
~/myApp $ ls
myApp.pro src zlib

这是一个相当简单的.pro文件,zlib之前仅says“构建myApp。”

# ~/myApp/myApp.pro
TEMPLATE = subdirs
CONFIG += ordered   # This tells Qt to compile the following SUBDIRS in order
SUBDIRS = zlib src

创建库.pro文件

现在我们需要告诉Qt如何构建我们的第三方库。我们通过创建新的.pro文件来完成此操作:

# ~/myApp/zlib/zlib.pro
TARGET = z            # The name of the output library - can be whatever you want
TEMPLATE = lib        # Tells Qt that we are compiling a library so the output will be bundled into a .a or .so file
CONFIG += staticlib   # Tells Qt that we want a static library, so a .a file. Remove this and you will get a .so file

QMAKE_CFLAGS_WARN_ON -= -Wall   # Optional - disable warnings when compiling this library
QMAKE_CXXFLAGS_WARN_ON -= -Wall # Optional - disable warnings when compiling this library

HEADERS += \
    crc32.h \
    deflate.h \
    gzguts.h \
    inffast.h \
    inffixed.h \
    inflate.h \
    inftrees.h \
    trees.h \
    zconf.h \
    zlib.h \
    zutil.h

SOURCES += \
    adler32.c \
    compress.c \
    crc32.c \
    deflate.c \
    gzclose.c \
    gzlib.c \
    gzread.c \
    gzwrite.c \
    infback.c \
    inffast.c \
    inflate.c \
    inftrees.c \
    trees.c \
    uncompr.c \
    zutil.c

如果您要构建zlib以外的其他内容,只需将TARGET更改为库的名称,并将HEADERSSOURCES的内容替换为需要为您的库编译。

您现在可以继续测试此.pro文件。

~/myApp/zlib/ $ qmake
~/myApp/zlib/ $ make
...
~/myApp/zlib/ $ ls libz.a
libz.a

耶!

将库链接到您的应用程序

最后,我们需要更新您的应用程序的.pro文件,以便在第三方库中进行链接。这有两个部分:

  1. 将库头文件添加到包含路径,以便编译器可以从那里获取定义的符号。
  2. 在编译和链接时间期间链接静态(或共享)库,以便将适用的对象代码链接到您的应用程序中。
  3. 首先,我们将头文件添加到包含路径中。将此行添加到src.pro

    INCLUDEPATH += zlib
    

    这允许您在代码中引用zlib.h,如下所示:

    #include "zlib.h"
    

    否则,您必须指定标题的完整相对路径,如下所示:

    #include "zlib/zlib.h"
    

    如果您对第二种方法没问题,那么就不需要更新INCLUDEPATH变量。

    第二个,我们需要添加链接器查找静态(或共享)库本身所需的参数。将此行添加到src.pro

    LIBS += -L$$PWD/../zlib -lz
    

    第一部分(-L$$PWD/../zlib)表示包含该库的文件夹位于../zlib,这应该是正确的,因为zlibsrc的同级文件夹。第二部分(-lz)表示库的名称为z。链接器推断出该库实际上位于文件libz.a

    完成

    此时,您可能需要通过执行make distclean来清理构建。但是从那里开始,您应该能够通过转到基本目录并运行qmakemake来构建包含第三方库的项目。

    cd ~/myApp
    qmake -r
    make
    

    注意:非常感谢@LaszloPapp启动此过程。这个答案的大部分原始资料来自他的回答。

答案 2 :(得分:0)

或者,如果您使用的是QT Creator,则可以尝试调查“项目设置”->“添加构建步骤”->“自定义构建步骤”,然后在其中添加脚本文件。 这可能有助于先构建lib,然后只需要将其链接到您的项目即可。

我不确定,但是最有可能您可以将编译器设置作为该脚本的参数来传递。我正在尝试解决这个问题。