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

Build a 3rd party library from source within an existing Qt project

本文关键字:源代码 构建 第三方 Qt 项目      更新时间:2023-10-16

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

一个复杂问题是zlib需要先运行configure,然后才能运行make

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

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

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

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

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

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}

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

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

设置构建顺序

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

~/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文件,仅说"在myApp之前构建zlib"。

# ~/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. 在编译和链接期间链接静态(或共享)库,以便适用的目标代码可以链接到应用程序中。

首先,我们将头文件添加到包含路径中。将此行添加到 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,这应该是正确的,因为zlib是一个要src的同级文件夹。第二部分(-lz)说库的名称是z。链接器由此推断库实际上位于文件libz.a中。

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

cd ~/myApp
qmake -r
make

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

或者,

如果您使用的是QT Creator,您可以尝试调查"项目设置"->"添加构建步骤"->"自定义构建步骤"并在那里添加脚本文件。这可能有助于之前构建 lib,然后您只需将其链接到您的项目。

我不确定,但最有可能的是,您可以将编译器设置(如参数)传递给此脚本。我现在正在尝试解决它。