在现有Qt项目中从源代码构建第三方库
Build a 3rd party library from source within an existing Qt project
我的项目需要并非所有目标计算机上都存在的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
更改为库的名称,并将 HEADERS
和 SOURCES
的内容替换为需要为您的库编译的文件。
您现在可以继续测试此.pro
文件。
~/myApp/zlib/ $ qmake
~/myApp/zlib/ $ make
...
~/myApp/zlib/ $ ls libz.a
libz.a
耶!
将库链接到您的应用程序中
最后,我们需要更新应用程序的.pro
文件以链接到第三方库中。这有两个部分:
- 将库头文件添加到包含路径,以便编译器可以从那里获取定义的符号。
- 在编译和链接期间链接静态(或共享)库,以便适用的目标代码可以链接到应用程序中。
首先,我们将头文件添加到包含路径中。将此行添加到 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
来清理构建。但是从那里您应该能够通过转到基目录并运行 qmake
和 make
来构建包含的第三方库的项目。
cd ~/myApp
qmake -r
make
注意:非常感谢@LaszloPapp启动此过程。这个答案的大部分原始资料都来自他的回答。
如果您使用的是QT Creator,您可以尝试调查"项目设置"->"添加构建步骤"->"自定义构建步骤"并在那里添加脚本文件。这可能有助于之前构建 lib,然后您只需将其链接到您的项目。
我不确定,但最有可能的是,您可以将编译器设置(如参数)传递给此脚本。我现在正在尝试解决它。
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 更改命令行 qt5 源代码构建配置的正确/快速方法
- 从源代码构建 gRPC C++
- 为什么Qt必须从源代码构建以进行交叉编译?
- 尝试使用 MSVC 从源代码构建 qt 创建器:无法打开包含文件:"stddef.h":没有这样的文件或目录
- 从源代码构建 pcl 1.7.2
- SQLite - 从源代码构建库或将源代码直接包含在我的项目中
- 从源代码构建 openCV 之前的步骤
- 在 OSX 上从源代码构建 GIMP 2.10 在"gimp-debug-tool-2.0"失败
- 我如何只构建 TensorFlow lite,而不是从源代码构建所有 TensorFlow
- 使用 bazel 从源代码构建张量流服务遇到错误:C++规则'@org_tensorflow//…'编译失败(出口 4)
- CMake configure_file没有源代码构建
- 如何为源代码构建指定搜索目录
- 从MACOS上的源代码构建QT时错误
- 在CentOS 7上从源代码构建TileServer GL
- GRPC C++从源代码构建致命错误
- 从源代码构建Qt 5.8 - 配置:未知命令行选项'-c++11'
- 如何从可从C++代码调用的 Ada 源代码构建静态库?
- 从源代码构建编译器是否会带来更好的优化
- 从源代码构建 MySQL 连接器/C++(找不到 Boost 库错误)